diff --git a/AwperativeKernel/Kernel/Component/Component.cs b/AwperativeKernel/Kernel/Component/Component.cs index 569b538..e4f7652 100644 --- a/AwperativeKernel/Kernel/Component/Component.cs +++ b/AwperativeKernel/Kernel/Component/Component.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Linq; using System.Reflection; +using Microsoft.VisualBasic; namespace AwperativeKernel; @@ -37,15 +39,7 @@ public abstract partial class Component : ComponentDocker /// - internal List EventDelegates; - - - - /// - /// - /// - internal Type _type; - + internal Collection EventDelegates = []; @@ -69,23 +63,20 @@ public abstract partial class Component : ComponentDocker /// /// Docker that this spawned in this Component /// Name of the component - internal void Initiate(ComponentDocker __parent, string __name, ICollection __tags) { + internal void Initiate(ComponentDocker __parent, string __name, ICollection __tags, Type __type) { ComponentDocker = __parent; Name = __name; _tags = [..__tags]; - _type = GetType(); - EventDelegates = new List(); for(int i = 0; i < Awperative.allEvents.Count; i++) EventDelegates.Add(null); - - - if (Awperative._TypeAssociatedTimeEvents.TryGetValue(GetType(), out HashSet presentEvents)) { - foreach (Awperative.TimeEvent presentEvent in presentEvents) { - MethodInfo info = GetType().GetMethod(presentEvent.ToString()); - Action newAction = (Action)Delegate.CreateDelegate(typeof(Action), this, info); - EventDelegates[(int)presentEvent] = newAction; + 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"], [GetType().ToString()]); + Debug.LogError("Awperative does not recognize the given type! Perhaps it was created after Start() was called?", ["Type"], [__type.Name]); } } @@ -106,6 +97,10 @@ public abstract partial class Component : ComponentDocker + public void TryEvent(int __timeEvent) { + EventDelegates[__timeEvent]?.Invoke(); + } + @@ -239,26 +234,4 @@ public abstract partial class Component : ComponentDocker for (int i = 0; i < targets.Count; i++) targets.InsertRange(i + 1, targets[i]._Components); return [..targets]; } - - - - internal ImmutableArray GetAllEvents() { - if (Awperative._TypeAssociatedTimeEvents.TryGetValue(this.GetType(), out HashSet timeEvents)) { - return [..timeEvents]; - } else { - Debug.LogError("Awperative doesn't recognize this type. Perhaps it was created after Start() was called?", ["Type"], [this.GetType().Name]); - return []; - } - } - - - internal ImmutableArray GetAllGlobalEvents() { - if (Awperative._TypeAssociatedTimeEvents.TryGetValue(this.GetType(), out HashSet timeEvents)) { - foreach (Awperative.TimeEvent timeEvent in timeEvents) if (!Awperative.globalEvents.Contains(timeEvent)) timeEvents.Remove(timeEvent); - return [..timeEvents]; - } else { - Debug.LogError("Awperative doesn't recognize this type. Perhaps it was created after Start() was called?", ["Type"], [this.GetType().Name]); - return []; - } - } } \ No newline at end of file diff --git a/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs b/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs index 9ce1306..837a7b9 100644 --- a/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs +++ b/AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Linq; using System.Reflection; @@ -60,45 +61,22 @@ public abstract class ComponentDocker internal void UpdatePriority(Component __component, int __priority) { //add ownership enforcement/method - foreach (String tag in __component._tags) _taggedComponents[tag].Remove(__component); - foreach (Awperative.TimeEvent timeEvent in __component.GetAllEvents()) { Awperative._TimeBasedComponents[timeEvent].Remove(__component);} - _Components.Remove(__component); + foreach (String tag in __component._tags) _taggedComponents[tag].Remove(__component); _Components.Remove(__component); __component._priority = __priority; - foreach (String tag in __component._tags) _taggedComponents[tag].Add(__component); - foreach (Awperative.TimeEvent timeEvent in __component.GetAllEvents()) { Awperative._TimeBasedComponents[timeEvent].Add(__component);} - _Components.Add(__component); - } - - - /// - /// Chains an event to all children, NOT MEANT FOR UPDATE OR DRAW ETC, JUST CREATE AND DESTROY - /// - /// - internal void TryEvent(Component __component, Awperative.TimeEvent __timeEvent) { - __component.EventDelegates[(int)__timeEvent]?.Invoke(); + foreach (String tag in __component._tags) _taggedComponents[tag].Add(__component); _Components.Add(__component); } //internal void TryEvent(Component __component, Awperative.TimeEvent __timeEvent) => __component.TryEvent(__timeEvent); + - - /// - /// Chains an event to all children, NOT MEANT FOR UPDATE OR DRAW ETC, JUST CREATE AND DESTROY - /// - /// - internal void ChainEvent(Awperative.TimeEvent __timeEvent) { - - if (this is Component dockerComponent) { - - TryEvent(dockerComponent, __timeEvent); - foreach (Component component in _Components.ToList()) { - component.EventDelegates[(int)__timeEvent]?.Invoke(); - component.ChainEvent(__timeEvent); - } - } else Debug.LogError("Please do not call chain event on anything besides a Component! It is meant for Create() and Destroy()"); - } + internal void ChainEvent(int __timeEvent) { foreach (Component component in _Components) { component.TryEvent(__timeEvent); component.ChainEvent(__timeEvent); }} + + + + @@ -110,47 +88,50 @@ public abstract class ComponentDocker /// /// Arguments to construct the Component with /// Type of Component to instantiate - /// - public __Type Add<__Type>(IEnumerable __args, string name = "", ICollection tags = null) where __Type : Component { + /// s + public __Type Add<__Type>(object[] __args, string name = "", ICollection tags = null) where __Type : Component { - if(name == "") { name = typeof(__Type).Name; } + 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 (typeof(__Type).GetConstructor(__args.Select(x => x.GetType()).ToArray()) == null) { + if (newComponentType.GetConstructor(__args.Select(x => x.GetType()).ToArray()) == null) { Debug.LogError("Component cannot be constructed with the given arguments", ["Type", "Args"], - [typeof(__Type).ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]"]); return null; + [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(typeof(__Type), __args); } + try { newComponent = (__Type)Activator.CreateInstance(newComponentType, __args); } catch { Debug.LogError("Component creation failed!", ["Type", "Args", "Docker"], - [typeof(__Type).ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]", GetHashCode().ToString()]); return null; + [newComponentType.ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]", GetHashCode().ToString()]); return null; } //If Component is null do not add if(newComponent == null) { Debug.LogError("Activator created Null Component", ["Type", "Args", "Docker"], - [typeof(__Type).ToString(), "[" + string.Join(", ", __args.Select(x => x.ToString())) + "]", GetHashCode().ToString()]); return null; + [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); - foreach (Awperative.TimeEvent timeEvent in newComponent.GetAllGlobalEvents()) { Awperative._TimeBasedComponents[timeEvent].Add(newComponent); } + newComponent.Initiate(this, name, tags, newComponentType); - newComponent.ChainEvent(Awperative.TimeEvent.Create); + newComponent.TryEvent(4); + newComponent.ChainEvent(4); return (__Type) newComponent; } @@ -531,13 +512,13 @@ public abstract class ComponentDocker [__component.GetHashCode().ToString(), __component.GetType().ToString(), GetHashCode().ToString()]); return; } - __component.ChainEvent(Awperative.TimeEvent.Destroy); + __component.TryEvent(5); + __component.ChainEvent(5); foreach (string tag in __component._tags) UnhashTaggedComponent(__component, tag); __component.ComponentDocker = null; _Components.Remove(__component); - foreach (Awperative.TimeEvent timeEvent in __component.GetAllEvents()) Awperative._TimeBasedComponents[timeEvent].Remove(__component); } diff --git a/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs b/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs index 5a4a635..ae6b605 100644 --- a/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs +++ b/AwperativeKernel/Kernel/Overhead/Awperative/Awperative.cs @@ -111,24 +111,22 @@ public static class Awperative foreach (Type type in Assembly.GetCallingAssembly().GetTypes()) { if (type.IsSubclassOf(typeof(Component))) { - List presentEvents = []; + byte eventProfile = 0; + List debugProfile = []; - foreach (TimeEvent timeType in allEvents) { - if (type.GetMethod(timeType.ToString()) != null) { - presentEvents.Add(timeType); - Debug.LogState("Found Event Method " + timeType); + for(int i = 0; i < ComponentEvents.Count; i++) { + if (type.GetMethod(ComponentEvents[i]) != null) { + eventProfile |= (byte)(1 << i); + debugProfile.Add(ComponentEvents[i]); } } - Debug.LogAction("Evaluated Component! ", ["Type", "Time Events"], [type.Name, "[" + string.Join(", ", presentEvents.Select(x => x.ToString())) + "]"]); - _TypeAssociatedTimeEvents.Add(type, presentEvents.ToHashSet()); + Debug.LogAction("Evaluated Component! ", ["Type", "Time Events", "Profile"], [type.Name, "[" + string.Join(", ", debugProfile.Select(x => x.ToString())) + "]", eventProfile.ToString()]); + _TypeAssociatedTimeEvents.Add(type, eventProfile); } } - - foreach (TimeEvent timeType in globalEvents) - _TimeBasedComponents.Add(timeType, new SortedSet(_componentSorter)); } @@ -140,56 +138,25 @@ public static class Awperative Base = new Base(); Base.Run(); } + + //Load, 0 + //Unload, 1 + //Update, 2 + //Draw 3 + //Create, 4 + //Destroy, 5 + + // 0000 0000 + // + + + internal static ReadOnlyCollection ComponentEvents = new(["Load", "Unload", "Update", "Draw", "Create", "Destroy"]); /// - /// + /// 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 enum TimeEvent - { - Create, - Destroy, - Load, - Unload, - Update, - Draw - } - - - - internal static ImmutableHashSet allEvents = [..Enum.GetValuesAsUnderlyingType().Cast()]; - internal static ImmutableHashSet globalEvents = [TimeEvent.Load, TimeEvent.Unload, TimeEvent.Update, TimeEvent.Draw]; - - - - /// - /// List of all type of components and the associated time events - /// - internal static Dictionary> _TypeAssociatedTimeEvents = new(new TypeComparer()); - - - internal class TypeComparer : IEqualityComparer - { - public bool Equals(Type __a, Type __b) { - return __a.Equals(__b); - } - - public int GetHashCode(Type __type) { - return __type.GetHashCode(); - } - } - - - internal static Dictionary> _TimeBasedComponents = []; - - - - /// - /// How Priority is sorted. - /// - internal readonly static Comparer _componentSorter = Comparer.Create((a, b) => { - int result = b.Priority.CompareTo(a.Priority); - return (result != 0) ? result : a.GetHashCode().CompareTo(b.GetHashCode()); - }); + internal static Dictionary _TypeAssociatedTimeEvents = []; } \ No newline at end of file diff --git a/AwperativeKernel/Kernel/Overhead/Base/Base.cs b/AwperativeKernel/Kernel/Overhead/Base/Base.cs index 5465e3a..b3974c8 100644 --- a/AwperativeKernel/Kernel/Overhead/Base/Base.cs +++ b/AwperativeKernel/Kernel/Overhead/Base/Base.cs @@ -22,7 +22,15 @@ public sealed class Base() : GameWindow(GameWindowSettings.Default, new NativeWi /// LoadContent() is called when the program starts; right after Initialize(). Override Load() in scripting tools or use hooks to call from this event. /// /// It is recommended to load content during LoadContent() - protected override void OnLoad() { foreach (Component component in Awperative._TimeBasedComponents[Awperative.TimeEvent.Load].ToList()) component.ChainEvent(Awperative.TimeEvent.Load); base.OnLoad(); } + protected override void OnLoad() { foreach(Scene scene in Awperative._scenes) scene.ChainEvent(0); base.OnLoad(); } + + + + /// + /// EndRun() is called if the program closes. Override Terminate() in scripting tools or use hooks to call from this event. + /// + /// This event may not trigger if the program is force closed. + protected override void OnClosing(CancelEventArgs __args) { foreach(Scene scene in Awperative._scenes) scene.ChainEvent(1); base.OnClosing(__args); } @@ -32,9 +40,7 @@ public sealed class Base() : GameWindow(GameWindowSettings.Default, new NativeWi /// Update() is called every frame; before Draw(). Override Update() in scripting tools to call from this event. /// /// Hooks are unable to receive both Update() and Draw() - protected override void OnUpdateFrame(FrameEventArgs __args) { foreach (Component component in Awperative._TimeBasedComponents[Awperative.TimeEvent.Update].ToList()) component.ChainEvent(Awperative.TimeEvent.Update); base.OnUpdateFrame(__args); } - - + protected override void OnUpdateFrame(FrameEventArgs __args) { foreach(Scene scene in Awperative._scenes) scene.ChainEvent(2); base.OnUpdateFrame(__args); } @@ -42,19 +48,5 @@ public sealed class Base() : GameWindow(GameWindowSettings.Default, new NativeWi /// Draw() is called every frame; after Update(). Override Draw() in scripting tools to call from this event. /// /// Hooks are unable to receive both Update() and Draw() - protected override void OnRenderFrame(FrameEventArgs __args) { foreach (Component component in Awperative._TimeBasedComponents[Awperative.TimeEvent.Draw].ToList()) component.ChainEvent(Awperative.TimeEvent.Draw); base.OnRenderFrame(__args); } - - - - - - /// - /// EndRun() is called if the program closes. Override Terminate() in scripting tools or use hooks to call from this event. - /// - /// This event may not trigger if the program is force closed. - protected override void OnClosing(CancelEventArgs __args) { foreach (Component component in Awperative._TimeBasedComponents[Awperative.TimeEvent.Unload].ToList()) component.ChainEvent(Awperative.TimeEvent.Unload); base.OnClosing(__args); } - - - - + protected override void OnRenderFrame(FrameEventArgs __args) { foreach(Scene scene in Awperative._scenes) scene.ChainEvent(3); base.OnRenderFrame(__args); } } \ No newline at end of file diff --git a/AwperativeKernel/Kernel/Scene/Scene.cs b/AwperativeKernel/Kernel/Scene/Scene.cs index 58c9d56..6915962 100644 --- a/AwperativeKernel/Kernel/Scene/Scene.cs +++ b/AwperativeKernel/Kernel/Scene/Scene.cs @@ -1,3 +1,6 @@ +using System.Collections.Generic; + + namespace AwperativeKernel; public sealed partial class Scene : ComponentDocker diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfo.cs index 408b563..1c415ff 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+abccecd29531912f8bab0e06c70666b1a8d88ceb")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+32fdae32482131f6e177956aee0f9ddcdf9877cf")] [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 d21f970..d42d723 100644 --- a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache +++ b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.AssemblyInfoInputs.cache @@ -1 +1 @@ -eaefd8ded26140e2f41a812ea39f0e84a94c9d2484a5baede0586b90e9c4efcb +22a4163440a667e1fc9f683e846ca5e0db424c2a4e8629dde601d67fa1038af8 diff --git a/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll b/AwperativeKernel/obj/Debug/net8.0/AwperativeKernel.dll index b7fb2e9..f7d5ab8 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 3901741..33d249e 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 9c2280b..7ca0f88 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 9c2280b..7ca0f88 100644 Binary files a/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll and b/AwperativeKernel/obj/Debug/net8.0/refint/AwperativeKernel.dll differ