Reflection Better, About to delete a lot of stuff

This commit is contained in:
2026-02-26 16:28:26 -05:00
parent 32fdae3248
commit abd47153ad
11 changed files with 80 additions and 164 deletions

View File

@@ -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<Action> EventDelegates;
/// <summary>
///
/// </summary>
internal Type _type;
internal Collection<Action> EventDelegates = [];
@@ -69,23 +63,20 @@ public abstract partial class Component : ComponentDocker
/// </summary>
/// <param name="__parent"> Docker that this spawned in this Component</param>
/// <param name="__name"> Name of the component</param>
internal void Initiate(ComponentDocker __parent, string __name, ICollection<string> __tags) {
internal void Initiate(ComponentDocker __parent, string __name, ICollection<string> __tags, Type __type) {
ComponentDocker = __parent;
Name = __name;
_tags = [..__tags];
_type = GetType();
EventDelegates = new List<Action>(); for(int i = 0; i < Awperative.allEvents.Count; i++) EventDelegates.Add(null);
if (Awperative._TypeAssociatedTimeEvents.TryGetValue(__type, out byte eventProfile)) {
if (Awperative._TypeAssociatedTimeEvents.TryGetValue(GetType(), out HashSet<Awperative.TimeEvent> 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;
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<Awperative.TimeEvent> GetAllEvents() {
if (Awperative._TypeAssociatedTimeEvents.TryGetValue(this.GetType(), out HashSet<Awperative.TimeEvent> 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<Awperative.TimeEvent> GetAllGlobalEvents() {
if (Awperative._TypeAssociatedTimeEvents.TryGetValue(this.GetType(), out HashSet<Awperative.TimeEvent> 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 [];
}
}
}

View File

@@ -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);
}
/// <summary>
/// Chains an event to all children, NOT MEANT FOR UPDATE OR DRAW ETC, JUST CREATE AND DESTROY
/// </summary>
/// <param name="__timeEvent"></param>
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);
/// <summary>
/// Chains an event to all children, NOT MEANT FOR UPDATE OR DRAW ETC, JUST CREATE AND DESTROY
/// </summary>
/// <param name="__timeEvent"></param>
internal void ChainEvent(Awperative.TimeEvent __timeEvent) {
internal void ChainEvent(int __timeEvent) { foreach (Component component in _Components) { component.TryEvent(__timeEvent); component.ChainEvent(__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()");
}
@@ -110,47 +88,50 @@ public abstract class ComponentDocker
/// </summary>
/// <param name="__args"> Arguments to construct the Component with</param>
/// <typeparam name="__Type"> Type of Component to instantiate</typeparam>
/// <returns></returns>
public __Type Add<__Type>(IEnumerable<Object> __args, string name = "", ICollection<string> tags = null) where __Type : Component {
/// <returns></returns>s
public __Type Add<__Type>(object[] __args, string name = "", ICollection<string> 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);
}

View File

@@ -111,24 +111,22 @@ public static class Awperative
foreach (Type type in Assembly.GetCallingAssembly().GetTypes()) {
if (type.IsSubclassOf(typeof(Component))) {
List<TimeEvent> presentEvents = [];
byte eventProfile = 0;
List<string> 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<Component>(_componentSorter));
}
@@ -141,55 +139,24 @@ public static class Awperative
Base.Run();
}
//Load, 0
//Unload, 1
//Update, 2
//Draw 3
//Create, 4
//Destroy, 5
// 0000 0000
//
/// <summary>
///
/// </summary>
internal enum TimeEvent
{
Create,
Destroy,
Load,
Unload,
Update,
Draw
}
internal static ImmutableHashSet<TimeEvent> allEvents = [..Enum.GetValuesAsUnderlyingType<TimeEvent>().Cast<TimeEvent>()];
internal static ImmutableHashSet<TimeEvent> globalEvents = [TimeEvent.Load, TimeEvent.Unload, TimeEvent.Update, TimeEvent.Draw];
internal static ReadOnlyCollection<string> ComponentEvents = new(["Load", "Unload", "Update", "Draw", "Create", "Destroy"]);
/// <summary>
/// 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
/// </summary>
internal static Dictionary<Type, HashSet<TimeEvent>> _TypeAssociatedTimeEvents = new(new TypeComparer());
internal class TypeComparer : IEqualityComparer<Type>
{
public bool Equals(Type __a, Type __b) {
return __a.Equals(__b);
}
public int GetHashCode(Type __type) {
return __type.GetHashCode();
}
}
internal static Dictionary<TimeEvent, SortedSet<Component>> _TimeBasedComponents = [];
/// <summary>
/// How Priority is sorted.
/// </summary>
internal readonly static Comparer<Component> _componentSorter = Comparer<Component>.Create((a, b) => {
int result = b.Priority.CompareTo(a.Priority);
return (result != 0) ? result : a.GetHashCode().CompareTo(b.GetHashCode());
});
internal static Dictionary<Type, byte> _TypeAssociatedTimeEvents = [];
}

View File

@@ -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.
/// </summary>
/// <remarks> It is recommended to load content during LoadContent()</remarks>
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(); }
/// <summary>
/// EndRun() is called if the program closes. Override Terminate() in scripting tools or use hooks to call from this event.
/// </summary>
/// <remarks> This event may not trigger if the program is force closed.</remarks>
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.
/// </summary>
/// <remarks> Hooks are unable to receive both Update() and Draw()</remarks>
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.
/// </summary>
/// <remarks> Hooks are unable to receive both Update() and Draw()</remarks>
protected override void OnRenderFrame(FrameEventArgs __args) { foreach (Component component in Awperative._TimeBasedComponents[Awperative.TimeEvent.Draw].ToList()) component.ChainEvent(Awperative.TimeEvent.Draw); base.OnRenderFrame(__args); }
/// <summary>
/// EndRun() is called if the program closes. Override Terminate() in scripting tools or use hooks to call from this event.
/// </summary>
/// <remarks> This event may not trigger if the program is force closed.</remarks>
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); }
}

View File

@@ -1,3 +1,6 @@
using System.Collections.Generic;
namespace AwperativeKernel;
public sealed partial class Scene : ComponentDocker

View File

@@ -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")]

View File

@@ -1 +1 @@
eaefd8ded26140e2f41a812ea39f0e84a94c9d2484a5baede0586b90e9c4efcb
22a4163440a667e1fc9f683e846ca5e0db424c2a4e8629dde601d67fa1038af8