using System.Collections.Generic; using System.Collections.Immutable; namespace AwperativeKernel; public abstract partial class Component : ComponentDocker { /// /// Current parent of the Component. Can be either Scene or another Component. /// public ComponentDocker ComponentDocker { get; internal set; } /// /// If the component receives time events or not. /// public bool Enabled = true; /// /// Order for when Components are called on. Only applies between Components on the same Docker. /// public int Priority { get => _priority; set => ComponentDocker.UpdatePriority(this, value); } internal int _priority; /// /// To be called when the Component is created. /// /// Docker that this spawned in this Component internal void Initiate(ComponentDocker __parent) { ComponentDocker = __parent; Create(); } /// /// Called when the Game is Closing; does not always happen depending on if it is Force Closed. /// protected internal virtual void Unload() {} /// /// Called when the Game is Loading. /// protected internal virtual void Load() {} /// /// Called every frame before Draw, it is recommended to do any Non-Drawing update logic here. /// protected internal virtual void Update() {} /// /// Called after Update when the screen is being drawn. Please only put Drawing related logic here. /// protected internal virtual void Draw() {} /// /// Called when the Component is created. /// protected internal virtual void Create() {} /// /// Called when the Component is destroyed. Not called when the Game is closed. /// protected internal virtual void Destroy() {} /// /// Scene the Component resides in. /// public Scene Scene => __QueryScene(); protected Scene __QueryScene() { if (ComponentDocker is Scene scene) return scene; if (ComponentDocker is Component Component) return Component.__QueryScene(); return null; } /// /// Identifiers for Components. /// public ImmutableArray Tags => [.._tags]; internal HashSet _tags = []; /// /// Adds a new tag to the Component /// /// The tag to add public void AddTag(string __tag) => ComponentDocker.HashTaggedComponent(this, __tag); /// /// Removes a tag from the Component /// /// The tag to remove public void RemoveTag(string __tag) => ComponentDocker.UnhashTaggedComponent(this, __tag); /// /// All parent Dockers and the parents of the parents up until the Scene. Will only list parents of parents, not uncle dockers. /// /// Dockers[0] is the parent of this object, and Dockers[^1] is the Scene. public ImmutableArray Dockers => __QueryDockers(); protected ImmutableArray __QueryDockers() { List returnValue = []; ComponentDocker currentComponentDocker = ComponentDocker; while (!(currentComponentDocker is Scene)) { if (currentComponentDocker is Component Component) { returnValue.Add(currentComponentDocker); currentComponentDocker = Component.ComponentDocker; } else { Debug.LogError("Component has a Parent that is not a Scene or Component, Please do not use the Docker class unless you know what you are doing!", ["Component", "Type", "Docker"], [GetHashCode().ToString(), GetType().ToString(), ComponentDocker.GetHashCode().ToString()]); } } returnValue.Add(currentComponentDocker); return [..returnValue]; } /// /// Returns the Parent Component. Will be null if the Component is under a scene. /// public Component Parent => __QueryParent(); protected Component __QueryParent() { if (ComponentDocker is Component Component) return Component; return null; } /// /// All parent Components and the parents of the parents up until the Scene. Will only list parents of parents, not uncle Components. /// public ImmutableArray Parents => __QueryComponents(); protected ImmutableArray __QueryComponents() { List returnValue = []; ComponentDocker currentComponentDocker = ComponentDocker; while (!(currentComponentDocker is Scene)) if (currentComponentDocker is Component Component) { returnValue.Add(Component); currentComponentDocker = Component.ComponentDocker; } return [..returnValue]; } /// /// Creates a new Scene /// /// Name of the Scene public Scene CreateScene(string __name) => Awperative.CreateScene(__name); /// /// Finds a scene. /// /// Name of the Scene /// public Scene GetScene(string __name) => Awperative.GetScene(__name); /// /// Destroys a Scene forever /// /// Target scene public void RemoveScene(Scene __scene) => Awperative.CloseScene(__scene); /// /// Destroys a Scene forever /// /// Name of the Scene public void RemoveScene(string __name) => Awperative.CloseScene(__name); }