From 846aa75dd583001cf77c80c24e1181d8f6114047 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 30 May 2025 12:58:08 +0300 Subject: [PATCH] perf: regular events to custom events --- .../Abstract/Assignable/IAssignable.cs | 2 +- .../Assignable/IHasBehaviourController.cs | 2 +- Engine.Core/Abstract/Assignable/IHasEntity.cs | 2 +- .../Abstract/Assignable/IHasStateEnable.cs | 2 +- .../Abstract/Assignable/IHasUniverse.cs | 2 +- .../Abstract/Assignable/IHasUniverseObject.cs | 2 +- Engine.Core/Abstract/IActive.cs | 2 +- Engine.Core/Abstract/IBehaviour.cs | 2 +- Engine.Core/Abstract/IBehaviourCollector.cs | 4 +- Engine.Core/Abstract/IBehaviourController.cs | 4 +- Engine.Core/Abstract/IEntity.cs | 2 +- Engine.Core/Abstract/IInitializable.cs | 4 +- Engine.Core/Abstract/INameable.cs | 2 +- Engine.Core/Abstract/IStateEnable.cs | 2 +- Engine.Core/Abstract/ITransform2D.cs | 6 +- Engine.Core/Abstract/IUniverse.cs | 18 ++-- Engine.Core/Abstract/IUniverseObject.cs | 10 +- Engine.Core/ActiveBehaviourCollector.cs | 49 ++++++---- Engine.Core/ActiveBehaviourCollectorSorted.cs | 3 - Engine.Core/BaseEntity.cs | 12 +-- Engine.Core/Behaviour.cs | 22 +++-- Engine.Core/BehaviourBase.cs | 30 ++++-- Engine.Core/BehaviourCollector.cs | 43 +++++---- Engine.Core/BehaviourCollectorSorted.cs | 3 - Engine.Core/BehaviourController.cs | 13 ++- Engine.Core/CoroutineManager.cs | 4 +- Engine.Core/Helpers/Event.cs | 94 +++++++++++++++++++ Engine.Core/Primitives/Shape2D.cs | 2 +- Engine.Core/StateEnable.cs | 6 +- Engine.Core/Systems/DrawManager.cs | 12 +-- Engine.Core/Systems/UpdateManager.cs | 14 +-- Engine.Core/Transform2D.cs | 30 +++--- Engine.Core/Universe.cs | 35 ++++--- Engine.Core/UniverseObject.cs | 24 ++--- Engine.Physics2D/Abstract/ICollider2D.cs | 6 +- Engine.Physics2D/Abstract/IPhysicsEngine2D.cs | 6 +- Engine.Physics2D/Collider2DBehaviourBase.cs | 28 +++--- Engine.Physics2D/PhysicsCoroutineManager.cs | 12 +-- Engine.Physics2D/PhysicsEngine2D.cs | 8 +- Engine.Physics2D/PhysicsEngine2DStandalone.cs | 11 ++- Engine.Systems/StateMachine/State.cs | 2 +- .../StateMachine/StateBehaviourBase.cs | 3 +- 42 files changed, 342 insertions(+), 198 deletions(-) create mode 100644 Engine.Core/Helpers/Event.cs diff --git a/Engine.Core/Abstract/Assignable/IAssignable.cs b/Engine.Core/Abstract/Assignable/IAssignable.cs index a571013..3d25cfa 100644 --- a/Engine.Core/Abstract/Assignable/IAssignable.cs +++ b/Engine.Core/Abstract/Assignable/IAssignable.cs @@ -8,7 +8,7 @@ public interface IAssignable /// /// Event triggered when the 's fields are unassigned and completely ready to recycle. /// - event UnassignEventHandler? OnUnassigned; + Event? OnUnassigned { get; } /// /// Unassign 's all fields and make it ready to recycle. diff --git a/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs b/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs index f58357d..6db3d39 100644 --- a/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs +++ b/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs @@ -8,7 +8,7 @@ public interface IHasBehaviourController : IAssignable /// /// Event triggered when the value has has been assigned a new value. /// - event BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned; + Event OnBehaviourControllerAssigned { get; } /// IBehaviourController BehaviourController { get; } diff --git a/Engine.Core/Abstract/Assignable/IHasEntity.cs b/Engine.Core/Abstract/Assignable/IHasEntity.cs index 13d211c..3368919 100644 --- a/Engine.Core/Abstract/Assignable/IHasEntity.cs +++ b/Engine.Core/Abstract/Assignable/IHasEntity.cs @@ -8,7 +8,7 @@ public interface IHasEntity : IAssignable /// /// Event triggered when the value has has been assigned a new value. /// - event EntityAssignedEventHandler? OnEntityAssigned; + Event OnEntityAssigned { get; } /// IEntity Entity { get; } diff --git a/Engine.Core/Abstract/Assignable/IHasStateEnable.cs b/Engine.Core/Abstract/Assignable/IHasStateEnable.cs index d7a96d0..a310b2c 100644 --- a/Engine.Core/Abstract/Assignable/IHasStateEnable.cs +++ b/Engine.Core/Abstract/Assignable/IHasStateEnable.cs @@ -8,7 +8,7 @@ public interface IHasStateEnable : IAssignable /// /// Event triggered when the value has has been assigned a new value. /// - event StateEnableAssignedEventHandler? OnStateEnableAssigned; + Event OnStateEnableAssigned { get; } /// IStateEnable StateEnable { get; } diff --git a/Engine.Core/Abstract/Assignable/IHasUniverse.cs b/Engine.Core/Abstract/Assignable/IHasUniverse.cs index 78f741b..e6681cd 100644 --- a/Engine.Core/Abstract/Assignable/IHasUniverse.cs +++ b/Engine.Core/Abstract/Assignable/IHasUniverse.cs @@ -8,7 +8,7 @@ public interface IHasUniverse : IAssignable /// /// Event triggered when the value has has been assigned a new value. /// - event UniverseAssignedEventHandler? OnUniverseAssigned; + Event OnUniverseAssigned { get; } /// IUniverse Universe { get; } diff --git a/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs b/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs index f02753c..2f6b48f 100644 --- a/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs +++ b/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs @@ -8,7 +8,7 @@ public interface IHasUniverseObject : IAssignable /// /// Event triggered when the value has has been assigned a new value. /// - event UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned; + Event OnUniverseObjectAssigned { get; } /// IUniverseObject UniverseObject { get; } diff --git a/Engine.Core/Abstract/IActive.cs b/Engine.Core/Abstract/IActive.cs index b8941d5..724c5fa 100644 --- a/Engine.Core/Abstract/IActive.cs +++ b/Engine.Core/Abstract/IActive.cs @@ -8,7 +8,7 @@ public interface IActive /// /// Event triggered when the state of the changes. /// - event ActiveChangedEventHandler? OnActiveChanged; + Event OnActiveChanged { get; } /// /// The value indicating whether the is enabled. diff --git a/Engine.Core/Abstract/IBehaviour.cs b/Engine.Core/Abstract/IBehaviour.cs index 695af6f..baeb531 100644 --- a/Engine.Core/Abstract/IBehaviour.cs +++ b/Engine.Core/Abstract/IBehaviour.cs @@ -8,7 +8,7 @@ public interface IBehaviour : IEntity, IActive, IHasBehaviourController, IHasSta /// /// Event triggered when the priority of the changes. /// - event PriorityChangedEventHandler? OnPriorityChanged; + Event OnPriorityChanged { get; } /// /// The priority of the . diff --git a/Engine.Core/Abstract/IBehaviourCollector.cs b/Engine.Core/Abstract/IBehaviourCollector.cs index fa016d4..c9fa4fc 100644 --- a/Engine.Core/Abstract/IBehaviourCollector.cs +++ b/Engine.Core/Abstract/IBehaviourCollector.cs @@ -10,12 +10,12 @@ public interface IBehaviourCollector : IHasUniverse where T : class /// /// Event triggered when an object of type is added to the collector. /// - event CollectedEventHandler? OnCollected; + Event, T> OnCollected { get; } /// /// Event triggered when an object of type is removed from the collector. /// - event RemovedEventHandler? OnRemoved; + Event, T> OnRemoved { get; } /// /// Amount of collected. diff --git a/Engine.Core/Abstract/IBehaviourController.cs b/Engine.Core/Abstract/IBehaviourController.cs index 5de1ea3..997751a 100644 --- a/Engine.Core/Abstract/IBehaviourController.cs +++ b/Engine.Core/Abstract/IBehaviourController.cs @@ -10,12 +10,12 @@ public interface IBehaviourController : IEntity, IHasUniverseObject /// /// Event triggered when a is added to the . /// - event BehaviourAddedEventHandler? OnBehaviourAdded; + Event OnBehaviourAdded { get; } /// /// Event triggered when a is removed from the . /// - event BehaviourRemovedEventHandler? OnBehaviourRemoved; + Event OnBehaviourRemoved { get; } /// /// Amount of collected. diff --git a/Engine.Core/Abstract/IEntity.cs b/Engine.Core/Abstract/IEntity.cs index 7a837c5..f33a635 100644 --- a/Engine.Core/Abstract/IEntity.cs +++ b/Engine.Core/Abstract/IEntity.cs @@ -9,7 +9,7 @@ public interface IEntity : IInitializable, IHasStateEnable /// Event triggered when the of the changes. /// The string action parameter is the previous of the . /// - event IdChangedEventHandler? OnIdChanged; + Event OnIdChanged { get; } /// /// The ID of the . diff --git a/Engine.Core/Abstract/IInitializable.cs b/Engine.Core/Abstract/IInitializable.cs index 7710354..881bda3 100644 --- a/Engine.Core/Abstract/IInitializable.cs +++ b/Engine.Core/Abstract/IInitializable.cs @@ -8,12 +8,12 @@ public interface IInitializable /// /// Event triggered when the method is called successfully. /// - event InitializedEventHandler? OnInitialized; + Event OnInitialized { get; } /// /// Event triggered when the method is called successfully. /// - event FinalizedEventHandler? OnFinalized; + Event OnFinalized { get; } /// /// The value indicating whether the entity has been initialized. diff --git a/Engine.Core/Abstract/INameable.cs b/Engine.Core/Abstract/INameable.cs index 3ac9f0c..015eee1 100644 --- a/Engine.Core/Abstract/INameable.cs +++ b/Engine.Core/Abstract/INameable.cs @@ -8,7 +8,7 @@ public interface INameable /// /// Event triggered when the name of the entity changes. /// - event NameChangedEventHandler? OnNameChanged; + Event OnNameChanged { get; } /// /// The name of the entity. diff --git a/Engine.Core/Abstract/IStateEnable.cs b/Engine.Core/Abstract/IStateEnable.cs index c39e404..29334ab 100644 --- a/Engine.Core/Abstract/IStateEnable.cs +++ b/Engine.Core/Abstract/IStateEnable.cs @@ -8,7 +8,7 @@ public interface IStateEnable : IHasEntity /// /// Event triggered when the state of the changes. /// - event EnabledChangedEventHandler? OnEnabledChanged; + Event OnEnabledChanged { get; } /// /// The value indicating whether the is enabled. diff --git a/Engine.Core/Abstract/ITransform2D.cs b/Engine.Core/Abstract/ITransform2D.cs index 45abbd0..c0ec888 100644 --- a/Engine.Core/Abstract/ITransform2D.cs +++ b/Engine.Core/Abstract/ITransform2D.cs @@ -8,17 +8,17 @@ public interface ITransform2D : IBehaviour /// /// Event triggered when the of the changes. /// - event PositionChangedEventHandler? OnPositionChanged; + Event OnPositionChanged { get; } /// /// Event triggered when the of the changes. /// - event ScaleChangedEventHandler? OnScaleChanged; + Event OnScaleChanged { get; } /// /// Event triggered when the of the changes. /// - event RotationChangedEventHandler? OnRotationChanged; + Event OnRotationChanged { get; } /// /// The world position of the in 2D space. diff --git a/Engine.Core/Abstract/IUniverse.cs b/Engine.Core/Abstract/IUniverse.cs index 8577aae..33c3162 100644 --- a/Engine.Core/Abstract/IUniverse.cs +++ b/Engine.Core/Abstract/IUniverse.cs @@ -10,47 +10,47 @@ public interface IUniverse : IEntity, IEnumerable /// /// Event triggered when is about to be called called on the . /// - event UpdateEventHandler? OnPreUpdate; + Event OnPreUpdate { get; } /// /// Event triggered when is called on the . /// - event UpdateEventHandler? OnUpdate; + Event OnUpdate { get; } /// /// Event triggered after is called on the . /// - event UpdateEventHandler? OnPostUpdate; + Event OnPostUpdate { get; } /// /// Event triggered when is about to be called called on the . /// - event DrawEventHandler? OnPreDraw; + Event OnPreDraw { get; } /// /// Event triggered when is called on the . /// - event DrawEventHandler? OnDraw; + Event OnDraw { get; } /// /// Event triggered after is called on the . /// - event DrawEventHandler? OnPostDraw; + Event OnPostDraw { get; } /// /// Event triggered when a is registered to the . /// - event UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered; + Event OnUniverseObjectRegistered { get; } /// /// Event triggered when a is unregistered from the . /// - event UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered; + Event OnUniverseObjectUnRegistered { get; } /// /// Event triggered when is changed on the . /// - event TimeScaleChangedEventHandler? OnTimeScaleChanged; + Event OnTimeScaleChanged { get; } /// /// Current time scale the operates on. diff --git a/Engine.Core/Abstract/IUniverseObject.cs b/Engine.Core/Abstract/IUniverseObject.cs index 09010a6..a90cabc 100644 --- a/Engine.Core/Abstract/IUniverseObject.cs +++ b/Engine.Core/Abstract/IUniverseObject.cs @@ -12,27 +12,27 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon /// /// Event triggered when the enters the universe. /// - event EnteredUniverseEventHandler? OnEnteredUniverse; + Event OnEnteredUniverse { get; } /// /// Event triggered when the exits the universe. /// - event ExitedUniverseEventHandler? OnExitedUniverse; + Event OnExitedUniverse { get; } /// /// Event triggered when the of the changes. The second parameter is the old . /// - event ParentChangedEventHandler? OnParentChanged; + Event OnParentChanged { get; } /// /// Event triggered when a new is added to the . /// - event ChildrenAddedEventHandler? OnChildrenAdded; + Event OnChildrenAdded { get; } /// /// Event triggered when an is removed from the . /// - event ChildrenRemovedEventHandler? OnChildrenRemoved; + Event OnChildrenRemoved { get; } /// /// Gets the this is connected to, if any. diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/ActiveBehaviourCollector.cs index 410feea..45370b5 100644 --- a/Engine.Core/ActiveBehaviourCollector.cs +++ b/Engine.Core/ActiveBehaviourCollector.cs @@ -1,15 +1,20 @@ -using System.Collections; +using System; using System.Collections.Generic; namespace Syntriax.Engine.Core; public class ActiveBehaviourCollector : IBehaviourCollector where T : class, IBehaviour { - public event IAssignable.UnassignEventHandler? OnUnassigned = null; - public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null; + public Event, T> OnCollected { get; private set; } = new(); + public Event, T> OnRemoved { get; private set; } = new(); + public Event OnUniverseAssigned { get; private set; } = new(); + public Event? OnUnassigned { get; private set; } = new(); - public event IBehaviourCollector.CollectedEventHandler? OnCollected = null; - public event IBehaviourCollector.RemovedEventHandler? OnRemoved = null; + private readonly Action cachedOnBehaviourAdded = null!; + private readonly Action cachedOnBehaviourRemoved = null!; + private readonly Action cachedOnBehaviourStateChanged = null!; + private readonly Action cachedOnUniverseObjectRegistered = null!; + private readonly Action cachedOnUniverseObjectUnregistered = null!; private readonly List monitoringBehaviours = new(32); protected readonly List activeBehaviours = new(32); @@ -17,13 +22,10 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas public IUniverse Universe { get; private set; } = null!; - public ActiveBehaviourCollector() { } - public ActiveBehaviourCollector(IUniverse universe) => Assign(universe); - private void OnUniverseObjectRegistered(IUniverse manager, IUniverseObject universeObject) { - universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; + universeObject.BehaviourController.OnBehaviourAdded.AddListener(cachedOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(cachedOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); @@ -31,8 +33,8 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) { - universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(cachedOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(cachedOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); @@ -46,7 +48,7 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas monitoringBehaviours.Add(tBehaviour); monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour); - tBehaviour.OnActiveChanged += OnBehaviourStateChanged; + tBehaviour.OnActiveChanged.AddListener(cachedOnBehaviourStateChanged); OnBehaviourStateChanged(tBehaviour, !tBehaviour.IsActive); } @@ -75,7 +77,7 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour)) return; - tBehaviour.OnActiveChanged -= OnBehaviourStateChanged; + tBehaviour.OnActiveChanged.RemoveListener(cachedOnBehaviourStateChanged); if (activeBehaviours.Remove(tBehaviour)) { OnBehaviourRemove(tBehaviour); @@ -91,8 +93,8 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas foreach (IUniverseObject universeObject in universe.UniverseObjects) OnUniverseObjectRegistered(universe, universeObject); - universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; - universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; + universe.OnUniverseObjectRegistered.AddListener(cachedOnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(cachedOnUniverseObjectUnregistered); Universe = universe; OnUniverseAssigned?.Invoke(this); @@ -108,8 +110,8 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas foreach (IUniverseObject universeObject in Universe.UniverseObjects) OnUniverseObjectUnregistered(Universe, universeObject); - Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; - Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; + Universe.OnUniverseObjectRegistered.RemoveListener(cachedOnUniverseObjectRegistered); + Universe.OnUniverseObjectUnRegistered.RemoveListener(cachedOnUniverseObjectUnregistered); Universe = null!; OnUnassigned?.Invoke(this); @@ -117,5 +119,14 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas } public int Count => activeBehaviours.Count; - public T this[System.Index index] => activeBehaviours[index]; + public T this[Index index] => activeBehaviours[index]; + + public ActiveBehaviourCollector() + { + cachedOnBehaviourAdded = OnBehaviourAdded; + cachedOnBehaviourRemoved = OnBehaviourRemoved; + cachedOnBehaviourStateChanged = OnBehaviourStateChanged; + cachedOnUniverseObjectRegistered = OnUniverseObjectRegistered; + cachedOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } } diff --git a/Engine.Core/ActiveBehaviourCollectorSorted.cs b/Engine.Core/ActiveBehaviourCollectorSorted.cs index e1622ff..64208cf 100644 --- a/Engine.Core/ActiveBehaviourCollectorSorted.cs +++ b/Engine.Core/ActiveBehaviourCollectorSorted.cs @@ -22,7 +22,4 @@ public class ActiveBehaviourCollectorSorted : ActiveBehaviourCollector whe if (SortBy is not null) activeBehaviours.Sort(SortBy); } - - public ActiveBehaviourCollectorSorted() { } - public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison sortBy) : base(universe) => SortBy = sortBy; } diff --git a/Engine.Core/BaseEntity.cs b/Engine.Core/BaseEntity.cs index fbd0769..0260046 100644 --- a/Engine.Core/BaseEntity.cs +++ b/Engine.Core/BaseEntity.cs @@ -4,13 +4,11 @@ namespace Syntriax.Engine.Core; public abstract class BaseEntity : IEntity { - public event IEntity.IdChangedEventHandler? OnIdChanged = null; - - public event IInitializable.InitializedEventHandler? OnInitialized = null; - public event IInitializable.FinalizedEventHandler? OnFinalized = null; - - public event IHasStateEnable.StateEnableAssignedEventHandler? OnStateEnableAssigned = null; - public event IAssignable.UnassignEventHandler? OnUnassigned = null; + public Event OnIdChanged { get; private set; } = new(); + public Event OnInitialized { get; private set; } = new(); + public Event OnFinalized { get; private set; } = new(); + public Event OnStateEnableAssigned { get; private set; } = new(); + public Event OnUnassigned { get; private set; } = new(); private IStateEnable _stateEnable = null!; diff --git a/Engine.Core/Behaviour.cs b/Engine.Core/Behaviour.cs index 4a9976f..85b1a5c 100644 --- a/Engine.Core/Behaviour.cs +++ b/Engine.Core/Behaviour.cs @@ -1,3 +1,5 @@ +using System; + namespace Syntriax.Engine.Core; public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, @@ -7,11 +9,17 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, protected IUniverse Universe => BehaviourController.UniverseObject.Universe; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject; + private readonly Action cachedEnteredUniverse = null!; + private readonly Action cachedExitedUniverse = null!; + public Behaviour() { - OnInitialized += OnInitialize; - OnFinalized += OnFinalize; - OnUnassigned += OnUnassign; + OnInitialized.AddListener(OnInitialize); + OnFinalized.AddListener(OnFinalize); + OnUnassigned.AddListener(OnUnassign); + + cachedEnteredUniverse = EnteredUniverse; + cachedExitedUniverse = ExitedUniverse; } protected virtual void OnUnassign() { } @@ -20,8 +28,8 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, protected virtual void OnInitialize() { } protected virtual void OnInitialize(IInitializable _) { - BehaviourController.UniverseObject.OnEnteredUniverse += EnteredUniverse; - BehaviourController.UniverseObject.OnExitedUniverse += ExitedUniverse; + BehaviourController.UniverseObject.OnEnteredUniverse.AddListener(cachedEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.AddListener(cachedExitedUniverse); OnInitialize(); @@ -32,8 +40,8 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, protected virtual void OnFinalize() { } protected virtual void OnFinalize(IInitializable _) { - BehaviourController.UniverseObject.OnEnteredUniverse -= EnteredUniverse; - BehaviourController.UniverseObject.OnExitedUniverse -= ExitedUniverse; + BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(cachedEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(cachedExitedUniverse); OnFinalize(); diff --git a/Engine.Core/BehaviourBase.cs b/Engine.Core/BehaviourBase.cs index 2aff939..085f23b 100644 --- a/Engine.Core/BehaviourBase.cs +++ b/Engine.Core/BehaviourBase.cs @@ -1,11 +1,17 @@ +using System; + namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] public abstract class BehaviourBase : BaseEntity, IBehaviour { - public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; - public event IBehaviour.PriorityChangedEventHandler? OnPriorityChanged = null; - public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; + public Event OnPriorityChanged { get; private set; } = new(); + public Event OnActiveChanged { get; private set; } = new(); + public Event OnBehaviourControllerAssigned { get; private set; } = new(); + + private Action cachedOnUniverseObjectAssigned = null!; + private Action cachedOnUniverseObjectActiveChanged = null!; + private Action cachedOnStateEnabledChanged = null!; private IBehaviourController _behaviourController = null!; public IBehaviourController BehaviourController => _behaviourController; @@ -36,7 +42,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour _behaviourController = behaviourController; OnAssign(behaviourController); - behaviourController.OnUniverseObjectAssigned += OnUniverseObjectAssigned; + behaviourController.OnUniverseObjectAssigned.AddListener(cachedOnUniverseObjectAssigned); if (behaviourController.UniverseObject is not null) OnUniverseObjectAssigned(behaviourController); OnBehaviourControllerAssigned?.Invoke(this); @@ -45,7 +51,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour private void OnUniverseObjectAssigned(IHasUniverseObject sender) { - sender.UniverseObject.OnActiveChanged += OnUniverseObjectActiveChanged; + sender.UniverseObject.OnActiveChanged.AddListener(cachedOnUniverseObjectActiveChanged); UpdateActive(); } @@ -53,13 +59,14 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour { base.OnAssign(stateEnable); - stateEnable.OnEnabledChanged += OnStateEnabledChanged; + stateEnable.OnEnabledChanged.AddListener(cachedOnStateEnabledChanged); } protected override void UnassignInternal() { - StateEnable.OnEnabledChanged -= OnStateEnabledChanged; - BehaviourController.OnUniverseObjectAssigned -= OnUniverseObjectAssigned; + BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(cachedOnUniverseObjectActiveChanged); + StateEnable.OnEnabledChanged.RemoveListener(cachedOnStateEnabledChanged); + BehaviourController.OnUniverseObjectAssigned.RemoveListener(cachedOnUniverseObjectAssigned); base.UnassignInternal(); _behaviourController = null!; } @@ -81,4 +88,11 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour if (previousActive != IsActive) OnActiveChanged?.Invoke(this, previousActive); } + + protected BehaviourBase() + { + cachedOnUniverseObjectAssigned = OnUniverseObjectAssigned; + cachedOnUniverseObjectActiveChanged = OnUniverseObjectActiveChanged; + cachedOnStateEnabledChanged = OnStateEnabledChanged; + } } diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 7869237..4e5e5cd 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -1,27 +1,28 @@ -using System.Collections; +using System; using System.Collections.Generic; namespace Syntriax.Engine.Core; public class BehaviourCollector : IBehaviourCollector where T : class { - public event IAssignable.UnassignEventHandler? OnUnassigned = null; - public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null; + public Event, T> OnCollected { get; private set; } = new(); + public Event, T> OnRemoved { get; private set; } = new(); + public Event OnUniverseAssigned { get; private set; } = new(); + public Event? OnUnassigned { get; private set; } = new(); - public event IBehaviourCollector.CollectedEventHandler? OnCollected = null; - public event IBehaviourCollector.RemovedEventHandler? OnRemoved = null; + private readonly Action cachedOnBehaviourAdded = null!; + private readonly Action cachedOnBehaviourRemoved = null!; + private readonly Action cachedOnUniverseObjectRegistered = null!; + private readonly Action cachedOnUniverseObjectUnregistered = null!; protected readonly List behaviours = new(32); public IUniverse Universe { get; private set; } = null!; - public BehaviourCollector() { } - public BehaviourCollector(IUniverse universe) => Assign(universe); - private void OnUniverseObjectRegistered(IUniverse manager, IUniverseObject universeObject) { - universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; + universeObject.BehaviourController.OnBehaviourAdded.AddListener(cachedOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(cachedOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); @@ -29,8 +30,8 @@ public class BehaviourCollector : IBehaviourCollector where T : class private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) { - universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(cachedOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(cachedOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); @@ -69,8 +70,8 @@ public class BehaviourCollector : IBehaviourCollector where T : class foreach (IUniverseObject universeObject in universe.UniverseObjects) OnUniverseObjectRegistered(universe, universeObject); - universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; - universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; + universe.OnUniverseObjectRegistered.AddListener(cachedOnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(cachedOnUniverseObjectUnregistered); Universe = universe; OnAssign(universe); @@ -87,8 +88,8 @@ public class BehaviourCollector : IBehaviourCollector where T : class foreach (IUniverseObject universeObject in Universe.UniverseObjects) OnUniverseObjectUnregistered(Universe, universeObject); - Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; - Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; + Universe.OnUniverseObjectRegistered.RemoveListener(cachedOnUniverseObjectRegistered); + Universe.OnUniverseObjectUnRegistered.RemoveListener(cachedOnUniverseObjectUnregistered); Universe = null!; OnUnassigned?.Invoke(this); @@ -96,5 +97,13 @@ public class BehaviourCollector : IBehaviourCollector where T : class } public int Count => behaviours.Count; - public T this[System.Index index] => behaviours[index]; + public T this[Index index] => behaviours[index]; + + public BehaviourCollector() + { + cachedOnBehaviourAdded = OnBehaviourAdded; + cachedOnBehaviourRemoved = OnBehaviourRemoved; + cachedOnUniverseObjectRegistered = OnUniverseObjectRegistered; + cachedOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } } diff --git a/Engine.Core/BehaviourCollectorSorted.cs b/Engine.Core/BehaviourCollectorSorted.cs index 6f93f76..1b1458e 100644 --- a/Engine.Core/BehaviourCollectorSorted.cs +++ b/Engine.Core/BehaviourCollectorSorted.cs @@ -22,7 +22,4 @@ public class BehaviourCollectorSorted : BehaviourCollector where T : class if (SortBy is not null) behaviours.Sort(SortBy); } - - public BehaviourCollectorSorted() { } - public BehaviourCollectorSorted(IUniverse universe, Comparison sortBy) : base(universe) => SortBy = sortBy; } diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index bbf1b8a..6829c9b 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -8,9 +8,9 @@ namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")] public class BehaviourController : BaseEntity, IBehaviourController { - public event IBehaviourController.BehaviourAddedEventHandler? OnBehaviourAdded = null; - public event IBehaviourController.BehaviourRemovedEventHandler? OnBehaviourRemoved = null; - public event IHasUniverseObject.UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned = null; + public Event OnBehaviourAdded { get; private set; } = new(); + public Event OnBehaviourRemoved { get; private set; } = new(); + public Event OnUniverseObjectAssigned { get; private set; } = new(); private readonly IList behaviours = new List(Constants.BEHAVIOURS_SIZE_INITIAL); @@ -20,6 +20,9 @@ public class BehaviourController : BaseEntity, IBehaviourController public int Count => behaviours.Count; public IBehaviour this[Index index] => behaviours[index]; + public int Count => behaviours.Count; + public IBehaviour this[Index index] => behaviours[index]; + public T AddBehaviour(T behaviour) where T : class, IBehaviour { InsertBehaviourByPriority(behaviour); @@ -28,7 +31,7 @@ public class BehaviourController : BaseEntity, IBehaviourController if (IsInitialized) behaviour.Initialize(); - behaviour.OnPriorityChanged += OnPriorityChange; + behaviour.OnPriorityChanged.AddListener(OnPriorityChange); OnBehaviourAdded?.Invoke(this, behaviour); return behaviour; } @@ -94,7 +97,7 @@ public class BehaviourController : BaseEntity, IBehaviourController if (!behaviours.Contains(behaviour)) throw new Exception($"{behaviour.GetType().Name} does not exist in {UniverseObject.Name}'s {nameof(IBehaviourController)}."); - behaviour.OnPriorityChanged -= OnPriorityChange; + behaviour.OnPriorityChanged.RemoveListener(OnPriorityChange); behaviour.Finalize(); behaviours.Remove(behaviour); OnBehaviourRemoved?.Invoke(this, behaviour); diff --git a/Engine.Core/CoroutineManager.cs b/Engine.Core/CoroutineManager.cs index 950891a..bbe49c7 100644 --- a/Engine.Core/CoroutineManager.cs +++ b/Engine.Core/CoroutineManager.cs @@ -20,12 +20,12 @@ public class CoroutineManager : UniverseObject protected override void OnEnteringUniverse(IUniverse universe) { - universe.OnUpdate += OnUpdate; + universe.OnUpdate.AddListener(OnUpdate); } protected override void OnExitingUniverse(IUniverse universe) { - universe.OnUpdate -= OnUpdate; + universe.OnUpdate.RemoveListener(OnUpdate); } private void OnUpdate(IUniverse sender, UniverseTime time) diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs new file mode 100644 index 0000000..766d604 --- /dev/null +++ b/Engine.Core/Helpers/Event.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; + +namespace Syntriax.Engine.Core; + +public class Event +{ + private readonly List listeners = new(1000); + + public void AddListener(Action listener) => listeners.Add(listener); + public void RemoveListener(Action listener) => listeners.Remove(listener); + public void Invoke() + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}()"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } +} + +public class Event +{ + private readonly List> listeners = new(1000); + + public void AddListener(Action listener) => listeners.Add(listener); + public void RemoveListener(Action listener) => listeners.Remove(listener); + public void Invoke(T1 argument) + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(argument); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({argument})"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } +} + +public class Event +{ + private readonly List> listeners = new(1000); + + public void AddListener(Action listener) => listeners.Add(listener); + public void RemoveListener(Action listener) => listeners.Remove(listener); + public void Invoke(T1 argument1, T2 argument2) + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(argument1, argument2); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2)})"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } +} + +public class Event +{ + private readonly List> listeners = new(1000); + + public void AddListener(Action listener) => listeners.Add(listener); + public void RemoveListener(Action listener) => listeners.Remove(listener); + public void Invoke(T1 argument1, T2 argument2, T3 argument3) + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(argument1, argument2, argument3); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2, argument3)})"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } +} + +public class Event +{ + private readonly List> listeners = new(1000); + + public void AddListener(Action listener) => listeners.Add(listener); + public void RemoveListener(Action listener) => listeners.Remove(listener); + public void Invoke(T1 argument1, T2 argument2, T3 argument3, T4 argument4) + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(argument1, argument2, argument3, argument4); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2, argument3, argument4)})"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } +} diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index 6030f8c..4449574 100644 --- a/Engine.Core/Primitives/Shape2D.cs +++ b/Engine.Core/Primitives/Shape2D.cs @@ -18,7 +18,7 @@ public class Shape2D(List vertices) : IEnumerable public static Shape2D Pentagon => CreateNgon(5, Vector2D.Up); public static Shape2D Hexagon => CreateNgon(6, Vector2D.Right); - public event ShapeUpdatedEventHandler? OnShapeUpdated = null; + public Event OnShapeUpdated { get; private set; } = new(); private List _vertices = vertices; diff --git a/Engine.Core/StateEnable.cs b/Engine.Core/StateEnable.cs index d3dd714..174880f 100644 --- a/Engine.Core/StateEnable.cs +++ b/Engine.Core/StateEnable.cs @@ -2,9 +2,9 @@ namespace Syntriax.Engine.Core; public class StateEnable : IStateEnable { - public event IAssignable.UnassignEventHandler? OnUnassigned = null; - public event IHasEntity.EntityAssignedEventHandler? OnEntityAssigned = null; - public event IStateEnable.EnabledChangedEventHandler? OnEnabledChanged = null; + public Event OnEnabledChanged { get; private set; } = new(); + public Event OnEntityAssigned { get; private set; } = new(); + public Event? OnUnassigned { get; private set; } = new(); private bool _enabled = true; private IEntity _entity = null!; diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index 2d05c91..a87b5f6 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -33,9 +33,9 @@ public class DrawManager : UniverseObject drawEntities.Assign(universe); postDrawEntities.Assign(universe); - universe.OnPreDraw += OnPreDraw; - universe.OnDraw += OnDraw; - universe.OnPostDraw += OnPostDraw; + universe.OnPreDraw.AddListener(OnPreDraw); + universe.OnDraw.AddListener(OnDraw); + universe.OnPostDraw.AddListener(OnPostDraw); } protected override void OnExitingUniverse(IUniverse universe) @@ -44,8 +44,8 @@ public class DrawManager : UniverseObject drawEntities.Unassign(); postDrawEntities.Unassign(); - universe.OnPreDraw -= OnPreDraw; - universe.OnDraw -= OnDraw; - universe.OnPostDraw -= OnPostDraw; + universe.OnPreDraw.RemoveListener(OnPreDraw); + universe.OnDraw.RemoveListener(OnDraw); + universe.OnPostDraw.RemoveListener(OnPostDraw); } } diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index 1380866..af65a8f 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -21,9 +21,9 @@ public class UpdateManager : UniverseObject updateEntities.Assign(universe); postUpdateEntities.Assign(universe); - universe.OnPreUpdate += OnPreUpdate; - universe.OnUpdate += OnUpdate; - universe.OnPostUpdate += OnPostUpdate; + universe.OnPreUpdate.AddListener(OnPreUpdate); + universe.OnUpdate.AddListener(OnUpdate); + universe.OnPostUpdate.AddListener(OnPostUpdate); } protected override void OnExitingUniverse(IUniverse universe) @@ -33,9 +33,9 @@ public class UpdateManager : UniverseObject updateEntities.Unassign(); postUpdateEntities.Unassign(); - universe.OnPreUpdate -= OnPreUpdate; - universe.OnUpdate -= OnUpdate; - universe.OnPostUpdate -= OnPostUpdate; + universe.OnPreUpdate.RemoveListener(OnPreUpdate); + universe.OnUpdate.RemoveListener(OnUpdate); + universe.OnPostUpdate.RemoveListener(OnPostUpdate); } private void OnPreUpdate(IUniverse sender, UniverseTime engineTime) @@ -69,6 +69,6 @@ public class UpdateManager : UniverseObject public UpdateManager() { - firstFrameUpdates.OnCollected += OnFirstFrameCollected; + firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected); } } diff --git a/Engine.Core/Transform2D.cs b/Engine.Core/Transform2D.cs index e51e21d..f67477c 100644 --- a/Engine.Core/Transform2D.cs +++ b/Engine.Core/Transform2D.cs @@ -5,9 +5,9 @@ namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("Name: {UniverseObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")] public class Transform2D : Behaviour, ITransform2D { - public event ITransform2D.PositionChangedEventHandler? OnPositionChanged = null; - public event ITransform2D.ScaleChangedEventHandler? OnScaleChanged = null; - public event ITransform2D.RotationChangedEventHandler? OnRotationChanged = null; + public Event OnPositionChanged { get; private set; } = new(); + public Event OnScaleChanged { get; private set; } = new(); + public Event OnRotationChanged { get; private set; } = new(); private Vector2D _position = Vector2D.Zero; private Vector2D _scale = Vector2D.One; @@ -207,12 +207,12 @@ public class Transform2D : Behaviour, ITransform2D protected override void InitializeInternal() { UpdateReferences(UniverseObject.Parent); - UniverseObject.OnParentChanged += OnParentChanged; + UniverseObject.OnParentChanged.AddListener(OnParentChanged); } protected override void FinalizeInternal() { - UniverseObject.OnParentChanged -= OnParentChanged; + UniverseObject.OnParentChanged.RemoveListener(OnParentChanged); } private void UpdateReferences(IUniverseObject? parent) @@ -220,28 +220,28 @@ public class Transform2D : Behaviour, ITransform2D ITransform2D? previousParent = parentTransform; if (previousParent is not null) { - previousParent.OnPositionChanged -= RecalculatePosition; - previousParent.OnScaleChanged -= RecalculateScale; - previousParent.OnRotationChanged -= RecalculateRotation; - previousParent.BehaviourController.UniverseObject.OnParentChanged -= OnParentChanged; - previousParent.BehaviourController.OnBehaviourAdded -= LookForTransform2D; + previousParent.OnPositionChanged.RemoveListener(RecalculatePosition); + previousParent.OnScaleChanged.RemoveListener(RecalculateScale); + previousParent.OnRotationChanged.RemoveListener(RecalculateRotation); + previousParent.BehaviourController.UniverseObject.OnParentChanged.RemoveListener(OnParentChanged); + previousParent.BehaviourController.OnBehaviourAdded.RemoveListener(LookForTransform2D); } parentTransform = parent?.BehaviourController.GetBehaviour(); if (parentTransform is not null) { - parentTransform.OnPositionChanged += RecalculatePosition; - parentTransform.OnScaleChanged += RecalculateScale; - parentTransform.OnRotationChanged += RecalculateRotation; - parentTransform.BehaviourController.UniverseObject.OnParentChanged += OnParentChanged; + parentTransform.OnPositionChanged.AddListener(RecalculatePosition); + parentTransform.OnScaleChanged.AddListener(RecalculateScale); + parentTransform.OnRotationChanged.AddListener(RecalculateRotation); + parentTransform.BehaviourController.UniverseObject.OnParentChanged.AddListener(OnParentChanged); UpdatePosition(); UpdateScale(); UpdateRotation(); } else if (UniverseObject.Parent is not null) - UniverseObject.Parent.BehaviourController.OnBehaviourAdded += LookForTransform2D; + UniverseObject.Parent.BehaviourController.OnBehaviourAdded.AddListener(LookForTransform2D); UpdateLocalPosition(); UpdateLocalScale(); diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index 62be549..c1e7fce 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -7,21 +7,28 @@ namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")] public class Universe : BaseEntity, IUniverse { - public event IUniverse.UpdateEventHandler? OnPreUpdate = null; - public event IUniverse.UpdateEventHandler? OnUpdate = null; - public event IUniverse.UpdateEventHandler? OnPostUpdate = null; - public event IUniverse.DrawEventHandler? OnPreDraw = null; - public event IUniverse.DrawEventHandler? OnDraw = null; - public event IUniverse.DrawEventHandler? OnPostDraw = null; + public Event OnPreUpdate { get; set; } = new(); + public Event OnUpdate { get; set; } = new(); + public Event OnPostUpdate { get; set; } = new(); + public Event OnPreDraw { get; set; } = new(); + public Event OnDraw { get; set; } = new(); + public Event OnPostDraw { get; set; } = new(); + public Event OnUniverseObjectRegistered { get; set; } = new(); + public Event OnUniverseObjectUnRegistered { get; set; } = new(); + public Event OnTimeScaleChanged { get; set; } = new(); - public event IUniverse.UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered = null; - public event IUniverse.UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered = null; - - public event IUniverse.TimeScaleChangedEventHandler? OnTimeScaleChanged = null; + private readonly Action cachedOnUniverseObjectFinalize = null!; + private readonly Action cachedOnUniverseObjectExitedUniverse = null!; private readonly List _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL); private float _timeScale = 1f; + public Universe() + { + cachedOnUniverseObjectFinalize = OnUniverseObjectFinalize; + cachedOnUniverseObjectExitedUniverse = OnUniverseObjectExitedUniverse; + } + public IReadOnlyList UniverseObjects => _universeObjects; public UniverseTime Time { get; private set; } = new(); @@ -46,8 +53,8 @@ public class Universe : BaseEntity, IUniverse if (_universeObjects.Contains(universeObject)) throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}."); - universeObject.OnFinalized += OnUniverseObjectFinalize; - universeObject.OnExitedUniverse += OnUniverseObjectExitedUniverse; + universeObject.OnFinalized.AddListener(cachedOnUniverseObjectFinalize); + universeObject.OnExitedUniverse.AddListener(cachedOnUniverseObjectExitedUniverse); if (!universeObject.Initialize()) throw new Exception($"{universeObject.Name} can't be initialized"); @@ -81,8 +88,8 @@ public class Universe : BaseEntity, IUniverse if (!_universeObjects.Contains(universeObject)) throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}."); - universeObject.OnFinalized -= OnUniverseObjectFinalize; - universeObject.OnExitedUniverse -= OnUniverseObjectExitedUniverse; + universeObject.OnFinalized.RemoveListener(cachedOnUniverseObjectFinalize); + universeObject.OnExitedUniverse.RemoveListener(cachedOnUniverseObjectExitedUniverse); for (int i = universeObject.Children.Count - 1; i >= 0; i--) Remove(universeObject.Children[i]); diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index 9a8adbd..7e19baa 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -6,14 +6,14 @@ namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")] public class UniverseObject : BaseEntity, IUniverseObject { - public event IUniverseObject.EnteredUniverseEventHandler? OnEnteredUniverse = null; - public event IUniverseObject.ExitedUniverseEventHandler? OnExitedUniverse = null; - public event IUniverseObject.ParentChangedEventHandler? OnParentChanged = null; - public event IUniverseObject.ChildrenAddedEventHandler? OnChildrenAdded = null; - public event IUniverseObject.ChildrenRemovedEventHandler? OnChildrenRemoved = null; - public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; - public event INameable.NameChangedEventHandler? OnNameChanged = null; - public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; + public Event OnEnteredUniverse { get; private set; } = new(); + public Event OnExitedUniverse { get; private set; } = new(); + public Event OnParentChanged { get; private set; } = new(); + public Event OnChildrenAdded { get; private set; } = new(); + public Event OnChildrenRemoved { get; private set; } = new(); + public Event OnActiveChanged { get; private set; } = new(); + public Event OnNameChanged { get; private set; } = new(); + public Event OnBehaviourControllerAssigned { get; private set; } = new(); private string _name = nameof(UniverseObject); private IUniverse _universe = null!; @@ -78,7 +78,7 @@ public class UniverseObject : BaseEntity, IUniverseObject if (previousParent is not null) { previousParent.RemoveChild(this); - previousParent.OnActiveChanged -= OnParentActiveChanged; + previousParent.OnActiveChanged.RemoveListener(OnParentActiveChanged); } Parent = parent; @@ -89,7 +89,7 @@ public class UniverseObject : BaseEntity, IUniverseObject parent.Universe.Register(this); parent.AddChild(this); - parent.OnActiveChanged += OnParentActiveChanged; + parent.OnActiveChanged.AddListener(OnParentActiveChanged); } UpdateActive(); @@ -131,7 +131,7 @@ public class UniverseObject : BaseEntity, IUniverseObject { base.OnAssign(stateEnable); - stateEnable.OnEnabledChanged += OnStateEnabledChanged; + stateEnable.OnEnabledChanged.AddListener(OnStateEnabledChanged); } private void OnParentActiveChanged(IActive sender, bool previousState) => UpdateActive(); @@ -149,7 +149,7 @@ public class UniverseObject : BaseEntity, IUniverseObject protected override void UnassignInternal() { base.UnassignInternal(); - StateEnable.OnEnabledChanged -= OnStateEnabledChanged; + StateEnable.OnEnabledChanged.RemoveListener(OnStateEnabledChanged); } protected override void InitializeInternal() diff --git a/Engine.Physics2D/Abstract/ICollider2D.cs b/Engine.Physics2D/Abstract/ICollider2D.cs index ee9c38a..7dd6307 100644 --- a/Engine.Physics2D/Abstract/ICollider2D.cs +++ b/Engine.Physics2D/Abstract/ICollider2D.cs @@ -10,17 +10,17 @@ public interface ICollider2D : IBehaviour /// /// Event triggered when a collision is detected. /// - event CollisionDetectedEventHandler? OnCollisionDetected; + Event OnCollisionDetected { get; } /// /// Event triggered when a collision is resolved. /// - event CollisionResolvedEventHandler? OnCollisionResolved; + Event OnCollisionResolved { get; } /// /// Event triggered when another triggers this . /// - event TriggeredEventHandler? OnTriggered; + Event OnTriggered { get; } /// ITransform2D Transform { get; } diff --git a/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs b/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs index c65f139..290f5bd 100644 --- a/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs +++ b/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs @@ -1,3 +1,5 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Physics2D; /// @@ -8,12 +10,12 @@ public interface IPhysicsEngine2D /// /// Event triggered when the has done a single physics iteration. /// - event PhysicsIterationEventHandler? OnPhysicsIteration; + Event OnPhysicsIteration { get; } /// /// Event triggered when the has done a full physics step/>. /// - event PhysicsStepEventHandler? OnPhysicsStep; + Event OnPhysicsStep { get; } /// /// The number of iterations the performs per step. diff --git a/Engine.Physics2D/Collider2DBehaviourBase.cs b/Engine.Physics2D/Collider2DBehaviourBase.cs index 66cfda2..8d04fcd 100644 --- a/Engine.Physics2D/Collider2DBehaviourBase.cs +++ b/Engine.Physics2D/Collider2DBehaviourBase.cs @@ -4,9 +4,9 @@ namespace Syntriax.Engine.Physics2D; public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D { - public event ICollider2D.CollisionDetectedEventHandler? OnCollisionDetected = null; - public event ICollider2D.CollisionResolvedEventHandler? OnCollisionResolved = null; - public event ICollider2D.TriggeredEventHandler? OnTriggered = null; + public Event OnCollisionDetected { get; private set; } = new(); + public Event OnCollisionResolved { get; private set; } = new(); + public Event OnTriggered { get; private set; } = new(); protected bool NeedsRecalculation { get; set; } = true; protected IRigidBody2D? _rigidBody2D = null; @@ -29,13 +29,13 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D { BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); - BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController; - BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController; + BehaviourController.OnBehaviourAdded.AddListener(OnBehaviourAddedToController); + BehaviourController.OnBehaviourRemoved.AddListener(OnBehaviourRemovedFromController); - Transform.OnPositionChanged += SetNeedsRecalculationFromPosition; - Transform.OnRotationChanged += SetNeedsRecalculationFromRotation; - Transform.OnScaleChanged += SetNeedsRecalculationFromScale; - UniverseObject.OnParentChanged += UpdateRigidBody2D; + Transform.OnPositionChanged.AddListener(SetNeedsRecalculationFromPosition); + Transform.OnRotationChanged.AddListener(SetNeedsRecalculationFromRotation); + Transform.OnScaleChanged.AddListener(SetNeedsRecalculationFromScale); + UniverseObject.OnParentChanged.AddListener(UpdateRigidBody2D); } private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent) @@ -61,12 +61,12 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D protected override void OnFinalize() { - BehaviourController.OnBehaviourAdded -= OnBehaviourAddedToController; - BehaviourController.OnBehaviourRemoved -= OnBehaviourRemovedFromController; - Transform.OnScaleChanged -= SetNeedsRecalculationFromScale; + BehaviourController.OnBehaviourAdded.RemoveListener(OnBehaviourAddedToController); + BehaviourController.OnBehaviourRemoved.RemoveListener(OnBehaviourRemovedFromController); + Transform.OnScaleChanged.RemoveListener(SetNeedsRecalculationFromScale); - Transform.OnPositionChanged -= SetNeedsRecalculationFromPosition; - Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation; + Transform.OnPositionChanged.RemoveListener(SetNeedsRecalculationFromPosition); + Transform.OnRotationChanged.RemoveListener(SetNeedsRecalculationFromRotation); } public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); diff --git a/Engine.Physics2D/PhysicsCoroutineManager.cs b/Engine.Physics2D/PhysicsCoroutineManager.cs index 9583933..20586ad 100644 --- a/Engine.Physics2D/PhysicsCoroutineManager.cs +++ b/Engine.Physics2D/PhysicsCoroutineManager.cs @@ -25,9 +25,9 @@ public class PhysicsCoroutineManager : UniverseObject { physicsEngine = universe.GetUniverseObject(); if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) - foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; + foundPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep); else - universe.OnUpdate += OnUpdate; + universe.OnUpdate.AddListener(OnUpdate); } private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime) @@ -45,8 +45,8 @@ public class PhysicsCoroutineManager : UniverseObject protected override void OnExitingUniverse(IUniverse universe) { if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine) - existingPhysicsEngine.OnPhysicsStep -= OnPhysicsStep; - universe.OnUpdate -= OnUpdate; + existingPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep); + universe.OnUpdate.RemoveListener(OnUpdate); } private void OnUpdate(IUniverse sender, UniverseTime engineTime) @@ -57,8 +57,8 @@ public class PhysicsCoroutineManager : UniverseObject physicsEngine = universe.GetUniverseObject(); if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) { - foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; - universe.OnUpdate -= OnUpdate; + foundPhysicsEngine.OnPhysicsStep.AddListener(OnPhysicsStep); + universe.OnUpdate.RemoveListener(OnUpdate); } } } diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index ae9a5e9..e8f074c 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -4,8 +4,8 @@ namespace Syntriax.Engine.Physics2D; public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D { - public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; - public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; + public Event OnPhysicsIteration { get; private set; } = new(); + public Event OnPhysicsStep { get; private set; } = new(); private float physicsTicker = 0f; private int _iterationPerStep = 1; @@ -178,7 +178,7 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D colliderCollector.Assign(universe); rigidBodyCollector.Assign(universe); - universe.OnPreUpdate += OnEnginePreUpdate; + universe.OnPreUpdate.AddListener(OnEnginePreUpdate); } protected override void OnExitingUniverse(IUniverse universe) @@ -189,7 +189,7 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D colliderCollector.Unassign(); rigidBodyCollector.Unassign(); - universe.OnPreUpdate -= OnEnginePreUpdate; + universe.OnPreUpdate.RemoveListener(OnEnginePreUpdate); } private void OnEnginePreUpdate(IUniverse sender, UniverseTime engineTime) diff --git a/Engine.Physics2D/PhysicsEngine2DStandalone.cs b/Engine.Physics2D/PhysicsEngine2DStandalone.cs index 375ed60..2e200f9 100644 --- a/Engine.Physics2D/PhysicsEngine2DStandalone.cs +++ b/Engine.Physics2D/PhysicsEngine2DStandalone.cs @@ -6,8 +6,8 @@ namespace Syntriax.Engine.Physics2D; public class PhysicsEngine2DStandalone : IPhysicsEngine2D { - public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; - public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; + public Event OnPhysicsIteration { get; private set; } = new(); + public Event OnPhysicsStep { get; private set; } = new(); private readonly List rigidBodies = new(32); private readonly List colliders = new(64); @@ -29,13 +29,16 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D foreach (ICollider2D collider2D in rigidBody.BehaviourController.GetBehaviours()) colliders.Add(collider2D); - rigidBody.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; - rigidBody.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; + rigidBody.BehaviourController.OnBehaviourAdded.AddListener(OnBehaviourAdded); + rigidBody.BehaviourController.OnBehaviourRemoved.AddListener(OnBehaviourRemoved); } public void RemoveRigidBody(IRigidBody2D rigidBody) { rigidBodies.Remove(rigidBody); + + rigidBody.BehaviourController.OnBehaviourAdded.RemoveListener(OnBehaviourAdded); + rigidBody.BehaviourController.OnBehaviourRemoved.RemoveListener(OnBehaviourRemoved); } public void Step(float deltaTime) diff --git a/Engine.Systems/StateMachine/State.cs b/Engine.Systems/StateMachine/State.cs index 656e269..87874dc 100644 --- a/Engine.Systems/StateMachine/State.cs +++ b/Engine.Systems/StateMachine/State.cs @@ -10,7 +10,7 @@ public class State : BaseEntity, IState public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null; public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null; public event IState.StateTransitionReadyEventHandler? OnStateTransitionReady = null; - public event INameable.NameChangedEventHandler? OnNameChanged = null; + public Event OnNameChanged { get; private set; } = new(); private readonly List transitions = []; private readonly Dictionary possibleTransitions = []; diff --git a/Engine.Systems/StateMachine/StateBehaviourBase.cs b/Engine.Systems/StateMachine/StateBehaviourBase.cs index 2b93388..4518839 100644 --- a/Engine.Systems/StateMachine/StateBehaviourBase.cs +++ b/Engine.Systems/StateMachine/StateBehaviourBase.cs @@ -7,7 +7,8 @@ public abstract class StateBehaviourBase : Behaviour, IState public event IState.StateUpdateEventHandler? OnStateUpdate = null; public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null; public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null; - public event INameable.NameChangedEventHandler? OnNameChanged = null; + + public Event OnNameChanged { get; private set; } = new(); public abstract event IState.StateTransitionReadyEventHandler? OnStateTransitionReady;