using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; namespace Awperative; public abstract partial class Container { public ImmutableArray Behaviors => [.._behaviors]; internal HashSet _behaviors = []; /// /// Add a new Behavior to the Docker; This is the only way they should be created. /// /// Arguments to construct the Behavior with /// Type of Behavior to instantiate /// public Component Add(object[] __args) where Generic : Component { //Log Action Debug.LogAction("Adding Component to Docker", ["Type", "Args", "Docker"], [typeof(Generic).ToString(), "[" + string.Join(", ", __args.SelectMany(x => x.ToString())) + "]", GetHashCode().ToString()]); //Behavior does not have a constructor that matches the given args if (typeof(Generic).GetConstructor((Type[])__args) == null) { Debug.LogError("Behavior cannot be constructed with the given arguments", ["Type", "Args"], [typeof(Generic).ToString(), "[" + string.Join(", ", __args.SelectMany(x => x.ToString())) + "]"]); return null; }; Component newComponent; //Tries to instantiate behavior, and sends a fail call if an issue occurs. try { newComponent = (Generic)Activator.CreateInstance(typeof(Generic), __args); } catch { Debug.LogError("Behavior creation failed!", ["Type", "Args", "Docker"], [typeof(Generic).ToString(), "[" + string.Join(", ", __args.SelectMany(x => x.ToString())) + "]", GetHashCode().ToString()]); return null; } //If behavior is null do not add if(newComponent == null) { Debug.LogError("Activator created Null Behavior", ["Type", "Args", "Docker"], [typeof(Generic).ToString(), "[" + string.Join(", ", __args.SelectMany(x => x.ToString())) + "]", GetHashCode().ToString()]); return null; } //Add to docker and initialize the new Behavior _behaviors.Add(newComponent); newComponent.Initiate(this); //Logs successful action! Debug.LogState("Successfully Created Behavior and Attached it to Docker", ["Type", "Args", "Docker", "Behavior"], [typeof(Generic).ToString(), "[" + string.Join(", ", __args.SelectMany(x => x.ToString())) + "]", GetHashCode().ToString(), newComponent.GetHashCode().ToString()]); return newComponent; } /// /// Adds a new Behavior to the Docker; This is the only way they should be created. /// /// /// public Component Add() where Generic : Component => Add([]); /// /// Transfers a Behavior to another Docker /// /// Component to move /// Container to move component to public void Transfer(Component __component, Container __container) { Debug.LogAction("Transferring Component to Different Docker", ["Component", "Type", "CurrentDocker", "NewDocker"], [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString(), __container.GetHashCode().ToString()]); if (!_behaviors.Contains(__component)) { Debug.LogError("Docker does not have ownership of Behavior", ["Component", "Type", "CurrentDocker", "NewDocker"], [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString(), __container.GetHashCode().ToString()]); return; } //Update docker lists __container._behaviors.Add(__component); _behaviors.Remove(__component); //Update components parent __component.Container = __container; Debug.LogState("Successfully Transferred Component to a new Docker" , ["Component", "Type", "CurrentDocker", "NewDocker"], [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString(), __container.GetHashCode().ToString()]); } /// /// Transfers the first found Behavior of a specific type to another Docker /// /// Container to move component to /// Type of component public void Transfer(Container container) where Generic : Component => Transfer(Get(), container); /// /// Transfers all Components in a list to another Container. /// /// List of Components to transfer /// Container to move Component to public void TransferAll(IEnumerable __behaviors, Container container) { foreach (Component behavior in __behaviors) Transfer(behavior, container); } /// /// Transfers all Components of a type to another Container. /// /// Target container /// Type of Components to transfer public void TransferAll(Container container) where Generic : Component => TransferAll(GetAll(), container); /// /// Searches and returns the first Component of a type found on the Docker. /// /// The Type of Component to search for /// public Component Get() where Generic : Component { Debug.LogAction("Searching for Component", ["Type", "Docker"], [typeof(Generic).ToString(), GetHashCode().ToString()]); //Iterates through the loop and returns if a match is found foreach (Component component in _behaviors) { if (component is Generic foundComponent) { Debug.LogState("Found Component", ["Type", "Behavior", "Docker"], [typeof(Generic).ToString(), foundComponent.GetHashCode().ToString(), GetHashCode().ToString()]); return foundComponent; } } //Throws error if there is no Component found Debug.LogError("Docker does not have target Component", ["Type", "Docker"], [typeof(Generic).ToString(), GetHashCode().ToString()]); return null; } /// /// Searches and returns all Components of a type found on the Docker. /// /// The Type of Components to search for /// public ImmutableArray GetAll() where Generic : Component { Debug.LogAction("Searching for all Components on Docker", ["Type", "Docker"], [typeof(Generic).ToString(), GetHashCode().ToString()]); List foundComponents = []; //Iterates through the loop and returns if a match is found foreach (Component component in _behaviors) { if (component is Generic foundComponent) { foundComponents.Add(foundComponent); } } //Throws error if there is no Component found if (foundComponents.Count == 0) { Debug.LogError("Docker does not have target Component", ["Type", "Docker"], [typeof(Generic).ToString(), GetHashCode().ToString()]); return []; } Debug.LogState("Found Components on Docker", ["Components", "Type", "Docker"], [(foundComponents.SelectMany(x => x.GetHashCode().ToString()) + "]").ToString(), typeof(Generic).ToString(), GetHashCode().ToString()]); return foundComponents.ToImmutableArray(); } /// /// Destroys a Component attached to docker /// /// public void Destroy(Component component) { //Component is null if (component == null) { Debug.LogError("Component is null", ["CurrentDocker"], [GetHashCode().ToString()]); return; } //Docker doesn't have Component if (!_behaviors.Contains(component)) { Debug.LogError("Docker does not have ownership of Behavior", ["Component", "Type", "CurrentDocker"], [component.GetHashCode().ToString(), component.GetType().ToString(), GetHashCode().ToString()]); return; } component.Destroy(); _behaviors.Remove(component); } public void Destroy() where Generic : Component { try { Component foundComponent = Get(); foundComponent.Destroy(); _behaviors.Remove(foundComponent); }catch { Debug.LogError("Removal failed"); } } public void DestroyAll() where Generic : Component { try { foreach (Component component in GetAll()) { component.Destroy(); _behaviors.Remove(component); } }catch { Debug.LogError("Removal failed"); } } public void Remove(Component component) { if(!_behaviors.Contains(component)) { Debug.LogError("Body does not have a component of this type"); return; } _behaviors.Remove(component); } public void Remove() where Generic : Component { try { Component foundComponent = Get(); _behaviors.Remove(foundComponent); }catch { Debug.LogError("Removal failed"); } } public void RemoveAll() where Generic : Component { try { foreach (Component component in GetAll()) { _behaviors.Remove(component); } }catch { Debug.LogError("Removal failed"); } } }