using System.Collections.Generic; using Godot; using System; using Rokojori.Extensions; namespace Rokojori { /** One Resource a TextureStackTexture2D has to listen to, and which layer an edit to it should redraw from. Exists because the change tree is deeper than the compositing tree. A composite walks layers; staying in sync means also watching every mask, every TextureSettings, every stamp set, every nested stack and every plain Texture2D sitting in a slot. All of those report the draw index of the layer that owns them, so an edit three levels down still becomes an incremental redraw from the right place rather than a full recomposite. Why this is needed at all: Godot does not emit `changed` on a scripted Resource when the inspector edits a plain [Export] field. Built-in resources emit it by hand from their setters - that is why Gradient, Curve and BaseMaterial3D all call emit_changed() in every setter. So every resource in this system does the same, and this is how they are found and subscribed. */ public struct TextureStackChangeSource { public Resource resource; /** Draw index of the owning layer - 0 is the bottom layer. */ public int drawIndex; /** Adds unless it is null or already in the list. The same resource reachable from two layers keeps the lower draw index, because a redraw has to start from the lowest layer the edit can affect. */ public static void Add( List into, Resource resource, int drawIndex ) { if ( resource == null || into == null ) { return; } for ( var i = 0; i < into.Count; i++ ) { if ( into[ i ].resource != resource ) { continue; } if ( drawIndex < into[ i ].drawIndex ) { var existing = into[ i ]; existing.drawIndex = drawIndex; into[ i ] = existing; } return; } into.Add( new TextureStackChangeSource(){ resource = resource, drawIndex = drawIndex } ); } } }