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})";
}
}