<commit_before>// Copyright 2002-2014, University of Colorado Boulder


/**
 * Handles a visual SVG layer of drawables.
 *
 * @author <NAME> <<EMAIL>>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var Poolable = require( 'PHET_CORE/Poolable' );
  var cleanArray = require( 'PHET_CORE/cleanArray' );
  var scenery = require( 'SCENERY/scenery' );
  var FittedBlock = require( 'SCENERY/display/FittedBlock' );
  var PixiDisplayObject = require( 'SCENERY/display/PixiDisplayObject' );
  var Util = require( 'SCENERY/util/Util' );

  scenery.PixiBlock = function PixiBlock( display, renderer, transformRootInstance, filterRootInstance ) {
    this.initialize( display, renderer, transformRootInstance, filterRootInstance );
  };
  var PixiBlock = scenery.PixiBlock;

  inherit( FittedBlock, PixiBlock, {
    initialize: function( display, renderer, transformRootInstance, filterRootInstance ) {
      this.initializeFittedBlock( display, renderer, transformRootInstance );

      this.filterRootInstance = filterRootInstance;

      this.dirtyGroups = cleanArray( this.dirtyGroups );
      this.dirtyDrawables = cleanArray( this.dirtyDrawables );
      this.paintMap = {}; // maps {string} paint.id => { count: {number}, paint: {Paint}, def: {SVGElement} }

      if ( !this.domElement ) {

        // Create the Pixi Stage
        this.stage = new PIXI.Stage( 0xFF0000 );

        // Create the renderer and view
        this.pixiRenderer = PIXI.autoDetectRenderer( 1024, 768, { transparent: false } );

        // main DOM element
        this.pixiCanvas = this.pixiRenderer.view;
        this.pixiCanvas.style.position = 'absolute';
        this.pixiCanvas.style.left = '0';
        this.pixiCanvas.style.top = '0';
        //OHTWO TODO: why would we clip the individual layers also? Seems like a potentially useless performance loss
        // this.pixiDisplayObject.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';
        this.pixiCanvas.style[ 'pointer-events' ] = 'none';

        this.baseTransformGroup = new PIXI.DisplayObjectContainer();
        this.stage.addChild( this.baseTransformGroup );
        this.domElement = this.pixiCanvas;
      }

      // reset what layer fitting can do (this.forceAcceleration set in fitted block initialization)
      Util.prepareForTransform( this.pixiCanvas, this.forceAcceleration );
      Util.unsetTransform( this.pixiCanvas ); // clear out any transforms that could have been previously applied

      var instanceClosestToRoot = transformRootInstance.trail.nodes.length > filterRootInstance.trail.nodes.length ? filterRootInstance : transformRootInstance;

      this.rootGroup = PixiDisplayObject.createFromPool( this, instanceClosestToRoot, null );
      this.baseTransformGroup.addChild( this.rootGroup.displayObject );

      // TODO: dirty list of nodes (each should go dirty only once, easier than scanning all?)

      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'initialized #' + this.id );

      return this;
    },

    markDirtyGroup: function( block ) {
      this.dirtyGroups.push( block );
      this.markDirty();
    },

    markDirtyDrawable: function( drawable ) {
      sceneryLog && sceneryLog.dirty && sceneryLog.dirty( 'markDirtyDrawable on PixiBlock#' + this.id + ' with ' + drawable.toString() );
      this.dirtyDrawables.push( drawable );
      this.markDirty();
    },

    setSizeFullDisplay: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'setSizeFullDisplay #' + this.id );

      var size = this.display.getSize();
      this.pixiCanvas.setAttribute( 'width', size.width );
      this.pixiCanvas.setAttribute( 'height', size.height );
    },

    setSizeFitBounds: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'setSizeFitBounds #' + this.id + ' with ' + this.fitBounds.toString() );

      var x = this.fitBounds.minX;
      var y = this.fitBounds.minY;

      // subtract off so we have a tight fit
      this.baseTransformGroup.x = (-x);
      this.baseTransformGroup.y = (-y);
      Util.setTransform( 'matrix(1,0,0,1,' + x + ',' + y + ')', this.pixiCanvas, this.forceAcceleration ); // reapply the translation as a CSS transform
      this.pixiCanvas.setAttribute( 'width', this.fitBounds.width );
      this.pixiCanvas.setAttribute( 'height', this.fitBounds.height );
    },

    update: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'update #' + this.id );

      if ( this.dirty && !this.disposed ) {
        this.dirty = false;

        //OHTWO TODO: call here!
        while ( this.dirtyGroups.length ) {
          var group = this.dirtyGroups.pop();

          // if this group has been disposed or moved to another block, don't mess with it
          if ( group.block === this ) {
            group.update();
          }
        }
        while ( this.dirtyDrawables.length ) {
          var drawable = this.dirtyDrawables.pop();

          // if this drawable has been disposed or moved to another block, don't mess with it
          if ( drawable.parentDrawable === this ) {
            drawable.update();
          }
        }

        // checks will be done in updateFit() to see whether it is needed
        this.updateFit();

      }
      this.pixiRenderer.render( this.stage );
    },

    dispose: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'dispose #' + this.id );
<commit_msg>Only render pixi when dirty<commit_after>// Copyright 2002-2014, University of Colorado Boulder


/**
 * Handles a visual SVG layer of drawables.
 *
 * @author <NAME> <<EMAIL>>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var Poolable = require( 'PHET_CORE/Poolable' );
  var cleanArray = require( 'PHET_CORE/cleanArray' );
  var scenery = require( 'SCENERY/scenery' );
  var FittedBlock = require( 'SCENERY/display/FittedBlock' );
  var PixiDisplayObject = require( 'SCENERY/display/PixiDisplayObject' );
  var Util = require( 'SCENERY/util/Util' );

  scenery.PixiBlock = function PixiBlock( display, renderer, transformRootInstance, filterRootInstance ) {
    this.initialize( display, renderer, transformRootInstance, filterRootInstance );
  };
  var PixiBlock = scenery.PixiBlock;

  inherit( FittedBlock, PixiBlock, {
    initialize: function( display, renderer, transformRootInstance, filterRootInstance ) {
      this.initializeFittedBlock( display, renderer, transformRootInstance );

      this.filterRootInstance = filterRootInstance;

      this.dirtyGroups = cleanArray( this.dirtyGroups );
      this.dirtyDrawables = cleanArray( this.dirtyDrawables );
      this.paintMap = {}; // maps {string} paint.id => { count: {number}, paint: {Paint}, def: {SVGElement} }

      if ( !this.domElement ) {

        // Create the Pixi Stage
        this.stage = new PIXI.Stage( 0xFF0000 );

        // Create the renderer and view
        this.pixiRenderer = PIXI.autoDetectRenderer( 1024, 768, { transparent: false } );

        // main DOM element
        this.pixiCanvas = this.pixiRenderer.view;
        this.pixiCanvas.style.position = 'absolute';
        this.pixiCanvas.style.left = '0';
        this.pixiCanvas.style.top = '0';
        //OHTWO TODO: why would we clip the individual layers also? Seems like a potentially useless performance loss
        // this.pixiDisplayObject.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';
        this.pixiCanvas.style[ 'pointer-events' ] = 'none';

        this.baseTransformGroup = new PIXI.DisplayObjectContainer();
        this.stage.addChild( this.baseTransformGroup );
        this.domElement = this.pixiCanvas;
      }

      // reset what layer fitting can do (this.forceAcceleration set in fitted block initialization)
      Util.prepareForTransform( this.pixiCanvas, this.forceAcceleration );
      Util.unsetTransform( this.pixiCanvas ); // clear out any transforms that could have been previously applied

      var instanceClosestToRoot = transformRootInstance.trail.nodes.length > filterRootInstance.trail.nodes.length ? filterRootInstance : transformRootInstance;

      this.rootGroup = PixiDisplayObject.createFromPool( this, instanceClosestToRoot, null );
      this.baseTransformGroup.addChild( this.rootGroup.displayObject );

      // TODO: dirty list of nodes (each should go dirty only once, easier than scanning all?)

      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'initialized #' + this.id );

      return this;
    },

    markDirtyGroup: function( block ) {
      this.dirtyGroups.push( block );
      this.markDirty();
    },

    markDirtyDrawable: function( drawable ) {
      sceneryLog && sceneryLog.dirty && sceneryLog.dirty( 'markDirtyDrawable on PixiBlock#' + this.id + ' with ' + drawable.toString() );
      this.dirtyDrawables.push( drawable );
      this.markDirty();
    },

    setSizeFullDisplay: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'setSizeFullDisplay #' + this.id );

      var size = this.display.getSize();
      this.pixiCanvas.setAttribute( 'width', size.width );
      this.pixiCanvas.setAttribute( 'height', size.height );
    },

    setSizeFitBounds: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'setSizeFitBounds #' + this.id + ' with ' + this.fitBounds.toString() );

      var x = this.fitBounds.minX;
      var y = this.fitBounds.minY;

      // subtract off so we have a tight fit
      this.baseTransformGroup.x = (-x);
      this.baseTransformGroup.y = (-y);
      Util.setTransform( 'matrix(1,0,0,1,' + x + ',' + y + ')', this.pixiCanvas, this.forceAcceleration ); // reapply the translation as a CSS transform
      this.pixiCanvas.setAttribute( 'width', this.fitBounds.width );
      this.pixiCanvas.setAttribute( 'height', this.fitBounds.height );
    },

    update: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'update #' + this.id );

      if ( this.dirty && !this.disposed ) {
        this.dirty = false;

        //OHTWO TODO: call here!
        while ( this.dirtyGroups.length ) {
          var group = this.dirtyGroups.pop();

          // if this group has been disposed or moved to another block, don't mess with it
          if ( group.block === this ) {
            group.update();
          }
        }
        while ( this.dirtyDrawables.length ) {
          var drawable = this.dirtyDrawables.pop();

          // if this drawable has been disposed or moved to another block, don't mess with it
          if ( drawable.parentDrawable === this ) {
            drawable.update();
          }
        }

        // checks will be done in updateFit() to see whether it is needed
        this.updateFit();
        this.pixiRenderer.render( this.stage );
      }
    },

    dispose: function() {
      sceneryLog && sceneryLog.PixiBlock && sceneryLog.PixiBlock( 'dispose #' + this.id );

{'fraction_non_alphanumeric': 0.1187687278670662, 'fraction_numerical': 0.005084899664033415, 'mean_word_length': 2.9391988555078683, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1323156', 'n_tokens_mistral': 3404, 'n_tokens_neox': 3185, 'n_words': 788}