using Ghost.Entities; using System.Collections.ObjectModel; namespace Ghost.Editor.Core.SceneGraph; /// /// Represents an entity node in the editor scene graph hierarchy. /// Contains editor-only metadata like display name and hierarchy information. /// public class EntityNode { private string _name; private readonly ObservableCollection _children; /// /// Gets or sets the entity this node represents. /// public Entity Entity { get; set; } /// /// Gets or sets the display name for this entity in the editor. /// This is NOT stored in runtime components. /// public string Name { get => _name; set { _name = value; OnNameChanged?.Invoke(this); } } /// /// Gets the parent node of this entity node. /// public EntityNode? Parent { get; internal set; } /// /// Gets the scene node that contains this entity. /// public SceneNode? OwnerScene { get; internal set; } /// /// Gets the collection of child entity nodes. /// public ObservableCollection Children => _children; /// /// Event raised when the name property changes. /// public event Action? OnNameChanged; /// /// Event raised when children collection changes. /// public event Action? OnChildrenChanged; public EntityNode(Entity entity, string name = "Entity") { Entity = entity; _name = name; _children = []; _children.CollectionChanged += (s, e) => OnChildrenChanged?.Invoke(this); } /// /// Adds a child entity node to this node. /// /// The child node to add. public void AddChild(EntityNode child) { if (child.Parent != null) { child.Parent.RemoveChild(child); } child.Parent = this; child.OwnerScene = OwnerScene; _children.Add(child); } /// /// Removes a child entity node from this node. /// /// The child node to remove. /// True if the child was removed, false otherwise. public bool RemoveChild(EntityNode child) { if (_children.Remove(child)) { child.Parent = null; return true; } return false; } /// /// Gets all descendants of this node (children, grandchildren, etc.) in depth-first order. /// /// An enumerable of all descendant nodes. public IEnumerable GetAllDescendants() { foreach (var child in _children) { yield return child; foreach (var descendant in child.GetAllDescendants()) { yield return descendant; } } } /// /// Finds an entity node by its entity reference. /// /// The entity to search for. /// The entity node if found, null otherwise. public EntityNode? FindNode(Entity entity) { if (Entity.Equals(entity)) { return this; } foreach (var child in _children) { var found = child.FindNode(entity); if (found != null) { return found; } } return null; } public override string ToString() { return $"{Name} (Entity: {Entity})"; } }