diff --git a/AwperativeKernel.sln.DotSettings.user b/AwperativeKernel.sln.DotSettings.user
index 13e04fa..de6613a 100644
--- a/AwperativeKernel.sln.DotSettings.user
+++ b/AwperativeKernel.sln.DotSettings.user
@@ -1,4 +1,6 @@
+ ForceIncluded
+ ForceIncluded
<AssemblyExplorer>
<Assembly Path="/Users/averynorris/Programming/Test/Awperative/Awperative/bin/Debug/net8.0/Awperative.dll" />
</AssemblyExplorer>
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/Component/Component.cs b/AwperativeKernel/Kernel/Component/Component.cs
index e4f7652..79fe4ad 100644
--- a/AwperativeKernel/Kernel/Component/Component.cs
+++ b/AwperativeKernel/Kernel/Component/Component.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Microsoft.VisualBasic;
@@ -12,15 +13,15 @@ namespace AwperativeKernel;
-public abstract partial class Component : ComponentDocker
+public abstract partial class Component : ComponentDocker, IDisposable
{
-
-
-
+
+
+
///
/// Current parent of the Component. Can be either Scene or another Component.
///
- public ComponentDocker ComponentDocker { get; internal set; }
+ public ComponentDocker ComponentDocker { get; internal set; } = null;
@@ -38,12 +39,8 @@ public abstract partial class Component : ComponentDocker
- ///
- internal Collection EventDelegates = [];
-
-
@@ -58,30 +55,6 @@ public abstract partial class Component : ComponentDocker
- ///
- /// To be called when the Component is created.
- ///
- /// Docker that this spawned in this Component
- /// Name of the component
- internal void Initiate(ComponentDocker __parent, string __name, ICollection __tags, Type __type) {
- ComponentDocker = __parent;
- Name = __name;
- _tags = [..__tags];
-
- if (Awperative._TypeAssociatedTimeEvents.TryGetValue(__type, out byte eventProfile)) {
-
- for (int i = 0; i < Awperative.ComponentEvents.Count; i++) {
- if ((eventProfile & (1 << i)) > 0)
- EventDelegates.Add((Action)Delegate.CreateDelegate(typeof(Action), this, __type.GetMethod(Awperative.ComponentEvents[i])!));
- else EventDelegates.Add(null);
- }
- } else {
- Debug.LogError("Awperative does not recognize the given type! Perhaps it was created after Start() was called?", ["Type"], [__type.Name]);
- }
- }
-
-
-
///
@@ -98,7 +71,8 @@ public abstract partial class Component : ComponentDocker
public void TryEvent(int __timeEvent) {
- EventDelegates[__timeEvent]?.Invoke();
+ Action eventDelegates = Awperative._TypeAssociatedTimeEvents[GetType()][__timeEvent];
+ eventDelegates?.Invoke(this);
}
@@ -234,4 +208,8 @@ public abstract partial class Component : ComponentDocker
for (int i = 0; i < targets.Count; i++) targets.InsertRange(i + 1, targets[i]._Components);
return [..targets];
}
+
+ public virtual void Dispose() {
+ GC.SuppressFinalize(this);
+ }
}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/ComponentDocker/Attributes/DockerOwns.cs b/AwperativeKernel/Kernel/ComponentDocker/Attributes/DockerOwns.cs
new file mode 100644
index 0000000..61e39cf
--- /dev/null
+++ b/AwperativeKernel/Kernel/ComponentDocker/Attributes/DockerOwns.cs
@@ -0,0 +1,223 @@
+using System;
+
+
+namespace AwperativeKernel;
+
+
+///
+/// Requires that the Docker owns the parameter
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class DockerOwns : Attribute
+{
+
+
+ ///
+ /// Verifies if the Component is actually owned by Docker. Throws an error if not.
+ ///
+ /// Docker we are checking ownership for
+ /// Component to check for
+ public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
+ if (__docker.Contains(__component)) return true;
+
+ Debug.LogError("Docker does not own the Component!", ["ComponentType", "ComponentName", "ComponentHash", "DockerType", "DockerName", "DockerHash"], [
+ __component.GetType().Name,
+ __component.Name,
+ __component.GetHashCode().ToString("N0"),
+ __docker.GetType().Name,
+ __docker switch { Scene scene => scene.Name, Component component => component.Name, _ => "unknown" },
+ __docker.GetHashCode().ToString("N0")
+ ]);
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the Docker does not own the parameter
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class DockerDoesntOwn : Attribute
+{
+
+
+ ///
+ /// Verifies if the Component is actually not owned by Docker. Throws an error if not.
+ ///
+ /// Docker we are checking ownership for
+ /// Component to check for
+ public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
+ if (!__docker.Contains(__component)) return true;
+
+ Debug.LogError("Docker owns the Component!", ["ComponentType", "ComponentName", "ComponentHash", "DockerType", "DockerName", "DockerHash"], [
+ __component.GetType().Name,
+ __component.Name,
+ __component.GetHashCode().ToString("N0"),
+ __docker.GetType().Name,
+ __docker switch { Scene scene => scene.Name, Component component => component.Name, _ => "unknown" },
+ __docker.GetHashCode().ToString("N0")
+ ]);
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the component is not attached to any Docker
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class OrphanComponent : Attribute
+{
+
+
+ ///
+ /// Verifies if the Component is an orphan, not fully accurate, because it only checks if the docker is null, this means it is technically possible
+ /// to have a component already attached to a docker, and still verify it as false if Docker is null, but this should be impossible in practice.
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(Component __component) {
+ if (__component.ComponentDocker == null) return true;
+
+ Debug.LogError("Component is already owned!", ["ComponentType", "ComponentName", "ComponentHash", "DockerType", "DockerName", "DockerHash"], [
+ __component.GetType().Name,
+ __component.Name,
+ __component.GetHashCode().ToString("N0"),
+ __component.ComponentDocker.GetType().Name,
+ __component.ComponentDocker switch { Scene scene => scene.Name, Component component => component.Name, _ => "unknown" },
+ __component.ComponentDocker.GetHashCode().ToString("N0")
+ ]);
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the Component is not null
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class ComponentNotNull : Attribute
+{
+
+
+ ///
+ /// Verifies if the Component is not null! Throws an error otherwise.
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(Component __component) {
+ if (__component != null) return true;
+
+ Debug.LogError("Component is null!");
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the Docker is not null
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class DockerNotNull : Attribute
+{
+
+
+ ///
+ /// Verifies if the Docker is not null! Throws an error otherwise.
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(ComponentDocker __componentDocker) {
+ if (__componentDocker != null) return true;
+
+ Debug.LogError("Docker is null!");
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the Scene is not null
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class SceneNotNull : Attribute
+{
+
+
+ ///
+ /// Verifies if the Scene is not null! Throws an error otherwise.
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(Scene __scene) {
+ if (__scene != null) return true;
+
+ Debug.LogError("Scene is null!");
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the object is not null
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class NotNull : Attribute
+{
+
+
+ ///
+ /// Verifies if the Scene is not null! Throws an error otherwise.
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(Object __object) {
+ if (__object != null) return true;
+
+ Debug.LogError("A Given parameter is null!", ["Type"],
+ [__object.GetType().Name
+ ]);
+
+ return Awperative.IgnoreErrors;
+ }
+}
+
+
+
+///
+/// Requires that the Docker is a different docker than the one given
+///
+[AttributeUsage(AttributeTargets.Parameter)]
+public class DifferentDocker : Attribute
+{
+
+
+ ///
+ /// Verifies if the Dockers are different!
+ ///
+ ///
+ ///
+ public static bool VerifyOrThrow(ComponentDocker __docker, ComponentDocker __other) {
+ if (__docker != __other) return true;
+
+ Debug.LogError("The Dockers are the same!", ["DockerType, DockerName, DockerHash"], [
+ __docker.GetType().Name,
+ __docker switch { Scene scene => scene.Name, Component component => component.Name, _ => "unknown" },
+ __docker.GetHashCode().ToString("N0")
+ ]);
+
+ return Awperative.IgnoreErrors;
+ }
+}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/ComponentDocker/ComponentDockEnum.cs b/AwperativeKernel/Kernel/ComponentDocker/ComponentDockEnum.cs
new file mode 100644
index 0000000..11fde12
--- /dev/null
+++ b/AwperativeKernel/Kernel/ComponentDocker/ComponentDockEnum.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+
+namespace AwperativeKernel;
+
+
+
+///
+/// Provides an Enumerator for the Component Docker, Loops through all Components in the Docker all for your convenience :)
+///
+/// Reference to the Component Docker's components, (List to Enumerate through)
+/// Enumerates on a snapshot of the list. This allows you to modify the ComponentDocker's collection during the loop.
+/// Avery Norris
+public class ComponentDockEnum(Component[] __components) : IEnumerator, IEnumerator, IDisposable
+{
+
+
+
+ //Current index of the loop
+ private int index = -1;
+
+
+
+ ///
+ /// Gets the current Component;
+ ///
+ public Component Current => __components[index];
+
+
+
+ ///
+ /// Get the current Component as a generic object
+ ///
+ object IEnumerator.Current => Current;
+
+
+
+ ///
+ /// Proceeds to the next index of the loop
+ ///
+ /// Returns true or false, depending on whether the Enumeration should continue
+ bool IEnumerator.MoveNext() { ++index; return index < __components.Length; }
+
+
+
+ ///
+ /// Resets the loop back to the very start
+ ///
+ public void Reset() => index = -1;
+
+
+
+ ///
+ /// Destroys the enumerator
+ ///
+ public void Dispose() => GC.SuppressFinalize(this);
+
+
+
+}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDocker.cs
similarity index 51%
rename from AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs
rename to AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDocker.cs
index 837a7b9..688b341 100644
--- a/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs
+++ b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDocker.cs
@@ -1,9 +1,11 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
-using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Linq;
using System.Reflection;
+using AwperativeKernel.Attributes;
namespace AwperativeKernel;
@@ -14,9 +16,33 @@ namespace AwperativeKernel;
///
/// Please don't inherit this. I don't know why you would
/// Avery Norris
-public abstract class ComponentDocker
+public abstract partial class ComponentDocker : IEnumerable, IEnumerable, IEquatable, IEquatable
{
+ public bool Equals(Component __other) {
+ if (this is Component component) {
+ return component == __other;
+ } else return false;
+ }
+
+ public bool Equals(ComponentDocker __other) {
+ return this == __other;
+ }
+
+
+ //blocks external inheritance
+ internal ComponentDocker() {}
+
+
+ IEnumerator IEnumerable.GetEnumerator() {
+ return GetEnumerator();
+ }
+
+ public IEnumerator GetEnumerator() {
+ Console.WriteLine("enumerator called" + _Components.Count);
+ return new ComponentDockEnum([.._Components]);
+ }
+
///
@@ -37,7 +63,9 @@ public abstract class ComponentDocker
/// Core of Docker, contains all of our precious Components. Sorts them by their priorities with highest going first.
/// If they are equal it defaults to hash codes to ensure consistent Behavior
///
- internal SortedSet _Components = new(_componentSorter);
+ internal List _Components = new();
+ internal Dictionary> _ComponentDictionary = new();
+ internal Dictionary> _taggedComponents = new();
@@ -60,163 +88,34 @@ public abstract class ComponentDocker
/// New priority for Component
internal void UpdatePriority(Component __component, int __priority) {
//add ownership enforcement/method
-
- foreach (String tag in __component._tags) _taggedComponents[tag].Remove(__component); _Components.Remove(__component);
-
+ _Components.Sort(_componentSorter);
__component._priority = __priority;
-
- foreach (String tag in __component._tags) _taggedComponents[tag].Add(__component); _Components.Add(__component);
}
//internal void TryEvent(Component __component, Awperative.TimeEvent __timeEvent) => __component.TryEvent(__timeEvent);
-
- internal void ChainEvent(int __timeEvent) { foreach (Component component in _Components) { component.TryEvent(__timeEvent); component.ChainEvent(__timeEvent); }}
-
-
-
-
-
-
-
-
-
-
- ///
- /// Add a new Component to the Docker; This is the only way they should be created.
- ///
- /// Arguments to construct the Component with
- /// Type of Component to instantiate
- /// s
- public __Type Add<__Type>(object[] __args, string name = "", ICollection tags = null) where __Type : Component {
-
- Type newComponentType = typeof(__Type);
-
- if(name == "") { name = newComponentType.Name; }
- if (tags == null) tags = [];
-
-
-
-
- //Component does not have a constructor that matches the given args
- if (newComponentType.GetConstructor(__args.Select(x => x.GetType()).ToArray()) == null) {
- Debug.LogError("Component cannot be constructed with the given arguments",
- ["Type", "Args"],
- [newComponentType.ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]"]); return null;
- };
-
- Component newComponent;
-
-
-
- //Tries to instantiate Component, and sends a fail call if an issue occurs.
- try { newComponent = (__Type)Activator.CreateInstance(newComponentType, __args); }
- catch {
- Debug.LogError("Component creation failed!", ["Type", "Args", "Docker"],
- [newComponentType.ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]", GetHashCode().ToString()]); return null;
+ internal void ChainEvent(int __timeEvent) {
+ for (int i = 0; i < _Components.Count; i++) {
+ _Components[i].TryEvent(__timeEvent);
+ _Components[i].ChainEvent(__timeEvent);
}
-
-
- //If Component is null do not add
- if(newComponent == null) {
- Debug.LogError("Activator created Null Component", ["Type", "Args", "Docker"],
- [newComponentType.ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]", GetHashCode().ToString()]); return null;
- }
-
-
- //Add to docker and initialize the new Component
- _Components.Add(newComponent);
- newComponent.Initiate(this, name, tags, newComponentType);
-
- newComponent.TryEvent(4);
- newComponent.ChainEvent(4);
-
- return (__Type) newComponent;
}
-
-
-
- ///
- /// Adds a new Component to the Docker; This is the only way they should be created.
- ///
- ///
- ///
- public __Type Add<__Type>(string name = "", string[] tags = null) where __Type : Component => Add<__Type>([], name: name, tags: tags);
+
+
+
+
-
-
-
-
-
- ///
- /// Transfers a child Component to another Docker
- ///
- /// Component to move
- /// Docker to move component to
- /// Components cannot transfer themselves with this Method!
- public void Move(Component __component, ComponentDocker __componentDocker) {
-
-
-
- //This allows self transfer behavior while preserving Docker's actual job, Before all other statements to prevent Double-Debugging.
- if (__component == this) { __component.ComponentDocker.Move(__component, __componentDocker); return; }
-
-
-
- if (__component == null) {
- Debug.LogError("Component is null!", ["CurrentDocker", "NewDocker"],
- [GetHashCode().ToString(), __componentDocker.GetHashCode().ToString()]); return; }
-
-
-
- if (!_Components.Contains(__component)) {
- Debug.LogError("Docker does not have ownership of Component", ["Component", "Type", "CurrentDocker", "NewDocker"],
- [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString(), __componentDocker.GetHashCode().ToString()]); return; }
-
-
-
- //Update docker lists
- __componentDocker._Components.Add(__component);
- _Components.Remove(__component);
-
-
-
- //Update components parent
- __component.ComponentDocker = __componentDocker;
- }
-
-
-
- ///
- /// Transfers the first found Component of a specific type to another Docker
- ///
- /// Docker to move component to
- /// Type of component
- public void Move<__Type>(ComponentDocker __componentDocker) where __Type : Component => Move(Get<__Type>(), __componentDocker);
-
-
-
- ///
- /// Transfers all Components in a list to another Docker.
- ///
- /// List of Components to transfer
- /// Docker to move Component to
- public void MoveAll(IEnumerable __Components, ComponentDocker __componentDocker) { foreach (Component Component in (Component[])[..__Components]) Move(Component, __componentDocker); }
-
-
-
- ///
- /// Transfers all Components of a type to another Docker.
- ///
- /// Target Docker
- /// Type of Components to transfer
- public void MoveAll<__Type>(ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>(), __componentDocker);
+
+
+
+
+
@@ -224,13 +123,9 @@ public abstract class ComponentDocker
+
+
-
-
- /// ///
- /// Holds Components at Keys of their tags.
- ///
- internal Dictionary> _taggedComponents = [];
@@ -463,97 +358,33 @@ public abstract class ComponentDocker
- ///
- /// Returns a bool based on if the Docker contains a Component with the given tag or not
- ///
- ///
- ///
- public bool Contains(string __tag) => _taggedComponents.ContainsKey(__tag);
-
-
- ///
- /// Returns a bool based on if the Docker contains a Component of that type or not
- ///
- /// Type of the Component
- ///
- public bool Contains<__Type>() where __Type : Component => _Components.Any(x => x is __Type);
-
-
-
- ///
- /// Returns a bool based on if the current __Component is owned by this Docker
- ///
- ///
- ///
- public bool Contains(Component __component) => _Components.Contains(__component);
-
-
-
-
-
- ///
- /// Destroys a Component attached to docker
- ///
- ///
- public void Remove(Component __component) {
- //Component is null
- if (__component == null) {
- Debug.LogError("Component is null", ["CurrentDocker"],
- [GetHashCode().ToString()]); return;
- }
+ private void AddComponentToLists(Component __component) {
+ var Type = __component.GetType();
+ _Components.Add(__component);
+ if (!_ComponentDictionary.TryAdd(Type, [__component])) _ComponentDictionary[Type].Add(__component);
-
- //Docker doesn't have Component
- if (!_Components.Contains(__component)) {
- Debug.LogError("Docker does not have ownership of Component", ["Component", "Type", "CurrentDocker"],
- [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString()]); return;
- }
-
- __component.TryEvent(5);
- __component.ChainEvent(5);
-
- foreach (string tag in __component._tags) UnhashTaggedComponent(__component, tag);
- __component.ComponentDocker = null;
-
- _Components.Remove(__component);
+ for(var i = 0; i < __component.Tags.Length; i++) { HashTaggedComponent(__component.Tags[i], __component); }
}
-
-
-
- ///
- /// Destroys the first found Component of a given type
- ///
- /// Type of Component to destroy
- public void Remove<__Type>() where __Type : Component => Remove(Get<__Type>());
+ private void RemoveComponentFromLists(Component __component) {
+ var Type = __component.GetType();
+ _Components.Remove(__component);
+
+ if(!_ComponentDictionary.ContainsKey(Type)) _ComponentDictionary[Type].Remove(__component);
+
+ for(var i = 0; i < __component.Tags.Length; i++) { UnhashTaggedComponent(__component.Tags[i], __component); }
+ }
+ private void HashTaggedComponent(string __tag, Component __component) {
+ if (!_taggedComponents.TryAdd(__component.Tags[i], [__component]))
+ _taggedComponents[__component.Tags[i]].Add(__component);
+ }
- ///
- /// Destroys all Components from a given collection.
- ///
- ///
- public void RemoveAll(IEnumerable __Components) { foreach (Component component in (Component[])[..__Components]) { Remove(component); } }
+ private void UnhashTaggedComponent(string __tag, Component __component) {
+ if(!_taggedComponents.ContainsKey(__tag)) _taggedComponents[__tag].Remove(__component);
+ }
-
-
- ///
- /// Destroys all Components of a given type
- ///
- ///
- public void RemoveAll<__Type>() where __Type : Component => RemoveAll(GetAll<__Type>());
-
-
-
- ///
- /// Destroys all Components attached to Docker
- ///
- public void RemoveAll() { foreach (Component component in (Component[])[.._Components]) { Remove(component); } }
-
-
-
-
-
}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerExposure.cs b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerExposure.cs
new file mode 100644
index 0000000..e396e20
--- /dev/null
+++ b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerExposure.cs
@@ -0,0 +1,32 @@
+
+
+namespace AwperativeKernel;
+
+
+public abstract partial class ComponentDocker
+{
+
+
+ ///
+ /// Returns a bool based on if the Docker contains a Component with the given tag or not
+ ///
+ ///
+ ///
+ public bool Contains([NotNull] string __tag) => NotNull.VerifyOrThrow(__tag) && _taggedComponents.ContainsKey(__tag);
+
+
+ ///
+ /// Returns a bool for if the Docker contains a Component of that type or not
+ ///
+ /// Type of the Component
+ public bool Contains<__Type>() where __Type : Component => _ComponentDictionary.ContainsKey(typeof(__Type));
+
+
+
+ ///
+ /// Returns a bool based on if the current __Component is owned by this Docker
+ ///
+ ///
+ ///
+ public bool Contains([ComponentNotNull,DockerOwns] Component __component) => NotNull.VerifyOrThrow(__component) && DockerOwns.VerifyOrThrow(this, __component) && _Components.Contains(__component);
+}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerManagement.cs b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerManagement.cs
new file mode 100644
index 0000000..292fdde
--- /dev/null
+++ b/AwperativeKernel/Kernel/ComponentDocker/Core/ComponentDockerManagement.cs
@@ -0,0 +1,189 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+
+
+namespace AwperativeKernel;
+
+
+public abstract partial class ComponentDocker
+{
+
+
+
+ ///
+ /// Adds a previously instantiated Component to the Docker
+ ///
+ /// The Component to add
+ /// This is NOT meant to transfer a Component from one docker to another (Please use Move() for that).
+ /// And If you are just instantiating an Empty Component, also consider instead using Add<Type>();
+ /// Avery Norris
+ #nullable enable
+ public void Add([ComponentNotNull,OrphanComponent] Component __component) {
+ if(!ComponentNotNull.VerifyOrThrow(__component)) return;
+ if(!OrphanComponent.VerifyOrThrow(__component)) return;
+
+ //Component has already been added to another docker
+ if (__component.ComponentDocker != null) { Debug.LogError("You cannot use add if the Component already belongs to a Docker, use Component.Transfer();"); return; }
+
+ InitiateComponent(__component);
+ }
+
+
+
+ ///
+ /// Add a new Component to the Docker; and returns a reference to it!
+ ///
+ /// Type of Component to instantiate
+ /// Component cannot have a Constructor
+ /// Avery Norris
+ public __Type Add<__Type>() where __Type : Component, new() { Component newComponent = new __Type(); InitiateComponent(newComponent); return (__Type)newComponent; }
+
+
+
+ ///
+ /// Add a new Component to the Docker; and returns a reference to it!
+ ///
+ /// Type of Component to instantiate
+ /// Component cannot have a Constructor
+ /// Avery Norris
+ public __Type Add<__Type>(string name = null, int priority = 0, Collection tags = null) where __Type : Component, new() {
+ Component newComponent = new __Type();
+ newComponent.Name = name ??= typeof(__Type).Name;
+ newComponent._tags = [..tags ??= []];
+ newComponent._priority = priority;
+
+ InitiateComponent(newComponent); return (__Type)newComponent;
+ }
+
+
+
+
+
+ ///
+ /// Sets important Component variables; and tries to send the Create() event.
+ ///
+ ///
+ ///
+ private void InitiateComponent(Component __component) {
+ //add to Component Docker's lists
+ AddComponentToLists(__component);
+
+ __component.ComponentDocker = this;
+ //create event
+ __component.TryEvent(4); __component.ChainEvent(4);
+ }
+
+
+
+
+
+ ///
+ /// Transfers a Component to another Docker
+ ///
+ /// Component to move
+ /// Docker to move component to
+ /// Components cannot transfer themselves with this Method!
+ public void Move([ComponentNotNull,DockerOwns] Component __component, [DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) {
+ if(!ComponentNotNull.VerifyOrThrow(__component)) return;
+ if(!DockerOwns.VerifyOrThrow(this, __component)) return;
+ if(!DockerNotNull.VerifyOrThrow(__componentDocker)) return;
+ if(!DifferentDocker.VerifyOrThrow(this, __componentDocker)) return;
+
+ if (!Contains(__component)) {
+ Debug.LogError("Docker does not have ownership over Component!", ["ComponentType"], [__component.GetType().Name]); return;
+ }
+
+ if (__componentDocker == this) {
+ Debug.LogError("Docker already has Component!", ["ComponentType"], [__component.GetType().Name]); return;
+ }
+
+ var type = __component.GetType();
+
+ //Modify collections on both Dockers
+ RemoveComponentFromLists(__component);
+ __componentDocker.AddComponentToLists(__component);
+
+ __component.ComponentDocker = __componentDocker;
+ }
+
+
+
+ ///
+ /// Transfers the first found Component of a specific type to another Docker
+ ///
+ /// Docker to move the Component to
+ /// Type of component
+ public void Move<__Type>([DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) where __Type : Component => Move(Get<__Type>(), __componentDocker);
+
+
+
+ ///
+ /// Transfers all Components in a collection to another Docker.
+ ///
+ /// The Components that need to be transferred
+ /// Docker to move Component to
+ public void MoveAll([ComponentNotNull,DockerOwns] IEnumerable __Components, [DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) { foreach (Component Component in (Component[])[..__Components]) Move(Component, __componentDocker); }
+
+
+
+ ///
+ /// Transfers all Components of a type to another Docker.
+ ///
+ /// Target Docker
+ /// Type of Components to transfer
+ public void MoveAll<__Type>([DockerNotNull, DifferentDocker] ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>(), __componentDocker);
+
+
+
+
+
+ ///
+ /// Destroys a Component attached to the Docker
+ ///
+ ///
+ public void Destroy([ComponentNotNull,DockerOwns] Component __component) {
+ if(!ComponentNotNull.VerifyOrThrow(__component)) return;
+ if(!DockerOwns.VerifyOrThrow(this, __component)) return;
+
+ __component.TryEvent(5);
+ __component.ChainEvent(5);
+
+ RemoveComponentFromLists(__component);
+ __component.ComponentDocker = null;
+
+ __component.Dispose();
+ }
+
+
+
+ ///
+ /// Destroys the first found Component of a given type
+ ///
+ /// Type of Component to destroy
+ public void Destroy<__Type>() where __Type : Component => Destroy(Get<__Type>());
+
+
+
+ ///
+ /// Destroys all Components from a given collection.
+ ///
+ ///
+ public void DestroyAll([ComponentNotNull, DockerOwns] Collection __Components) { for (var i = 0; i < __Components.Count; i++) Destroy(__Components[i]); }
+
+
+
+ ///
+ /// Destroys all Components of a given type
+ ///
+ ///
+ public void DestroyAll<__Type>() where __Type : Component => DestroyAll(GetAll<__Type>());
+
+
+
+ ///
+ /// Destroys all Components attached to Docker
+ ///
+ public void DestroyAll() { for(var i = 0; i < _Components.Count; i++) Destroy(_Components[i]); }
+}
\ No newline at end of file
diff --git a/AwperativeKernel/Kernel/Debug/Debug.cs b/AwperativeKernel/Kernel/Debug/Debug.cs
index d1fb2ba..a5885ae 100644
--- a/AwperativeKernel/Kernel/Debug/Debug.cs
+++ b/AwperativeKernel/Kernel/Debug/Debug.cs
@@ -146,15 +146,17 @@ public static class Debug
///
/// Message to debug
public static void LogError(string __message) => LogGeneric(__message, "ERR", [], []);
-
+
///
/// Writes the current message to the log file. With any given call sign.
///
/// Message to debug
/// Names of values to debug
/// Values to debug
- public static void LogError(string __message, string[] __parameters, string[] __values) => LogGeneric(__message, "ERR", __parameters, __values);
-
+ public static void LogError(string __message, string[] __parameters, string[] __values) {
+ if(Awperative.DebugErrors) LogGeneric(__message, "ERR", __parameters, __values, Awperative.ThrowExceptions);
+ }
+
///
/// Writes the current message to the log file if the condition is true.
///
@@ -173,11 +175,14 @@ public static class Debug
/// Message identifier
/// Names of values to debug
/// Values to debug
- public static void LogGeneric(string __message, string __callSign, string[] __parameters, string[] __values) {
+ /// Should this throw an exception instead
+ public static void LogGeneric(string __message, string __callSign, string[] __parameters, string[] __values, bool __exception = false) {
string output = "\n\n" + __callSign + "- \"" + __message + "\"\n STK-" + new StackTrace();
for (int i = 0; i < __parameters.Length || i < __values.Length; i++)
output += "\n " + __parameters[i] + "- " + __values[i];
+
+ if (__exception) throw new Exception(output);
File.AppendAllText(LogFilePath, output);
}
diff --git a/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs b/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs
index ae6b605..33fcbb9 100644
--- a/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs
+++ b/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs
@@ -2,7 +2,9 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using System.Linq.Expressions;
using System.Reflection;
@@ -44,6 +46,7 @@ public static class Awperative
public static bool DebugMode = false;
+
@@ -111,22 +114,37 @@ public static class Awperative
foreach (Type type in Assembly.GetCallingAssembly().GetTypes()) {
if (type.IsSubclassOf(typeof(Component))) {
+
+ Action[] timeEvents = new Action[ComponentEvents.Count];
+
byte eventProfile = 0;
List debugProfile = [];
for(int i = 0; i < ComponentEvents.Count; i++) {
- if (type.GetMethod(ComponentEvents[i]) != null) {
- eventProfile |= (byte)(1 << i);
+ MethodInfo eventMethod = type.GetMethod(ComponentEvents[i]);
+
+ if (eventMethod != null) {
+
debugProfile.Add(ComponentEvents[i]);
- }
+
+ var ComponentInstanceParameter = Expression.Parameter(typeof(Component), "__component");
+ var Casting = Expression.Convert(ComponentInstanceParameter, type);
+ var Call = Expression.Call(Casting, eventMethod);
+ var Lambda = Expression.Lambda>(Call, ComponentInstanceParameter);
+ timeEvents[i] = Lambda.Compile();
+
+ } else timeEvents[i] = null;
}
Debug.LogAction("Evaluated Component! ", ["Type", "Time Events", "Profile"], [type.Name, "[" + string.Join(", ", debugProfile.Select(x => x.ToString())) + "]", eventProfile.ToString()]);
- _TypeAssociatedTimeEvents.Add(type, eventProfile);
+ _TypeAssociatedTimeEvents.Add(type, timeEvents);
}
}
+
+
+
}
@@ -134,6 +152,7 @@ public static class Awperative
///
/// Starts Awperative up! This method runs forever.
///
+ [DoesNotReturn]
public static void Run() {
Base = new Base();
Base.Run();
@@ -158,5 +177,30 @@ public static class Awperative
/// List of all type of components and the associated time events
/// Each event is a 0 or 1 based on true or false, stored at their index in the byte
///
- internal static Dictionary _TypeAssociatedTimeEvents = [];
+ internal static Dictionary[]> _TypeAssociatedTimeEvents = [];
+
+
+
+ public static SafetyLevel safetyLevel {
+ get => _safetyLevel;
+ set {
+ ThrowExceptions = value is SafetyLevel.Extreme;
+ IgnoreErrors = value is SafetyLevel.Low or SafetyLevel.None;
+ DebugErrors = value is not SafetyLevel.None;
+ _safetyLevel = value;
+ }
+ } private static SafetyLevel _safetyLevel;
+
+ public static bool ThrowExceptions { get; private set; } = false;
+ public static bool IgnoreErrors { get; private set; } = false;
+ public static bool DebugErrors { get; private set; } = true;
+
+
+ //What to do if there is an error, keep in mind low and none still can have errors, because you are turning off validation checking
+ public enum SafetyLevel {
+ Extreme, //Throw exceptions and stop the whole program
+ Normal, //Just debug it to the console, and halt current process
+ Low, //Push through tasks but debug error
+ None, //Ignore most/all errors and do not debug it,
+ }
}
\ No newline at end of file
diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs
index 1c415ff..f3ac88e 100644
--- a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs
+++ b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs
@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+32fdae32482131f6e177956aee0f9ddcdf9877cf")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+abd47153ad47e5c2d5300dcab27ac4628f468ab1")]
[assembly: System.Reflection.AssemblyProductAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyTitleAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache
index d42d723..5663421 100644
--- a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache
+++ b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache
@@ -1 +1 @@
-22a4163440a667e1fc9f683e846ca5e0db424c2a4e8629dde601d67fa1038af8
+8e04a8f03c26d3cf7cdf50da4979193904b566d6f40392f132e749a5bd9092b9
diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.csproj.CoreCompileInputs.cache b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.csproj.CoreCompileInputs.cache
index c5e7555..29e9348 100644
--- a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.csproj.CoreCompileInputs.cache
+++ b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-1492481e4eae3b80db2d149ab088600d21214f29161b6bc87c6dbab466600b9b
+e4b135c3045a438e4953bde74a036a568da5652715efda203daab787973e7f7e
diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll
index f7d5ab8..89b7af5 100644
Binary files a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll and b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll differ
diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.pdb b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.pdb
index 33d249e..8e3e3bf 100644
Binary files a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.pdb and b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.pdb differ
diff --git a/AwperativeKernel/obj/Debug/net8.0/ref/AwperativeKernel.dll b/AwperativeKernel/obj/Debug/net8.0/ref/AwperativeKernel.dll
index 7ca0f88..1b1cce7 100644
Binary files a/AwperativeKernel/obj/Debug/net8.0/ref/AwperativeKernel.dll and b/AwperativeKernel/obj/Debug/net8.0/ref/AwperativeKernel.dll differ
diff --git a/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll b/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll
index 7ca0f88..1b1cce7 100644
Binary files a/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll and b/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll differ