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

/**
 * An instance that is specific to the display (not necessarily a global instance, could be in a Canvas cache, etc),
 * that is needed to tracking instance-specific display information, and signals to the display system when other
 * changes are necessary.
 *
 * DisplayInstances generally form a true tree, as opposed to the DAG of nodes. The one exception is for shared Canvas caches,
 * where multiple instances can point to one globally-stored (shared) cache instance.
 *
 * A DisplayInstance is pooled, but when constructed will not automatically create children, drawables, etc.
 * syncTree() is responsible for synchronizing the instance itself and its entire subtree.
 *
 **********************
 * Relative transform system description:
 *
 * A "relative" transform here is the transform that a Trail would have, not necessarily rooted at the display's root. Imagine we have a
 * CSS-transformed backbone div, and nodes underneath that render to Canvas. On the Canvas, we will need to set the context's transform to
 * the matrix that will transform from the displayed instances' local coordinates frames to the CSS-transformed backbone instance. Notably,
 * transforming the backbone instance or any of its ancestors does NOT affect this "relative" transform from the instance to the displayed
 * instances, while any Node transform changes between (not including) the backbone instance and (including) the displayed instance WILL
 * affect that relative transform. This is key to setting the CSS transform on backbones, DOM nodes, having the transforms necessary for
 * the fastest Canvas display, and determining fitting bounds for layers.
 *
 * Each DisplayInstance has its own "relative trail", although these aren't stored. We use implicit hierarchies in the DisplayInstance tree
 * for this purpose. If a DisplayInstance is a CSS-transformed backbone, or any other case that requires drawing beneath to be done relative
 * to its local coordinate frame, we call it a transform "root", and it has instance.isTransformed set to true. This should NEVER change for
 * an instance (any changes that would do this require reconstructing the instance tree).
 *
 * There are implicit hierarchies for each root, with trails starting from that root's children (they won't apply that root's transform since
 * we assume we are working within that root's local coordinate frame). These should be effectively independent (if there are no bugs), so that
 * flags affecting one implicit hierarchy will not affect the other (dirty flags, etc.), and traversals should not cross these boundaries.
 * 
 * For various purposes, we want a system that can:
 * - every frame before repainting: notify listeners on instances whether its relative transform has changed (add|removeRelativeTransformListener)
 * - every frame before repainting: precompute relative transforms on instances where we know this is required (add|removeRelativeTransformPrecompute)
 * - any time during repainting:    provide an efficient way to lazily compute relative transforms when needed
 *
 * This is done by first having one step in the pre-repaint phase that traverses the tree where necessary, notifying relative transform listeners,
 * and precomputing relative transforms when they have changed (and precomputation is requested). This traversal leaves metadata on the instances
 * so that we can (fairly) efficiently force relative transform "validation" any time afterwards that makes sure the relativeMatrix property is up-to-date.
 *
 * First of all, to ensure we traverse the right parts of the tree, we need to keep metadata on what needs to be traversed. This is done by tracking counts
 * of listeners/precompution needs, both on the instance itself, and how many children have these needs. We use counts instead of boolean flags so that we can
 * update this quickly while (a) never requiring full children scans to update this metadata, and (b) minimizing the need to traverse all the way up to the root
 * to update the metadata. The end result is hasRelativeTransformListenerNeed and hasRelativeTransformComputeNeed which compute, respectively, whether we need
 * to traverse this instance for listeners and precomputation.
 *
 * The other tricky bits to remember for this traversal are the flags it sets, and how later validation uses and updates these flags.
 * First of all, we have relativeSelfDirty and relativeChildDirtyFrame. When a node's transform changes, we mark relativeSelfDirty on the node, and
 * relativeChildDirtyFrame for all ancestors up to (and including) the transform root. relativeChildDirtyFrame allows us to prune our traversal to only
 * modified subtrees. Additionally, so that we can retain the invariant that it is "set" parent node if it is set on a child, we store the rendering frame
 * ID (unique to traversals) instead of a boolean true/false. Our traversal may skip subtrees where relativeChildDirtyFrame is "set" due to no listeners
 * or precomputation needed for that subtree, so if we used booleans this would be violated. Violating that invariant would prevent us from "bailing out" when
 * setting the relativeChildDirtyFrame flag, and on EVERY transform change we would have to traverse ALL of the way to the root (instead of the efficient
 * "stop at the ancestor where it is also set").
 *
 * relativeSelfDirty is initially set on instances whose nodes had transform changes (they mark that this relative transform, and all transforms beneath, are dirty).
 * We maintain the invariant that if a relative transform needs to be recomputed, it or one of its ancestors WILL ALWAYS have this flag set. This is required
 * so that later validation of the relative transform can verify whether it has been changed in an efficient way. When we recompute the relative transform for one
 * instance, we have to set this flag on all children to maintain this invariant.
 *
 * Additionally, so that we can have fast "validation" speed, we also store into relativeFrameId the last rendering frame ID (counter) where we either verified that
 * the relative transform is up to date, or we have recomputed it. Thus when "validating" a relative transform that wasn't precomputed, we only need to scan up
 * the ancestors to the first one that was verified OK this frame (boolean flags are insufficient for this, since we would have to clear them all to false on every
 * frame, requiring a full tree traversal). In the future, we may set this flag to the frame proactively during traversal to speed up validation, but that is not done
 * at the time of this writing.
 **********************
 *
 * @author <NAME> <<EMAIL>>
 */

define( function( require ) {
  'use strict';
  
  var inherit = require( 'PHET_CORE/inherit' );
  var Poolable = require( 'PHET_CORE/Poolable' );
  var Matrix3 = require( 'DOT/Matrix3' );
  var scenery = require( 'SCENERY/scenery' );
  
  var globalIdCounter = 1;
  
  // display instance linked list ops
  function connectDrawables( a, b ) {
    a.nextDrawable = b;
    b.previousDrawable = a;
  }
  
  scenery.DisplayInstance = function DisplayInstance( display, trail ) {
    this.initializedOnce = false;
    
    this.initialize( display, trail );
  };
  var DisplayInstance = scenery.DisplayInstance;
  
  inherit( Object, DisplayInstance, {
    initialize: function( display, trail ) {
      trail.setImmutable(); // prevent the trail passed in from being mutated after this point (we want a consistent trail)
      
      this.id = globalIdCounter++;
      
      this.cleanInstance( display, trail, trail.lastNode() );
      
      // properties relevant to the "relative" transform to the closest transform root. Please see detailed docs at the top of the file!
      this.relativeMatrix = this.relativeMatrix || new Matrix3();  // the actual cached transform to the root
      this.relativeSelfDirty = true;                   // whether our relativeMatrix is dirty
      this.relativeChildDirtyFrame = display._frameId; // Whether children have dirty transforms (if it is the current frame) NOTE: used only for pre-repaint traversal,
                                                       // and can be ignored if it has a value less than the current frame ID. This allows us to traverse and hit all listeners
                                                       // for this particular traversal, without leaving an invalid subtree (a boolean flag here is insufficient, since our
                                                       // traversal handling would validate our invariant of this.relativeChildDirtyFrame => parent.relativeChildDirtyFrame).
                                                       // In this case, they are both effectively "false" unless they are the current frame ID, in which case that invariant holds.
      //this.relativeTransformListeners = [];          // will be notified in pre-repaint phase that our relative transform has changed (but not computed by default)
      this.relativeChildrenListenersCount = 0;         // how many children have (or have descendants with) relativeTransformListeners
      this.relativePrecomputeCount = 0;                // if >0, indicates this should be precomputed in the pre-repaint phase
      this.relativeChildrenPrecomputeCount = 0;        // how many children have (or have descendants with) >0 relativePrecomputeCount
      this.relativeFrameId = -1;                       // used to mark what frame the transform was updated in (to accelerate non-precomputed relative transform access)
      
      // properties relevant to the node's direct transform
      this.transformDirty = true; // whether the node's transform has changed (until the pre-repaint phase)
      
      this.nodeTransformListener = this.markTransformDirty.bind( this );
      this.node.onStatic( 'transform', this.nodeTransformListener );
      
      // If we are a transform root, notify the display that we are dirty. We'll be validated when it's at that phase at the next updateDisplay().
      if ( this.isTransformed ) {
        display.markTransformRootDirty( this, true );
      }
      
      this.initializedOnce = true;
    },
    
    // called for initialization of properties (via initialize(), via constructor), or to clean the instance for placement in the pool (don't leak memory)
    cleanInstance: function( display, trail, node ) {
      this.display = display;
      this.trail = trail;
      this.node = node;
      this.parent = null; // will be set as needed
      this.children = this.children ? ( this.children.length = 0, this.children ) : []; // Array[DisplayInstance]
      this.sharedCacheInstance = null; // reference to a shared cache instance (if applicable, it's different than a child)
      
      this.selfDrawable = null;
      this.groupDrawable = null; // e.g. backbone or non-shared cache
      this.sharedCacheDrawable = null; // our drawable if we are a shared cache
      
      // references into the linked list of drawables (null if nothing is drawable under this)
      this.firstDrawable = null;
      this.lastDrawable = null;
      
      // references that will be filled in with syncTree
      this.state = null;
      this.isTransformed = false; // whether this instance creates a new "root" for the relative trail transforms
      
      // will be notified in pre-repaint phase that our relative transform has changed (but not computed by default)
      // NOTE: it's part of the relative transform feature, see above for documentation
      this.relativeTransformListeners = this.relativeTransformListeners ? ( this.relativeTransformListeners.length = 0, this.relativeTransformListeners ) : [];
    },
    
    // updates the internal {RenderState}, and fully synchronizes the instance subtree
    /*OHTWO TODO:
     * Create new instances for added children
     * Remove instances for removed children
     * Rearrange instances for moved children
     * *** Handle compatibility state check with children, rebuild them if necessary
     * Mark unused instances/drawables on the Display for recycling after completing update?
     * Pruning:
     *   - If children haven't changed, skip instance add/move/remove
     *   - If RenderState hasn't changed AND there are no render/instance/stitch changes below us, EXIT (whenever we are assured children don't need sync)
     * Return linked-list of alternating changed (add/remove) and keep sections of drawables, for processing with backbones/canvas caches
     *
     * Other notes:
     *<commit_msg>Using cleanArray in DisplayInstance<commit_after>// Copyright 2002-2014, University of Colorado

/**
 * An instance that is specific to the display (not necessarily a global instance, could be in a Canvas cache, etc),
 * that is needed to tracking instance-specific display information, and signals to the display system when other
 * changes are necessary.
 *
 * DisplayInstances generally form a true tree, as opposed to the DAG of nodes. The one exception is for shared Canvas caches,
 * where multiple instances can point to one globally-stored (shared) cache instance.
 *
 * A DisplayInstance is pooled, but when constructed will not automatically create children, drawables, etc.
 * syncTree() is responsible for synchronizing the instance itself and its entire subtree.
 *
 **********************
 * Relative transform system description:
 *
 * A "relative" transform here is the transform that a Trail would have, not necessarily rooted at the display's root. Imagine we have a
 * CSS-transformed backbone div, and nodes underneath that render to Canvas. On the Canvas, we will need to set the context's transform to
 * the matrix that will transform from the displayed instances' local coordinates frames to the CSS-transformed backbone instance. Notably,
 * transforming the backbone instance or any of its ancestors does NOT affect this "relative" transform from the instance to the displayed
 * instances, while any Node transform changes between (not including) the backbone instance and (including) the displayed instance WILL
 * affect that relative transform. This is key to setting the CSS transform on backbones, DOM nodes, having the transforms necessary for
 * the fastest Canvas display, and determining fitting bounds for layers.
 *
 * Each DisplayInstance has its own "relative trail", although these aren't stored. We use implicit hierarchies in the DisplayInstance tree
 * for this purpose. If a DisplayInstance is a CSS-transformed backbone, or any other case that requires drawing beneath to be done relative
 * to its local coordinate frame, we call it a transform "root", and it has instance.isTransformed set to true. This should NEVER change for
 * an instance (any changes that would do this require reconstructing the instance tree).
 *
 * There are implicit hierarchies for each root, with trails starting from that root's children (they won't apply that root's transform since
 * we assume we are working within that root's local coordinate frame). These should be effectively independent (if there are no bugs), so that
 * flags affecting one implicit hierarchy will not affect the other (dirty flags, etc.), and traversals should not cross these boundaries.
 * 
 * For various purposes, we want a system that can:
 * - every frame before repainting: notify listeners on instances whether its relative transform has changed (add|removeRelativeTransformListener)
 * - every frame before repainting: precompute relative transforms on instances where we know this is required (add|removeRelativeTransformPrecompute)
 * - any time during repainting:    provide an efficient way to lazily compute relative transforms when needed
 *
 * This is done by first having one step in the pre-repaint phase that traverses the tree where necessary, notifying relative transform listeners,
 * and precomputing relative transforms when they have changed (and precomputation is requested). This traversal leaves metadata on the instances
 * so that we can (fairly) efficiently force relative transform "validation" any time afterwards that makes sure the relativeMatrix property is up-to-date.
 *
 * First of all, to ensure we traverse the right parts of the tree, we need to keep metadata on what needs to be traversed. This is done by tracking counts
 * of listeners/precompution needs, both on the instance itself, and how many children have these needs. We use counts instead of boolean flags so that we can
 * update this quickly while (a) never requiring full children scans to update this metadata, and (b) minimizing the need to traverse all the way up to the root
 * to update the metadata. The end result is hasRelativeTransformListenerNeed and hasRelativeTransformComputeNeed which compute, respectively, whether we need
 * to traverse this instance for listeners and precomputation.
 *
 * The other tricky bits to remember for this traversal are the flags it sets, and how later validation uses and updates these flags.
 * First of all, we have relativeSelfDirty and relativeChildDirtyFrame. When a node's transform changes, we mark relativeSelfDirty on the node, and
 * relativeChildDirtyFrame for all ancestors up to (and including) the transform root. relativeChildDirtyFrame allows us to prune our traversal to only
 * modified subtrees. Additionally, so that we can retain the invariant that it is "set" parent node if it is set on a child, we store the rendering frame
 * ID (unique to traversals) instead of a boolean true/false. Our traversal may skip subtrees where relativeChildDirtyFrame is "set" due to no listeners
 * or precomputation needed for that subtree, so if we used booleans this would be violated. Violating that invariant would prevent us from "bailing out" when
 * setting the relativeChildDirtyFrame flag, and on EVERY transform change we would have to traverse ALL of the way to the root (instead of the efficient
 * "stop at the ancestor where it is also set").
 *
 * relativeSelfDirty is initially set on instances whose nodes had transform changes (they mark that this relative transform, and all transforms beneath, are dirty).
 * We maintain the invariant that if a relative transform needs to be recomputed, it or one of its ancestors WILL ALWAYS have this flag set. This is required
 * so that later validation of the relative transform can verify whether it has been changed in an efficient way. When we recompute the relative transform for one
 * instance, we have to set this flag on all children to maintain this invariant.
 *
 * Additionally, so that we can have fast "validation" speed, we also store into relativeFrameId the last rendering frame ID (counter) where we either verified that
 * the relative transform is up to date, or we have recomputed it. Thus when "validating" a relative transform that wasn't precomputed, we only need to scan up
 * the ancestors to the first one that was verified OK this frame (boolean flags are insufficient for this, since we would have to clear them all to false on every
 * frame, requiring a full tree traversal). In the future, we may set this flag to the frame proactively during traversal to speed up validation, but that is not done
 * at the time of this writing.
 **********************
 *
 * @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 Matrix3 = require( 'DOT/Matrix3' );
  var scenery = require( 'SCENERY/scenery' );
  
  var globalIdCounter = 1;
  
  // display instance linked list ops
  function connectDrawables( a, b ) {
    a.nextDrawable = b;
    b.previousDrawable = a;
  }
  
  scenery.DisplayInstance = function DisplayInstance( display, trail ) {
    this.initializedOnce = false;
    
    this.initialize( display, trail );
  };
  var DisplayInstance = scenery.DisplayInstance;
  
  inherit( Object, DisplayInstance, {
    initialize: function( display, trail ) {
      trail.setImmutable(); // prevent the trail passed in from being mutated after this point (we want a consistent trail)
      
      this.id = globalIdCounter++;
      
      this.cleanInstance( display, trail, trail.lastNode() );
      
      // properties relevant to the "relative" transform to the closest transform root. Please see detailed docs at the top of the file!
      this.relativeMatrix = this.relativeMatrix || new Matrix3();  // the actual cached transform to the root
      this.relativeSelfDirty = true;                   // whether our relativeMatrix is dirty
      this.relativeChildDirtyFrame = display._frameId; // Whether children have dirty transforms (if it is the current frame) NOTE: used only for pre-repaint traversal,
                                                       // and can be ignored if it has a value less than the current frame ID. This allows us to traverse and hit all listeners
                                                       // for this particular traversal, without leaving an invalid subtree (a boolean flag here is insufficient, since our
                                                       // traversal handling would validate our invariant of this.relativeChildDirtyFrame => parent.relativeChildDirtyFrame).
                                                       // In this case, they are both effectively "false" unless they are the current frame ID, in which case that invariant holds.
      //this.relativeTransformListeners = [];          // will be notified in pre-repaint phase that our relative transform has changed (but not computed by default)
      this.relativeChildrenListenersCount = 0;         // how many children have (or have descendants with) relativeTransformListeners
      this.relativePrecomputeCount = 0;                // if >0, indicates this should be precomputed in the pre-repaint phase
      this.relativeChildrenPrecomputeCount = 0;        // how many children have (or have descendants with) >0 relativePrecomputeCount
      this.relativeFrameId = -1;                       // used to mark what frame the transform was updated in (to accelerate non-precomputed relative transform access)
      
      // properties relevant to the node's direct transform
      this.transformDirty = true; // whether the node's transform has changed (until the pre-repaint phase)
      
      this.nodeTransformListener = this.markTransformDirty.bind( this );
      this.node.onStatic( 'transform', this.nodeTransformListener );
      
      // If we are a transform root, notify the display that we are dirty. We'll be validated when it's at that phase at the next updateDisplay().
      if ( this.isTransformed ) {
        display.markTransformRootDirty( this, true );
      }
      
      this.initializedOnce = true;
    },
    
    // called for initialization of properties (via initialize(), via constructor), or to clean the instance for placement in the pool (don't leak memory)
    cleanInstance: function( display, trail, node ) {
      this.display = display;
      this.trail = trail;
      this.node = node;
      this.parent = null; // will be set as needed
      this.children = cleanArray( this.children ); // Array[DisplayInstance]
      this.sharedCacheInstance = null; // reference to a shared cache instance (if applicable, it's different than a child)
      
      this.selfDrawable = null;
      this.groupDrawable = null; // e.g. backbone or non-shared cache
      this.sharedCacheDrawable = null; // our drawable if we are a shared cache
      
      // references into the linked list of drawables (null if nothing is drawable under this)
      this.firstDrawable = null;
      this.lastDrawable = null;
      
      // references that will be filled in with syncTree
      this.state = null;
      this.isTransformed = false; // whether this instance creates a new "root" for the relative trail transforms
      
      // will be notified in pre-repaint phase that our relative transform has changed (but not computed by default)
      // NOTE: it's part of the relative transform feature, see above for documentation
      //OHTWO TODO: should we rely on listeners removing themselves?
      this.relativeTransformListeners = cleanArray( this.relativeTransformListeners );
    },
    
    // updates the internal {RenderState}, and fully synchronizes the instance subtree
    /*OHTWO TODO:
     * Create new instances for added children
     * Remove instances for removed children
     * Rearrange instances for moved children
     * *** Handle compatibility state check with children, rebuild them if necessary
     * Mark unused instances/drawables on the Display for recycling after completing update?
     * Pruning:
     *   - If children haven't changed, skip instance add/move/remove
     *   - If RenderState hasn't changed AND there are no render/instance/stitch changes below us, EXIT (whenever we are assured children don't need sync)
     * Return linked-list of alternating changed (add/remove) and keep sections of drawables, for processing with backbones/canvas caches
     *
     * Other notes:
     *
{'fraction_non_alphanumeric': 0.058211975715249394, 'fraction_numerical': 0.0015078766715606524, 'mean_word_length': 3.4447971781305116, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2335844', 'n_tokens_mistral': 5863, 'n_tokens_neox': 5698, 'n_words': 3174}