diff --git a/Engine.Core/Abstract/Assignable/IAssignable.cs b/Engine.Core/Abstract/Assignable/IAssignable.cs index a571013..b4cac2a 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. @@ -17,6 +17,4 @@ public interface IAssignable /// , if the fields are unsigned successfully, if not. /// bool Unassign(); - - delegate void UnassignEventHandler(IAssignable sender); } diff --git a/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs b/Engine.Core/Abstract/Assignable/IHasBehaviourController.cs index f58357d..6feff7e 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; } @@ -21,6 +21,4 @@ public interface IHasBehaviourController : IAssignable /// , if the value given assigned successfully assigned, if not. /// bool Assign(IBehaviourController behaviourController); - - delegate void BehaviourControllerAssignedEventHandler(IHasBehaviourController sender); } diff --git a/Engine.Core/Abstract/Assignable/IHasEntity.cs b/Engine.Core/Abstract/Assignable/IHasEntity.cs index 13d211c..205ffe5 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; } @@ -21,6 +21,4 @@ public interface IHasEntity : IAssignable /// , if the value given assigned successfully assigned, if not. /// bool Assign(IEntity entity); - - delegate void EntityAssignedEventHandler(IHasEntity sender); } diff --git a/Engine.Core/Abstract/Assignable/IHasStateEnable.cs b/Engine.Core/Abstract/Assignable/IHasStateEnable.cs index d7a96d0..0a5c766 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; } @@ -21,6 +21,4 @@ public interface IHasStateEnable : IAssignable /// , if the value given assigned successfully assigned, if not. /// bool Assign(IStateEnable stateEnable); - - delegate void StateEnableAssignedEventHandler(IHasStateEnable sender); } diff --git a/Engine.Core/Abstract/Assignable/IHasUniverse.cs b/Engine.Core/Abstract/Assignable/IHasUniverse.cs index 78f741b..bcf13f2 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; } @@ -21,6 +21,4 @@ public interface IHasUniverse : IAssignable /// , if the value given assigned successfully assigned, if not. /// bool Assign(IUniverse universe); - - delegate void UniverseAssignedEventHandler(IHasUniverse sender); } diff --git a/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs b/Engine.Core/Abstract/Assignable/IHasUniverseObject.cs index f02753c..ad1081a 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; } @@ -21,6 +21,4 @@ public interface IHasUniverseObject : IAssignable /// , if the value given assigned successfully assigned, if not. /// bool Assign(IUniverseObject universeObject); - - delegate void UniverseObjectAssignedEventHandler(IHasUniverseObject sender); } diff --git a/Engine.Core/Abstract/IActive.cs b/Engine.Core/Abstract/IActive.cs index b8941d5..7fbfd6c 100644 --- a/Engine.Core/Abstract/IActive.cs +++ b/Engine.Core/Abstract/IActive.cs @@ -8,12 +8,12 @@ public interface IActive /// /// Event triggered when the state of the changes. /// - event ActiveChangedEventHandler? OnActiveChanged; + Event OnActiveChanged { get; } /// /// The value indicating whether the is enabled. /// bool IsActive { get; } - delegate void ActiveChangedEventHandler(IActive sender, bool previousState); + readonly record struct ActiveChangedArguments(bool PreviousState); } diff --git a/Engine.Core/Abstract/IBehaviour.cs b/Engine.Core/Abstract/IBehaviour.cs index 695af6f..25ec8cd 100644 --- a/Engine.Core/Abstract/IBehaviour.cs +++ b/Engine.Core/Abstract/IBehaviour.cs @@ -8,12 +8,12 @@ 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 . /// int Priority { get; set; } - delegate void PriorityChangedEventHandler(IBehaviour sender, int previousPriority); + readonly record struct PriorityChangedArguments(int PreviousPriority); } diff --git a/Engine.Core/Abstract/IBehaviourCollector.cs b/Engine.Core/Abstract/IBehaviourCollector.cs index fa016d4..ad9ed56 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, BehaviourCollectedArguments> OnCollected { get; } /// /// Event triggered when an object of type is removed from the collector. /// - event RemovedEventHandler? OnRemoved; + Event, BehaviourRemovedArguments> OnRemoved { get; } /// /// Amount of collected. @@ -32,12 +32,11 @@ public interface IBehaviourCollector : IHasUniverse where T : class /// /// The instance of the that triggered the event. /// The object of type that was added to the collector. - delegate void CollectedEventHandler(IBehaviourCollector sender, T behaviourCollected); + readonly record struct BehaviourCollectedArguments(T BehaviourCollected); /// /// Delegate for handling the event. /// - /// The instance of the that triggered the event. - /// The object of type that was removed from the collector. - delegate void RemovedEventHandler(IBehaviourCollector sender, T behaviourRemoved); + /// The object of type that was removed from the collector. + readonly record struct BehaviourRemovedArguments(T BehaviourRemoved); } diff --git a/Engine.Core/Abstract/IBehaviourController.cs b/Engine.Core/Abstract/IBehaviourController.cs index 5de1ea3..590e2e8 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. @@ -78,6 +78,6 @@ public interface IBehaviourController : IEntity, IHasUniverseObject /// The to remove. void RemoveBehaviour(T behaviour) where T : class, IBehaviour; - delegate void BehaviourAddedEventHandler(IBehaviourController sender, IBehaviour behaviourAdded); - delegate void BehaviourRemovedEventHandler(IBehaviourController sender, IBehaviour behaviourRemoved); + readonly record struct BehaviourAddedArguments(IBehaviour BehaviourAdded); + readonly record struct BehaviourRemovedArguments(IBehaviour BehaviourRemoved); } diff --git a/Engine.Core/Abstract/IEntity.cs b/Engine.Core/Abstract/IEntity.cs index 7a837c5..3eeefdd 100644 --- a/Engine.Core/Abstract/IEntity.cs +++ b/Engine.Core/Abstract/IEntity.cs @@ -9,12 +9,12 @@ 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 . /// string Id { get; set; } - delegate void IdChangedEventHandler(IEntity sender, string previousId); + readonly record struct IdChangedArguments(string PreviousId); } diff --git a/Engine.Core/Abstract/IInitializable.cs b/Engine.Core/Abstract/IInitializable.cs index 7710354..64230d3 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. @@ -31,7 +31,4 @@ public interface IInitializable /// /// if finalization is successful, otherwise . bool Finalize(); - - delegate void InitializedEventHandler(IInitializable sender); - delegate void FinalizedEventHandler(IInitializable sender); } diff --git a/Engine.Core/Abstract/INameable.cs b/Engine.Core/Abstract/INameable.cs index 3ac9f0c..93442be 100644 --- a/Engine.Core/Abstract/INameable.cs +++ b/Engine.Core/Abstract/INameable.cs @@ -8,12 +8,12 @@ public interface INameable /// /// Event triggered when the name of the entity changes. /// - event NameChangedEventHandler? OnNameChanged; + Event OnNameChanged { get; } /// /// The name of the entity. /// string Name { get; set; } - delegate void NameChangedEventHandler(INameable sender, string previousName); + readonly record struct NameChangedArguments(string PreviousName); } diff --git a/Engine.Core/Abstract/IStateEnable.cs b/Engine.Core/Abstract/IStateEnable.cs index c39e404..4c61668 100644 --- a/Engine.Core/Abstract/IStateEnable.cs +++ b/Engine.Core/Abstract/IStateEnable.cs @@ -8,12 +8,12 @@ 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. /// bool Enabled { get; set; } - delegate void EnabledChangedEventHandler(IStateEnable sender, bool previousState); + readonly record struct EnabledChangedArguments(bool PreviousState); } diff --git a/Engine.Core/Abstract/ITransform2D.cs b/Engine.Core/Abstract/ITransform2D.cs index 45abbd0..b0175fa 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. @@ -51,23 +51,20 @@ public interface ITransform2D : IBehaviour float LocalRotation { get; set; } /// - /// Delegate for the event triggered when the 's rotation changes. + /// Arguments for the event triggered when the 's rotation changes. /// - /// The that the parent has changed. - /// The previous of the . - delegate void PositionChangedEventHandler(ITransform2D sender, Vector2D previousPosition); + /// The previous of the . + readonly record struct PositionChangedArguments(Vector2D PreviousPosition); /// - /// Delegate for the event triggered when the 's rotation changes. + /// Arguments for the event triggered when the 's rotation changes. /// - /// The that the parent has changed. - /// The previous of the . - delegate void ScaleChangedEventHandler(ITransform2D sender, Vector2D previousScale); + /// The previous of the . + readonly record struct ScaleChangedArguments(Vector2D PreviousScale); /// - /// Delegate for the event triggered when the 's rotation changes. + /// Arguments for the event triggered when the 's rotation changes. /// - /// The that the parent has changed. - /// The previous of the . - delegate void RotationChangedEventHandler(ITransform2D sender, float previousRotation); + /// The previous of the . + readonly record struct RotationChangedArguments(float PreviousRotation); } diff --git a/Engine.Core/Abstract/IUniverse.cs b/Engine.Core/Abstract/IUniverse.cs index 8577aae..116967b 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. @@ -103,11 +103,8 @@ public interface IUniverse : IEntity, IEnumerable /// void Draw(); - delegate void TimeScaleChangedEventHandler(IUniverse sender, float previousTimeScale); - - delegate void UpdateEventHandler(IUniverse sender, UniverseTime engineTime); - delegate void DrawEventHandler(IUniverse sender); - - delegate void UniverseObjectRegisteredEventHandler(IUniverse sender, IUniverseObject universeObjectRegistered); - delegate void UniverseObjectUnRegisteredEventHandler(IUniverse sender, IUniverseObject universeObjectUnregistered); + readonly record struct TimeScaleChangedArguments(float PreviousTimeScale); + readonly record struct UpdateArguments(UniverseTime EngineTime); + readonly record struct UniverseObjectRegisteredArguments(IUniverseObject UniverseObjectRegistered); + readonly record struct UniverseObjectUnRegisteredArguments(IUniverseObject UniverseObjectUnregistered); } diff --git a/Engine.Core/Abstract/IUniverseObject.cs b/Engine.Core/Abstract/IUniverseObject.cs index 09010a6..7f03950 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. @@ -94,38 +94,38 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon void RemoveChild(IUniverseObject universeObject); /// - /// EventHandler delegate for the event triggered when the enters the universe of a . + /// Arguments for the event triggered when the enters the universe of a . /// /// The that entered the universe. /// The that the has entered it's universe. - delegate void EnteredUniverseEventHandler(IUniverseObject sender, IUniverse universe); + readonly record struct EnteredUniverseArguments(IUniverse Universe); /// - /// EventHandler delegate for the event triggered when the exits the universe of a . + /// Arguments for the event triggered when the exits the universe of a . /// /// The that exited the universe. /// The that the has exited it's universe. - delegate void ExitedUniverseEventHandler(IUniverseObject sender, IUniverse universe); + readonly record struct ExitedUniverseArguments(IUniverse Universe); /// - /// Delegate for the event triggered when the 's parent changes. + /// Arguments for the event triggered when the 's parent changes. /// /// The that the parent has changed. /// The previous the sender was a child of. /// The new and current the sender is a child of. - delegate void ParentChangedEventHandler(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent); + readonly record struct ParentChangedArguments(IUniverseObject? PreviousParent, IUniverseObject? CurrentParent); /// - /// Delegate for the event triggered when a new added as a child. + /// Arguments for the event triggered when a new added as a child. /// /// The parent this event is being called from. /// The that got removed as a children of the sender . - delegate void ChildrenAddedEventHandler(IUniverseObject sender, IUniverseObject childrenAdded); + readonly record struct ChildrenAddedArguments(IUniverseObject ChildrenAdded); /// /// Delegate for the event triggered when a new removed from being a child. /// /// The parent this event is being called from. /// The that got removed as a children of the sender . - delegate void ChildrenRemovedEventHandler(IUniverseObject sender, IUniverseObject childrenRemoved); + readonly record struct ChildrenRemovedArguments(IUniverseObject ChildrenRemoved); } diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/ActiveBehaviourCollector.cs index 410feea..533ff47 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, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); + public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); + public Event OnUniverseAssigned { get; } = new(); + public Event? OnUnassigned { get; } = new(); - public event IBehaviourCollector.CollectedEventHandler? OnCollected = null; - public event IBehaviourCollector.RemovedEventHandler? OnRemoved = null; + private readonly Event.EventHandler delegateOnBehaviourAdded = null!; + private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; + private readonly Event.EventHandler delegateOnBehaviourStateChanged = null!; + private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; + private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; private readonly List monitoringBehaviours = new(32); protected readonly List activeBehaviours = new(32); @@ -17,69 +22,70 @@ 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) + private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) { - universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; + IUniverseObject universeObject = args.UniverseObjectRegistered; + + universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); + OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); } - private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) + private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) { - universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; + IUniverseObject universeObject = args.UniverseObjectUnregistered; + + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); + OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); } protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } - private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) { - if (behaviour is not T tBehaviour) + if (args.BehaviourAdded is not T tBehaviour) return; monitoringBehaviours.Add(tBehaviour); monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour); - tBehaviour.OnActiveChanged += OnBehaviourStateChanged; - OnBehaviourStateChanged(tBehaviour, !tBehaviour.IsActive); + tBehaviour.OnActiveChanged.AddListener(delegateOnBehaviourStateChanged); + OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive)); } - private void OnBehaviourStateChanged(IActive sender, bool previousState) + private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args) { T behaviour = monitoringActiveToBehaviour[sender]; if (sender.IsActive) { activeBehaviours.Add(behaviour); OnBehaviourAdd(behaviour); - OnCollected?.Invoke(this, behaviour); + OnCollected?.Invoke(this, new(behaviour)); } else if (activeBehaviours.Remove(behaviour)) { OnBehaviourRemove(behaviour); - OnRemoved?.Invoke(this, behaviour); + OnRemoved?.Invoke(this, new(behaviour)); } } protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } - private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) { - if (behaviour is not T tBehaviour) + if (args.BehaviourRemoved is not T tBehaviour) return; if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour)) return; - tBehaviour.OnActiveChanged -= OnBehaviourStateChanged; + tBehaviour.OnActiveChanged.RemoveListener(delegateOnBehaviourStateChanged); if (activeBehaviours.Remove(tBehaviour)) { OnBehaviourRemove(tBehaviour); - OnRemoved?.Invoke(this, tBehaviour); + OnRemoved?.Invoke(this, new(tBehaviour)); } } @@ -89,10 +95,10 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas return false; foreach (IUniverseObject universeObject in universe.UniverseObjects) - OnUniverseObjectRegistered(universe, universeObject); + OnUniverseObjectRegistered(universe, new(universeObject)); - universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; - universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; + universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); Universe = universe; OnUniverseAssigned?.Invoke(this); @@ -106,10 +112,10 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas return false; foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectUnregistered(Universe, universeObject); + OnUniverseObjectUnregistered(Universe, new(universeObject)); - Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; - Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; + Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); + Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); Universe = null!; OnUnassigned?.Invoke(this); @@ -117,5 +123,25 @@ 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() + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnBehaviourStateChanged = OnBehaviourStateChanged; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } + + public ActiveBehaviourCollector(IUniverse universe) + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnBehaviourStateChanged = OnBehaviourStateChanged; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + + Assign(universe); + } } diff --git a/Engine.Core/BaseEntity.cs b/Engine.Core/BaseEntity.cs index fbd0769..e98e387 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; } = new(); + public Event OnInitialized { get; } = new(); + public Event OnFinalized { get; } = new(); + public Event OnStateEnableAssigned { get; } = new(); + public Event OnUnassigned { get; } = new(); private IStateEnable _stateEnable = null!; @@ -33,7 +31,7 @@ public abstract class BaseEntity : IEntity string previousId = _id; _id = value; - OnIdChanged?.Invoke(this, previousId); + OnIdChanged?.Invoke(this, new(previousId)); } } diff --git a/Engine.Core/Behaviour.cs b/Engine.Core/Behaviour.cs index 4a9976f..a7d899e 100644 --- a/Engine.Core/Behaviour.cs +++ b/Engine.Core/Behaviour.cs @@ -7,11 +7,17 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, protected IUniverse Universe => BehaviourController.UniverseObject.Universe; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject; + private readonly Event.EventHandler delegateEnteredUniverse = null!; + private readonly Event.EventHandler delegateExitedUniverse = null!; + public Behaviour() { - OnInitialized += OnInitialize; - OnFinalized += OnFinalize; - OnUnassigned += OnUnassign; + OnInitialized.AddListener(OnInitialize); + OnFinalized.AddListener(OnFinalize); + OnUnassigned.AddListener(OnUnassign); + + delegateEnteredUniverse = EnteredUniverse; + delegateExitedUniverse = ExitedUniverse; } protected virtual void OnUnassign() { } @@ -20,25 +26,25 @@ 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(delegateEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.AddListener(delegateExitedUniverse); OnInitialize(); if (UniverseObject.IsInUniverse) - EnteredUniverse(UniverseObject, Universe); + EnteredUniverse(UniverseObject, new(Universe)); } protected virtual void OnFinalize() { } protected virtual void OnFinalize(IInitializable _) { - BehaviourController.UniverseObject.OnEnteredUniverse -= EnteredUniverse; - BehaviourController.UniverseObject.OnExitedUniverse -= ExitedUniverse; + BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(delegateEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(delegateExitedUniverse); OnFinalize(); if (UniverseObject.IsInUniverse) - ExitedUniverse(UniverseObject, Universe); + ExitedUniverse(UniverseObject, new(Universe)); } protected virtual void OnFirstActiveFrame() { } @@ -133,8 +139,8 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, } protected virtual void OnEnteredUniverse(IUniverse universe) { } - protected virtual void EnteredUniverse(IUniverseObject sender, IUniverse universe) => OnEnteredUniverse(universe); + protected virtual void EnteredUniverse(IUniverseObject sender, IUniverseObject.EnteredUniverseArguments args) => OnEnteredUniverse(args.Universe); protected virtual void OnExitedUniverse(IUniverse universe) { } - protected virtual void ExitedUniverse(IUniverseObject sender, IUniverse universe) => OnExitedUniverse(universe); + protected virtual void ExitedUniverse(IUniverseObject sender, IUniverseObject.ExitedUniverseArguments args) => OnExitedUniverse(args.Universe); } diff --git a/Engine.Core/Behaviour2D.cs b/Engine.Core/Behaviour2D.cs index f7be439..6cfbcc0 100644 --- a/Engine.Core/Behaviour2D.cs +++ b/Engine.Core/Behaviour2D.cs @@ -17,6 +17,6 @@ public abstract class Behaviour2D : Behaviour, IBehaviour2D } protected sealed override void OnUnassign(IAssignable assignable) => base.OnUnassign(assignable); - protected sealed override void EnteredUniverse(IUniverseObject sender, IUniverse universe) => base.EnteredUniverse(sender, universe); - protected sealed override void ExitedUniverse(IUniverseObject sender, IUniverse universe) => base.ExitedUniverse(sender, universe); + protected sealed override void EnteredUniverse(IUniverseObject sender, IUniverseObject.EnteredUniverseArguments args) => base.EnteredUniverse(sender, args); + protected sealed override void ExitedUniverse(IUniverseObject sender, IUniverseObject.ExitedUniverseArguments args) => base.ExitedUniverse(sender, args); } diff --git a/Engine.Core/BehaviourBase.cs b/Engine.Core/BehaviourBase.cs index 2aff939..5846d13 100644 --- a/Engine.Core/BehaviourBase.cs +++ b/Engine.Core/BehaviourBase.cs @@ -3,9 +3,13 @@ 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; } = new(); + public Event OnActiveChanged { get; } = new(); + public Event OnBehaviourControllerAssigned { get; } = new(); + + private readonly Event.EventHandler delegateOnUniverseObjectAssigned = null!; + private readonly Event.EventHandler delegateOnUniverseObjectActiveChanged = null!; + private readonly Event.EventHandler delegateOnStateEnabledChanged = null!; private IBehaviourController _behaviourController = null!; public IBehaviourController BehaviourController => _behaviourController; @@ -21,7 +25,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour int previousPriority = _priority; _priority = value; - OnPriorityChanged?.Invoke(this, previousPriority); + OnPriorityChanged?.Invoke(this, new(previousPriority)); } } @@ -36,7 +40,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour _behaviourController = behaviourController; OnAssign(behaviourController); - behaviourController.OnUniverseObjectAssigned += OnUniverseObjectAssigned; + behaviourController.OnUniverseObjectAssigned.AddListener(delegateOnUniverseObjectAssigned); if (behaviourController.UniverseObject is not null) OnUniverseObjectAssigned(behaviourController); OnBehaviourControllerAssigned?.Invoke(this); @@ -45,7 +49,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour private void OnUniverseObjectAssigned(IHasUniverseObject sender) { - sender.UniverseObject.OnActiveChanged += OnUniverseObjectActiveChanged; + sender.UniverseObject.OnActiveChanged.AddListener(delegateOnUniverseObjectActiveChanged); UpdateActive(); } @@ -53,13 +57,14 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour { base.OnAssign(stateEnable); - stateEnable.OnEnabledChanged += OnStateEnabledChanged; + stateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); } protected override void UnassignInternal() { - StateEnable.OnEnabledChanged -= OnStateEnabledChanged; - BehaviourController.OnUniverseObjectAssigned -= OnUniverseObjectAssigned; + BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged); + StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); + BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned); base.UnassignInternal(); _behaviourController = null!; } @@ -70,8 +75,8 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour Debug.Assert.AssertStateEnableAssigned(this); } - private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive(); - private void OnUniverseObjectActiveChanged(IActive sender, bool previousState) => UpdateActive(); + private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); + private void OnUniverseObjectActiveChanged(IActive sender, IActive.ActiveChangedArguments args) => UpdateActive(); private void UpdateActive() { @@ -79,6 +84,13 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour _isActive = StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; if (previousActive != IsActive) - OnActiveChanged?.Invoke(this, previousActive); + OnActiveChanged?.Invoke(this, new(previousActive)); + } + + protected BehaviourBase() + { + delegateOnUniverseObjectAssigned = OnUniverseObjectAssigned; + delegateOnUniverseObjectActiveChanged = OnUniverseObjectActiveChanged; + delegateOnStateEnabledChanged = OnStateEnabledChanged; } } diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 7869237..ae04f3a 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -1,63 +1,68 @@ -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, IBehaviourCollector.BehaviourCollectedArguments> OnCollected { get; } = new(); + public Event, IBehaviourCollector.BehaviourRemovedArguments> OnRemoved { get; } = new(); + public Event OnUniverseAssigned { get; } = new(); + public Event? OnUnassigned { get; } = new(); - public event IBehaviourCollector.CollectedEventHandler? OnCollected = null; - public event IBehaviourCollector.RemovedEventHandler? OnRemoved = null; + private readonly Event.EventHandler delegateOnBehaviourAdded = null!; + private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; + private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; + private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = 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) + private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args) { - universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; + IUniverseObject universeObject = args.UniverseObjectRegistered; + + universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); + OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); } - private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) + private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args) { - universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; - universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; + IUniverseObject universeObject = args.UniverseObjectUnregistered; + + universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); + universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); for (int i = 0; i < universeObject.BehaviourController.Count; i++) - OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); + OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); } protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } - private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) { - if (behaviour is not T tBehaviour) + if (args.BehaviourAdded is not T tBehaviour) return; behaviours.Add(tBehaviour); - OnBehaviourAdd(behaviour); - OnCollected?.Invoke(this, tBehaviour); + OnBehaviourAdd(args.BehaviourAdded); + OnCollected?.Invoke(this, new(tBehaviour)); } protected virtual void OnBehaviourRemove(IBehaviour behaviour) { } - private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args) { - if (behaviour is not T tBehaviour) + if (args.BehaviourRemoved is not T tBehaviour) return; if (!behaviours.Remove(tBehaviour)) return; - OnBehaviourRemove(behaviour); - OnRemoved?.Invoke(this, tBehaviour); + OnBehaviourRemove(args.BehaviourRemoved); + OnRemoved?.Invoke(this, new(tBehaviour)); } protected virtual void OnAssign(IUniverse universe) { } @@ -67,10 +72,10 @@ public class BehaviourCollector : IBehaviourCollector where T : class return false; foreach (IUniverseObject universeObject in universe.UniverseObjects) - OnUniverseObjectRegistered(universe, universeObject); + OnUniverseObjectRegistered(universe, new(universeObject)); - universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; - universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; + universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered); + universe.OnUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered); Universe = universe; OnAssign(universe); @@ -85,10 +90,10 @@ public class BehaviourCollector : IBehaviourCollector where T : class return false; foreach (IUniverseObject universeObject in Universe.UniverseObjects) - OnUniverseObjectUnregistered(Universe, universeObject); + OnUniverseObjectUnregistered(Universe, new(universeObject)); - Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; - Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; + Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered); + Universe.OnUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered); Universe = null!; OnUnassigned?.Invoke(this); @@ -96,5 +101,23 @@ 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() + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + } + + public BehaviourCollector(IUniverse universe) + { + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; + delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered; + delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered; + + Assign(universe); + } } diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index bbf1b8a..5e4855f 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; @@ -8,11 +7,11 @@ 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; } = new(); + public Event OnBehaviourRemoved { get; } = new(); + public Event OnUniverseObjectAssigned { get; } = new(); - private readonly IList behaviours = new List(Constants.BEHAVIOURS_SIZE_INITIAL); + private readonly List behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL); private IUniverseObject _universeObject = null!; @@ -28,8 +27,9 @@ public class BehaviourController : BaseEntity, IBehaviourController if (IsInitialized) behaviour.Initialize(); - behaviour.OnPriorityChanged += OnPriorityChange; - OnBehaviourAdded?.Invoke(this, behaviour); + + behaviour.OnPriorityChanged.AddListener(OnPriorityChange); + OnBehaviourAdded?.Invoke(this, new(behaviour)); return behaviour; } @@ -94,10 +94,10 @@ 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); + OnBehaviourRemoved?.Invoke(this, new(behaviour)); } protected virtual void OnAssign(IUniverseObject universeObject) { } @@ -146,7 +146,7 @@ public class BehaviourController : BaseEntity, IBehaviourController behaviours.Add(behaviour); } - private void OnPriorityChange(IBehaviour sender, int previousPriority) + private void OnPriorityChange(IBehaviour sender, IBehaviour.PriorityChangedArguments args) { behaviours.Remove(sender); InsertBehaviourByPriority(sender); diff --git a/Engine.Core/CoroutineManager.cs b/Engine.Core/CoroutineManager.cs index 950891a..511f755 100644 --- a/Engine.Core/CoroutineManager.cs +++ b/Engine.Core/CoroutineManager.cs @@ -20,15 +20,15 @@ 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) + private void OnUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = enumerators.Count - 1; i >= 0; i--) { diff --git a/Engine.Core/Helpers/Event.cs b/Engine.Core/Helpers/Event.cs new file mode 100644 index 0000000..121b637 --- /dev/null +++ b/Engine.Core/Helpers/Event.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace Syntriax.Engine.Core; + +public class Event +{ + private readonly List listeners = new(8); + + public void AddListener(EventHandler listener) => listeners.Add(listener); + public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + public void Clear() => listeners.Clear(); + public void Invoke(TSender 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 delegate void EventHandler(TSender sender); +} + +public class Event +{ + private readonly List listeners = new(8); + + public void AddListener(EventHandler listener) => listeners.Add(listener); + public void RemoveListener(EventHandler listener) => listeners.Remove(listener); + public void Clear() => listeners.Clear(); + public void Invoke(TSender sender, TArguments args) + { + for (int i = 0; i < listeners.Count; i++) + try { listeners[i].Invoke(sender, args); } + catch (Exception exception) + { + string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", sender, args)})"; + Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}"); + } + } + + public delegate void EventHandler(TSender sender, TArguments args); +} diff --git a/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs b/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs index 0daed26..a92034d 100644 --- a/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs +++ b/Engine.Core/Helpers/Progression/IReadOnlyProgressionTracker.cs @@ -2,12 +2,11 @@ namespace Syntriax.Engine.Core; public interface IReadOnlyProgressionTracker { - event ProgressionUpdatedEventHandler? OnUpdated; - event ProgressionEndedEventHandler? OnEnded; + Event OnUpdated { get; } + Event OnEnded { get; } float Progression { get; } string Status { get; } - delegate void ProgressionUpdatedEventHandler(IReadOnlyProgressionTracker sender, float previousProgression, string previousStatus); - delegate void ProgressionEndedEventHandler(IReadOnlyProgressionTracker sender); + readonly record struct ProgressionUpdatedArguments(float PreviousProgression, string PreviousStatus); } diff --git a/Engine.Core/Helpers/Progression/ProgressionTracker.cs b/Engine.Core/Helpers/Progression/ProgressionTracker.cs index 7175561..93cf936 100644 --- a/Engine.Core/Helpers/Progression/ProgressionTracker.cs +++ b/Engine.Core/Helpers/Progression/ProgressionTracker.cs @@ -2,8 +2,8 @@ namespace Syntriax.Engine.Core; public class ProgressionTracker : IProgressionTracker { - public event IReadOnlyProgressionTracker.ProgressionUpdatedEventHandler? OnUpdated = null; - public event IReadOnlyProgressionTracker.ProgressionEndedEventHandler? OnEnded = null; + public Event OnUpdated { get; } = new(); + public Event OnEnded { get; } = new(); public float Progression { get; private set; } = 0f; public string Status { get; private set; } = "Default"; @@ -19,7 +19,7 @@ public class ProgressionTracker : IProgressionTracker Progression = progression.Clamp(Progression, 1f); Status = status; - OnUpdated?.Invoke(this, previousProgression, previousStatus); + OnUpdated?.Invoke(this, new(previousProgression, previousStatus)); if (progression >= 1f) OnEnded?.Invoke(this); @@ -30,7 +30,7 @@ public class ProgressionTracker : IProgressionTracker Progression = 0f; Status = "Default"; - OnUpdated = null; - OnEnded = null; + OnUpdated.Clear(); + OnEnded.Clear(); } } diff --git a/Engine.Core/Primitives/Shape2D.cs b/Engine.Core/Primitives/Shape2D.cs index 6030f8c..06122c0 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; } = new(); private List _vertices = vertices; @@ -256,8 +256,6 @@ public class Shape2D(List vertices) : IEnumerable /// IEnumerator IEnumerable.GetEnumerator() => Vertices.GetEnumerator(); - - public delegate void ShapeUpdatedEventHandler(Shape2D shape2D); } /// diff --git a/Engine.Core/Serialization/EntityRegistry.cs b/Engine.Core/Serialization/EntityRegistry.cs index a698ab1..c02b9d2 100644 --- a/Engine.Core/Serialization/EntityRegistry.cs +++ b/Engine.Core/Serialization/EntityRegistry.cs @@ -5,7 +5,7 @@ namespace Syntriax.Engine.Core.Serialization; public class EntityRegistry { - public event EntityRegisteredEventHandler? OnEntityRegistered = null!; + public Event OnEntityRegistered = null!; private readonly Dictionary?> assignCallbacks = []; private readonly Dictionary registeredEntities = []; @@ -14,7 +14,7 @@ public class EntityRegistry public void Add(IEntity entity) { if (registeredEntities.TryAdd(entity.Id, entity)) - OnEntityRegistered?.Invoke(this, entity); + OnEntityRegistered?.Invoke(this, new(entity)); } public void QueueAssign(string id, Action setMethod) @@ -35,5 +35,5 @@ public class EntityRegistry registeredEntities.Clear(); } - public delegate void EntityRegisteredEventHandler(EntityRegistry sender, IEntity entity); + public readonly record struct EntityRegisteredArguments(IEntity Entity); } diff --git a/Engine.Core/StateEnable.cs b/Engine.Core/StateEnable.cs index d3dd714..2b4fc9e 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; } = new(); + public Event OnEntityAssigned { get; } = new(); + public Event? OnUnassigned { get; } = new(); private bool _enabled = true; private IEntity _entity = null!; @@ -21,7 +21,7 @@ public class StateEnable : IStateEnable bool previousState = _enabled; _enabled = value; - OnEnabledChanged?.Invoke(this, previousState); + OnEnabledChanged?.Invoke(this, new(previousState)); } } diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index 2d05c91..53f5267 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -1,4 +1,3 @@ - namespace Syntriax.Engine.Core; public class DrawManager : UniverseObject @@ -33,9 +32,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 +43,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..470f1c6 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -1,4 +1,3 @@ - using System.Collections.Generic; namespace Syntriax.Engine.Core; @@ -21,9 +20,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,12 +32,12 @@ 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) + private void OnPreUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = toCallFirstFrameUpdates.Count - 1; i >= 0; i--) { @@ -50,25 +49,25 @@ public class UpdateManager : UniverseObject preUpdateEntities[i].PreUpdate(); } - private void OnUpdate(IUniverse sender, UniverseTime engineTime) + private void OnUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = updateEntities.Count - 1; i >= 0; i--) updateEntities[i].Update(); } - private void OnPostUpdate(IUniverse sender, UniverseTime engineTime) + private void OnPostUpdate(IUniverse sender, IUniverse.UpdateArguments args) { for (int i = postUpdateEntities.Count - 1; i >= 0; i--) postUpdateEntities[i].PostUpdate(); } - private void OnFirstFrameCollected(IBehaviourCollector sender, IFirstFrameUpdate behaviourCollected) + private void OnFirstFrameCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) { - toCallFirstFrameUpdates.Add(behaviourCollected); + toCallFirstFrameUpdates.Add(args.BehaviourCollected); } public UpdateManager() { - firstFrameUpdates.OnCollected += OnFirstFrameCollected; + firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected); } } diff --git a/Engine.Core/Transform2D.cs b/Engine.Core/Transform2D.cs index e51e21d..fa50bb9 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; } = new(); + public Event OnScaleChanged { get; } = new(); + public Event OnRotationChanged { get; } = new(); private Vector2D _position = Vector2D.Zero; private Vector2D _scale = Vector2D.One; @@ -31,7 +31,7 @@ public class Transform2D : Behaviour, ITransform2D _position = value; UpdateLocalPosition(); - OnPositionChanged?.Invoke(this, previousPosition); + OnPositionChanged?.Invoke(this, new(previousPosition)); } } @@ -47,7 +47,7 @@ public class Transform2D : Behaviour, ITransform2D _scale = value; UpdateLocalScale(); - OnScaleChanged?.Invoke(this, previousScale); + OnScaleChanged?.Invoke(this, new(previousScale)); } } @@ -63,7 +63,7 @@ public class Transform2D : Behaviour, ITransform2D _rotation = value; UpdateLocalRotation(); - OnRotationChanged?.Invoke(this, previousRotation); + OnRotationChanged?.Invoke(this, new(previousRotation)); } } @@ -79,7 +79,7 @@ public class Transform2D : Behaviour, ITransform2D _localPosition = value; UpdatePosition(); - OnPositionChanged?.Invoke(this, previousPosition); + OnPositionChanged?.Invoke(this, new(previousPosition)); } } @@ -97,8 +97,8 @@ public class Transform2D : Behaviour, ITransform2D UpdateScale(); UpdatePosition(); - OnScaleChanged?.Invoke(this, previousScale); - OnPositionChanged?.Invoke(this, previousPosition); + OnScaleChanged?.Invoke(this, new(previousScale)); + OnPositionChanged?.Invoke(this, new(previousPosition)); } } @@ -114,21 +114,21 @@ public class Transform2D : Behaviour, ITransform2D _localRotation = value; UpdateRotation(); - OnRotationChanged?.Invoke(this, previousRotation); + OnRotationChanged?.Invoke(this, new(previousRotation)); } } - private void RecalculatePosition(ITransform2D _, Vector2D previousPosition) + private void RecalculatePosition(ITransform2D _, ITransform2D.PositionChangedArguments args) { if (parentTransform is null) return; UpdatePosition(); - OnPositionChanged?.Invoke(this, previousPosition); + OnPositionChanged?.Invoke(this, args); } - private void RecalculateScale(ITransform2D _, Vector2D previousScale) + private void RecalculateScale(ITransform2D _, ITransform2D.ScaleChangedArguments args) { if (parentTransform is null) return; @@ -138,11 +138,11 @@ public class Transform2D : Behaviour, ITransform2D UpdateScale(); UpdatePosition(); - OnScaleChanged?.Invoke(this, previousScale); - OnPositionChanged?.Invoke(this, previousPosition); + OnScaleChanged?.Invoke(this, args); + OnPositionChanged?.Invoke(this, new(previousPosition)); } - private void RecalculateRotation(ITransform2D _, float previousRotation) + private void RecalculateRotation(ITransform2D _, ITransform2D.RotationChangedArguments args) { if (parentTransform is null) return; @@ -152,8 +152,8 @@ public class Transform2D : Behaviour, ITransform2D UpdateRotation(); UpdatePosition(); - OnRotationChanged?.Invoke(this, previousRotation); - OnPositionChanged?.Invoke(this, previousPosition); + OnRotationChanged?.Invoke(this, args); + OnPositionChanged?.Invoke(this, new(previousPosition)); } private void UpdateLocalPosition() @@ -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,48 +220,48 @@ 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(); UpdateLocalRotation(); - OnPositionChanged?.Invoke(this, Position); - OnScaleChanged?.Invoke(this, Scale); - OnRotationChanged?.Invoke(this, Rotation); + OnPositionChanged?.Invoke(this, new(Position)); + OnScaleChanged?.Invoke(this, new(Scale)); + OnRotationChanged?.Invoke(this, new(Rotation)); } - private void LookForTransform2D(IBehaviourController sender, IBehaviour behaviourAdded) + private void LookForTransform2D(IBehaviourController sender, IBehaviourController.BehaviourAddedArguments args) { - if (behaviourAdded is not ITransform2D transform2D) + if (args.BehaviourAdded is not ITransform2D) return; UpdateReferences(UniverseObject.Parent); } - private void OnParentChanged(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent) + private void OnParentChanged(IUniverseObject sender, IUniverseObject.ParentChangedArguments args) { - UpdateReferences(newParent); + UpdateReferences(args.CurrentParent); } } diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index 62be549..f0f82a4 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; } = new(); + public Event OnUpdate { get; } = new(); + public Event OnPostUpdate { get; } = new(); + public Event OnPreDraw { get; } = new(); + public Event OnDraw { get; } = new(); + public Event OnPostDraw { get; } = new(); + public Event OnUniverseObjectRegistered { get; } = new(); + public Event OnUniverseObjectUnRegistered { get; } = new(); + public Event OnTimeScaleChanged { get; } = new(); - public event IUniverse.UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered = null; - public event IUniverse.UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered = null; - - public event IUniverse.TimeScaleChangedEventHandler? OnTimeScaleChanged = null; + private readonly Event.EventHandler delegateOnUniverseObjectFinalize = null!; + private readonly Event.EventHandler delegateOnUniverseObjectExitedUniverse = null!; private readonly List _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL); private float _timeScale = 1f; + public Universe() + { + delegateOnUniverseObjectFinalize = OnUniverseObjectFinalize; + delegateOnUniverseObjectExitedUniverse = OnUniverseObjectExitedUniverse; + } + public IReadOnlyList UniverseObjects => _universeObjects; public UniverseTime Time { get; private set; } = new(); @@ -37,7 +44,7 @@ public class Universe : BaseEntity, IUniverse float previousTimeScale = _timeScale; _timeScale = value; - OnTimeScaleChanged?.Invoke(this, previousTimeScale); + OnTimeScaleChanged?.Invoke(this, new(previousTimeScale)); } } @@ -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(delegateOnUniverseObjectFinalize); + universeObject.OnExitedUniverse.AddListener(delegateOnUniverseObjectExitedUniverse); if (!universeObject.Initialize()) throw new Exception($"{universeObject.Name} can't be initialized"); @@ -60,7 +67,7 @@ public class Universe : BaseEntity, IUniverse if (!universeObject.EnterUniverse(this)) throw new Exception($"{universeObject.Name} can't enter the universe"); - OnUniverseObjectRegistered?.Invoke(this, universeObject); + OnUniverseObjectRegistered?.Invoke(this, new(universeObject)); } public T InstantiateUniverseObject(params object?[]? args) where T : class, IUniverseObject @@ -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(delegateOnUniverseObjectFinalize); + universeObject.OnExitedUniverse.RemoveListener(delegateOnUniverseObjectExitedUniverse); for (int i = universeObject.Children.Count - 1; i >= 0; i--) Remove(universeObject.Children[i]); @@ -95,7 +102,7 @@ public class Universe : BaseEntity, IUniverse if (!universeObject.Finalize()) throw new Exception($"{universeObject.Name} can't be finalized"); - OnUniverseObjectUnRegistered?.Invoke(this, universeObject); + OnUniverseObjectUnRegistered?.Invoke(this, new(universeObject)); } protected override void InitializeInternal() @@ -118,9 +125,9 @@ public class Universe : BaseEntity, IUniverse UnscaledTime = engineTime; Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale))); - OnPreUpdate?.Invoke(this, Time); - OnUpdate?.Invoke(this, Time); - OnPostUpdate?.Invoke(this, Time); + OnPreUpdate?.Invoke(this, new(Time)); + OnUpdate?.Invoke(this, new(Time)); + OnPostUpdate?.Invoke(this, new(Time)); } public void Draw() @@ -138,7 +145,7 @@ public class Universe : BaseEntity, IUniverse Remove(universeObject); } - private void OnUniverseObjectExitedUniverse(IUniverseObject sender, IUniverse universe) + private void OnUniverseObjectExitedUniverse(IUniverseObject sender, IUniverseObject.ExitedUniverseArguments args) { if (sender is IUniverseObject universeObject) Remove(universeObject); diff --git a/Engine.Core/UniverseObject.cs b/Engine.Core/UniverseObject.cs index 9a8adbd..94ff25a 100644 --- a/Engine.Core/UniverseObject.cs +++ b/Engine.Core/UniverseObject.cs @@ -6,14 +6,15 @@ 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; } = new(); + public Event OnExitedUniverse { get; } = new(); + public Event OnParentChanged { get; } = new(); + public Event OnChildrenAdded { get; } = new(); + public Event OnChildrenRemoved { get; } = new(); + + public Event OnActiveChanged { get; } = new(); + public Event OnNameChanged { get; } = new(); + public Event OnBehaviourControllerAssigned { get; } = new(); private string _name = nameof(UniverseObject); private IUniverse _universe = null!; @@ -37,7 +38,7 @@ public class UniverseObject : BaseEntity, IUniverseObject string previousName = _name; _name = value; - OnNameChanged?.Invoke(this, previousName); + OnNameChanged?.Invoke(this, new(previousName)); } } @@ -50,7 +51,7 @@ public class UniverseObject : BaseEntity, IUniverseObject _universe = universe; UpdateActive(); OnEnteringUniverse(universe); - OnEnteredUniverse?.Invoke(this, universe); + OnEnteredUniverse?.Invoke(this, new(universe)); return true; } @@ -62,7 +63,7 @@ public class UniverseObject : BaseEntity, IUniverseObject OnExitingUniverse(universe); _universe = null!; - OnExitedUniverse?.Invoke(this, universe); + OnExitedUniverse?.Invoke(this, new(universe)); return true; } @@ -78,7 +79,7 @@ public class UniverseObject : BaseEntity, IUniverseObject if (previousParent is not null) { previousParent.RemoveChild(this); - previousParent.OnActiveChanged -= OnParentActiveChanged; + previousParent.OnActiveChanged.RemoveListener(OnParentActiveChanged); } Parent = parent; @@ -89,11 +90,11 @@ public class UniverseObject : BaseEntity, IUniverseObject parent.Universe.Register(this); parent.AddChild(this); - parent.OnActiveChanged += OnParentActiveChanged; + parent.OnActiveChanged.AddListener(OnParentActiveChanged); } UpdateActive(); - OnParentChanged?.Invoke(this, previousParent, parent); + OnParentChanged?.Invoke(this, new(previousParent, parent)); } public void AddChild(IUniverseObject parent) @@ -103,7 +104,7 @@ public class UniverseObject : BaseEntity, IUniverseObject _children.Add(parent); parent.SetParent(this); - OnChildrenAdded?.Invoke(this, parent); + OnChildrenAdded?.Invoke(this, new(parent)); } public void RemoveChild(IUniverseObject child) @@ -112,7 +113,7 @@ public class UniverseObject : BaseEntity, IUniverseObject return; child.SetParent(null); - OnChildrenRemoved?.Invoke(this, child); + OnChildrenRemoved?.Invoke(this, new(child)); } protected virtual void OnAssign(IBehaviourController behaviourController) { } @@ -131,11 +132,11 @@ public class UniverseObject : BaseEntity, IUniverseObject { base.OnAssign(stateEnable); - stateEnable.OnEnabledChanged += OnStateEnabledChanged; + stateEnable.OnEnabledChanged.AddListener(OnStateEnabledChanged); } - private void OnParentActiveChanged(IActive sender, bool previousState) => UpdateActive(); - private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive(); + private void OnParentActiveChanged(IActive sender, IActive.ActiveChangedArguments args) => UpdateActive(); + private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); private void UpdateActive() { @@ -143,13 +144,13 @@ public class UniverseObject : BaseEntity, IUniverseObject _isActive = StateEnable.Enabled && (Parent?.IsActive ?? true); if (previousActive != IsActive) - OnActiveChanged?.Invoke(this, previousActive); + OnActiveChanged?.Invoke(this, new(previousActive)); } 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..a6cfa7d 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; } @@ -44,7 +44,7 @@ public interface ICollider2D : IBehaviour void Resolve(CollisionDetectionInformation collisionDetectionInformation); void Trigger(ICollider2D initiator); - delegate void CollisionDetectedEventHandler(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation); - delegate void CollisionResolvedEventHandler(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation); - delegate void TriggeredEventHandler(ICollider2D sender, ICollider2D initiatorCollider); + readonly record struct CollisionDetectedArguments(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation); + readonly record struct CollisionResolvedArguments(ICollider2D sender, CollisionDetectionInformation collisionDetectionInformation); + readonly record struct TriggeredArguments(ICollider2D sender, ICollider2D initiatorCollider); } diff --git a/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs b/Engine.Physics2D/Abstract/IPhysicsEngine2D.cs index c65f139..c096daf 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. @@ -33,6 +35,6 @@ public interface IPhysicsEngine2D /// The time step. void StepIndividual(IRigidBody2D rigidBody, float deltaTime); - delegate void PhysicsIterationEventHandler(IPhysicsEngine2D sender, float iterationDeltaTime); - delegate void PhysicsStepEventHandler(IPhysicsEngine2D sender, float stepDeltaTime); + readonly record struct PhysicsIterationArguments(IPhysicsEngine2D sender, float iterationDeltaTime); + readonly record struct PhysicsStepArguments(IPhysicsEngine2D sender, float stepDeltaTime); } diff --git a/Engine.Physics2D/Collider2DBehaviourBase.cs b/Engine.Physics2D/Collider2DBehaviourBase.cs index 66cfda2..72acf9c 100644 --- a/Engine.Physics2D/Collider2DBehaviourBase.cs +++ b/Engine.Physics2D/Collider2DBehaviourBase.cs @@ -4,13 +4,30 @@ 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; } = new(); + public Event OnCollisionResolved { get; } = new(); + public Event OnTriggered { get; } = new(); + + private readonly Event.EventHandler delegateOnBehaviourAddedToController = null!; + private readonly Event.EventHandler delegateOnBehaviourRemovedFromController = null!; + private readonly Event.EventHandler delegateSetNeedsRecalculationFromPosition = null!; + private readonly Event.EventHandler delegateSetNeedsRecalculationFromRotation = null!; + private readonly Event.EventHandler delegateSetNeedsRecalculationFromScale = null!; + private readonly Event.EventHandler delegateUpdateRigidBody2D = null!; protected bool NeedsRecalculation { get; set; } = true; protected IRigidBody2D? _rigidBody2D = null; + protected Collider2DBehaviourBase() + { + delegateOnBehaviourAddedToController = OnBehaviourAddedToController; + delegateOnBehaviourRemovedFromController = OnBehaviourRemovedFromController; + delegateSetNeedsRecalculationFromPosition = SetNeedsRecalculationFromPosition; + delegateSetNeedsRecalculationFromRotation = SetNeedsRecalculationFromRotation; + delegateSetNeedsRecalculationFromScale = SetNeedsRecalculationFromScale; + delegateUpdateRigidBody2D = UpdateRigidBody2D; + } + public IRigidBody2D? RigidBody2D => _rigidBody2D; public bool IsTrigger { get; set; } = false; @@ -29,44 +46,44 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D { BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); - BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController; - BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController; + BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAddedToController); + BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemovedFromController); - Transform.OnPositionChanged += SetNeedsRecalculationFromPosition; - Transform.OnRotationChanged += SetNeedsRecalculationFromRotation; - Transform.OnScaleChanged += SetNeedsRecalculationFromScale; - UniverseObject.OnParentChanged += UpdateRigidBody2D; + Transform.OnPositionChanged.AddListener(delegateSetNeedsRecalculationFromPosition); + Transform.OnRotationChanged.AddListener(delegateSetNeedsRecalculationFromRotation); + Transform.OnScaleChanged.AddListener(delegateSetNeedsRecalculationFromScale); + UniverseObject.OnParentChanged.AddListener(delegateUpdateRigidBody2D); } - private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent) + private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject.ParentChangedArguments args) { BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); } - private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour) + private void OnBehaviourAddedToController(IBehaviourController sender, IBehaviourController.BehaviourAddedArguments args) { - if (behaviour is IRigidBody2D rigidBody) + if (args.BehaviourAdded is IRigidBody2D rigidBody) _rigidBody2D = rigidBody; } - private void OnBehaviourRemovedFromController(IBehaviourController _, IBehaviour behaviour) + private void OnBehaviourRemovedFromController(IBehaviourController sender, IBehaviourController.BehaviourRemovedArguments args) { - if (behaviour is IRigidBody2D _) + if (args.BehaviourRemoved is IRigidBody2D) _rigidBody2D = null; } - private void SetNeedsRecalculationFromScale(ITransform2D sender, Vector2D previousScale) => NeedsRecalculation = true; - private void SetNeedsRecalculationFromPosition(ITransform2D sender, Vector2D previousPosition) => NeedsRecalculation = true; - private void SetNeedsRecalculationFromRotation(ITransform2D sender, float previousRotation) => NeedsRecalculation = true; + private void SetNeedsRecalculationFromPosition(ITransform2D sender, ITransform2D.PositionChangedArguments args) => NeedsRecalculation = true; + private void SetNeedsRecalculationFromScale(ITransform2D sender, ITransform2D.ScaleChangedArguments args) => NeedsRecalculation = true; + private void SetNeedsRecalculationFromRotation(ITransform2D sender, ITransform2D.RotationChangedArguments args) => NeedsRecalculation = true; protected override void OnFinalize() { - BehaviourController.OnBehaviourAdded -= OnBehaviourAddedToController; - BehaviourController.OnBehaviourRemoved -= OnBehaviourRemovedFromController; - Transform.OnScaleChanged -= SetNeedsRecalculationFromScale; + BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAddedToController); + BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemovedFromController); + Transform.OnScaleChanged.RemoveListener(delegateSetNeedsRecalculationFromScale); - Transform.OnPositionChanged -= SetNeedsRecalculationFromPosition; - Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation; + Transform.OnPositionChanged.RemoveListener(delegateSetNeedsRecalculationFromPosition); + Transform.OnRotationChanged.RemoveListener(delegateSetNeedsRecalculationFromRotation); } public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); diff --git a/Engine.Physics2D/PhysicsCoroutineManager.cs b/Engine.Physics2D/PhysicsCoroutineManager.cs index 9583933..e5d47c1 100644 --- a/Engine.Physics2D/PhysicsCoroutineManager.cs +++ b/Engine.Physics2D/PhysicsCoroutineManager.cs @@ -7,6 +7,8 @@ namespace Syntriax.Engine.Physics2D; public class PhysicsCoroutineManager : UniverseObject { + private readonly Event.EventHandler delegateOnUpdate = null!; + private readonly List enumerators = []; private IPhysicsEngine2D? physicsEngine = null; @@ -25,9 +27,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,11 +47,11 @@ 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) + private void OnUpdate(IUniverse sender, IUniverse.UpdateArguments args) { if (Universe is not IUniverse universe) return; @@ -57,8 +59,13 @@ 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); } } + + public PhysicsCoroutineManager() + { + delegateOnUpdate = OnUpdate; + } } diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index ae9a5e9..355d0ca 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -4,8 +4,10 @@ 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; } = new(); + public Event OnPhysicsStep { get; } = new(); + + private readonly Event.EventHandler delegateOnPreUpdate = null!; private float physicsTicker = 0f; private int _iterationPerStep = 1; @@ -178,7 +180,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,12 +191,12 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D colliderCollector.Unassign(); rigidBodyCollector.Unassign(); - universe.OnPreUpdate -= OnEnginePreUpdate; + universe.OnPreUpdate.RemoveListener(OnEnginePreUpdate); } - private void OnEnginePreUpdate(IUniverse sender, UniverseTime engineTime) + private void OnEnginePreUpdate(IUniverse sender, IUniverse.UpdateArguments args) { - physicsTicker += engineTime.DeltaTime; + physicsTicker += args.EngineTime.DeltaTime; while (physicsTicker >= IterationPeriod) { @@ -207,11 +209,15 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D { collisionDetector = new CollisionDetector2D(); collisionResolver = new CollisionResolver2D(); + + delegateOnPreUpdate = OnEnginePreUpdate; } public PhysicsEngine2D(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver) { this.collisionDetector = collisionDetector; this.collisionResolver = collisionResolver; + + delegateOnPreUpdate = OnEnginePreUpdate; } } diff --git a/Engine.Physics2D/PhysicsEngine2DStandalone.cs b/Engine.Physics2D/PhysicsEngine2DStandalone.cs index 375ed60..66bf714 100644 --- a/Engine.Physics2D/PhysicsEngine2DStandalone.cs +++ b/Engine.Physics2D/PhysicsEngine2DStandalone.cs @@ -6,8 +6,11 @@ namespace Syntriax.Engine.Physics2D; public class PhysicsEngine2DStandalone : IPhysicsEngine2D { - public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; - public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; + public Event OnPhysicsIteration { get; } = new(); + public Event OnPhysicsStep { get; } = new(); + + private readonly Event.EventHandler delegateOnBehaviourAdded = null!; + private readonly Event.EventHandler delegateOnBehaviourRemoved = null!; private readonly List rigidBodies = new(32); private readonly List colliders = new(64); @@ -29,13 +32,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(delegateOnBehaviourAdded); + rigidBody.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved); } public void RemoveRigidBody(IRigidBody2D rigidBody) { rigidBodies.Remove(rigidBody); + + rigidBody.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded); + rigidBody.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved); } public void Step(float deltaTime) @@ -172,17 +178,17 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime; } - private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourAdded(IBehaviourController sender, IBehaviourController.BehaviourAddedArguments args) { - if (behaviour is not ICollider2D collider2D) + if (args.BehaviourAdded is not ICollider2D collider2D) return; colliders.Add(collider2D); } - private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour) + private void OnBehaviourRemoved(IBehaviourController sender, IBehaviourController.BehaviourRemovedArguments args) { - if (behaviour is not ICollider2D collider2D) + if (args.BehaviourRemoved is not ICollider2D collider2D) return; colliders.Remove(collider2D); @@ -192,11 +198,17 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D { collisionDetector = new CollisionDetector2D(); collisionResolver = new CollisionResolver2D(); + + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; } public PhysicsEngine2DStandalone(ICollisionDetector2D collisionDetector, ICollisionResolver2D collisionResolver) { this.collisionDetector = collisionDetector; this.collisionResolver = collisionResolver; + + delegateOnBehaviourAdded = OnBehaviourAdded; + delegateOnBehaviourRemoved = OnBehaviourRemoved; } } diff --git a/Engine.Systems/Input/IButtonInputs.cs b/Engine.Systems/Input/IButtonInputs.cs index 6361772..75cd678 100644 --- a/Engine.Systems/Input/IButtonInputs.cs +++ b/Engine.Systems/Input/IButtonInputs.cs @@ -4,15 +4,15 @@ namespace Syntriax.Engine.Systems.Input; public interface IButtonInputs : IHasStateEnable { - event ButtonCallbackEventHandler? OnAnyButtonPressed; - event ButtonCallbackEventHandler? OnAnyButtonReleased; + Event, ButtonCallbackArguments> OnAnyButtonPressed { get; } + Event, ButtonCallbackArguments> OnAnyButtonReleased { get; } - void RegisterOnPress(T button, ButtonCallbackEventHandler callback); - void UnregisterOnPress(T button, ButtonCallbackEventHandler callback); - void RegisterOnRelease(T button, ButtonCallbackEventHandler callback); - void UnregisterOnRelease(T button, ButtonCallbackEventHandler callback); + void RegisterOnPress(T button, Event, ButtonCallbackArguments>.EventHandler callback); + void UnregisterOnPress(T button, Event, ButtonCallbackArguments>.EventHandler callback); + void RegisterOnRelease(T button, Event, ButtonCallbackArguments>.EventHandler callback); + void UnregisterOnRelease(T button, Event, ButtonCallbackArguments>.EventHandler callback); bool IsPressed(T button); - delegate void ButtonCallbackEventHandler(IButtonInputs buttonInputs, T button); + readonly record struct ButtonCallbackArguments(T Button); } diff --git a/Engine.Systems/StateMachine/IState.cs b/Engine.Systems/StateMachine/IState.cs index e3bb49e..f30b260 100644 --- a/Engine.Systems/StateMachine/IState.cs +++ b/Engine.Systems/StateMachine/IState.cs @@ -4,10 +4,10 @@ namespace Syntriax.Engine.Systems.StateMachine; public interface IState : IEntity, INameable { - event StateUpdateEventHandler? OnStateUpdate; - event StateTransitionedFromEventHandler? OnStateTransitionedFrom; - event StateTransitionedToEventHandler? OnStateTransitionedTo; - event StateTransitionReadyEventHandler? OnStateTransitionReady; + Event OnStateUpdate { get; } + Event OnStateTransitionedFrom { get; } + Event OnStateTransitionedTo { get; } + Event OnStateTransitionReady { get; } IState? GetNextState(); @@ -15,8 +15,7 @@ public interface IState : IEntity, INameable void TransitionTo(IState from); void TransitionFrom(IState to); - delegate void StateUpdateEventHandler(IState sender); - delegate void StateTransitionedFromEventHandler(IState sender, IState toState); - delegate void StateTransitionedToEventHandler(IState sender, IState fromState); - delegate void StateTransitionReadyEventHandler(IState sender, IState toState); + readonly record struct StateTransitionedFromArguments(IState ToState); + readonly record struct StateTransitionedToArguments(IState FromState); + readonly record struct StateTransitionReadyArguments(IState ToState); } diff --git a/Engine.Systems/StateMachine/State.cs b/Engine.Systems/StateMachine/State.cs index 656e269..86b030e 100644 --- a/Engine.Systems/StateMachine/State.cs +++ b/Engine.Systems/StateMachine/State.cs @@ -6,11 +6,11 @@ namespace Syntriax.Engine.Systems.StateMachine; public class State : BaseEntity, IState { - public event IState.StateUpdateEventHandler? OnStateUpdate = null; - 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 OnStateUpdate { get; } = new(); + public Event OnStateTransitionedFrom { get; } = new(); + public Event OnStateTransitionedTo { get; } = new(); + public Event OnStateTransitionReady { get; } = new(); + public Event OnNameChanged { get; } = new(); private readonly List transitions = []; private readonly Dictionary possibleTransitions = []; @@ -28,7 +28,7 @@ public class State : BaseEntity, IState string previousName = _name; _name = value; - OnNameChanged?.Invoke(this, previousName); + OnNameChanged?.Invoke(this, new(previousName)); } } @@ -53,12 +53,12 @@ public class State : BaseEntity, IState public void Update() { if (GetNextState() is IState transitionState) - OnStateTransitionReady?.Invoke(this, transitionState); + OnStateTransitionReady?.Invoke(this, new(transitionState)); OnStateUpdate?.Invoke(this); } - public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, from); - public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, to); + public void TransitionTo(IState from) => OnStateTransitionedTo?.Invoke(this, new(from)); + public void TransitionFrom(IState to) => OnStateTransitionedFrom?.Invoke(this, new(to)); public IState? GetNextState() { diff --git a/Engine.Systems/StateMachine/StateBehaviourBase.cs b/Engine.Systems/StateMachine/StateBehaviourBase.cs index 2b93388..efc6c9a 100644 --- a/Engine.Systems/StateMachine/StateBehaviourBase.cs +++ b/Engine.Systems/StateMachine/StateBehaviourBase.cs @@ -4,12 +4,11 @@ namespace Syntriax.Engine.Systems.StateMachine; 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 abstract event IState.StateTransitionReadyEventHandler? OnStateTransitionReady; + public Event OnStateUpdate { get; } = new(); + public Event OnStateTransitionedFrom { get; } = new(); + public Event OnStateTransitionedTo { get; } = new(); + public Event OnStateTransitionReady { get; } = new(); + public Event OnNameChanged { get; } = new(); private string _name = string.Empty; public string Name @@ -22,7 +21,7 @@ public abstract class StateBehaviourBase : Behaviour, IState string previousName = _name; _name = value; - OnNameChanged?.Invoke(this, previousName); + OnNameChanged?.Invoke(this, new(previousName)); } } @@ -37,14 +36,14 @@ public abstract class StateBehaviourBase : Behaviour, IState public void TransitionTo(IState from) { OnTransitionedToState(from); - OnStateTransitionedTo?.Invoke(this, from); + OnStateTransitionedTo?.Invoke(this, new(from)); } protected virtual void OnTransitionedFromState(IState to) { } public void TransitionFrom(IState to) { OnTransitionedFromState(to); - OnStateTransitionedFrom?.Invoke(this, to); + OnStateTransitionedFrom?.Invoke(this, new(to)); } public abstract IState? GetNextState(); diff --git a/Engine.Systems/StateMachine/StateMachine.cs b/Engine.Systems/StateMachine/StateMachine.cs index 10b4be9..90b0b29 100644 --- a/Engine.Systems/StateMachine/StateMachine.cs +++ b/Engine.Systems/StateMachine/StateMachine.cs @@ -5,9 +5,17 @@ namespace Syntriax.Engine.Systems.StateMachine; public class StateMachine : Behaviour { - public event StateChangedEventHandler? OnStateChanged = null; + public Event OnStateChanged { get; } = new(); + + private readonly Event.EventHandler delegateOnStateTransitionReady = null!; private IState _state = new State(); + + public StateMachine() + { + delegateOnStateTransitionReady = OnStateTransitionReady; + } + [Serialize] public IState State { @@ -18,20 +26,20 @@ public class StateMachine : Behaviour return; IState previousState = _state; - previousState.OnStateTransitionReady -= OnStateTransitionReady; + previousState.OnStateTransitionReady.RemoveListener(delegateOnStateTransitionReady); _state = value; previousState.TransitionFrom(value); value.TransitionTo(_state); - OnStateChanged?.Invoke(this, previousState, value); + OnStateChanged?.Invoke(this, new(value, previousState)); - value.OnStateTransitionReady += OnStateTransitionReady; + value.OnStateTransitionReady.AddListener(delegateOnStateTransitionReady); } } - private void OnStateTransitionReady(IState sender, IState toState) + private void OnStateTransitionReady(IState sender, IState.StateTransitionReadyArguments args) { - State = toState; + State = args.ToState; while (State.GetNextState() is IState nextState) State = nextState; } @@ -47,5 +55,5 @@ public class StateMachine : Behaviour State.Update(); } - public delegate void StateChangedEventHandler(StateMachine sender, IState previousState, IState newState); + public readonly record struct StateChangedArguments(IState CurrentState, IState PreviousState); } diff --git a/Engine.Systems/Time/IReadOnlyStopwatch.cs b/Engine.Systems/Time/IReadOnlyStopwatch.cs index 3caaaa9..ea28155 100644 --- a/Engine.Systems/Time/IReadOnlyStopwatch.cs +++ b/Engine.Systems/Time/IReadOnlyStopwatch.cs @@ -1,18 +1,19 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Systems.Time; public interface IReadOnlyStopwatch { - event StopwatchEventHandler? OnStarted; - event StopwatchDeltaEventHandler? OnDelta; - event StopwatchEventHandler? OnStopped; + Event OnStarted { get; } + Event OnDelta { get; } + Event OnStopped { get; } double Time { get; } TimerState State { get; } - event StopwatchEventHandler? OnPaused; - event StopwatchEventHandler? OnResumed; + Event OnPaused { get; } + Event OnResumed { get; } - delegate void StopwatchEventHandler(IReadOnlyStopwatch sender); - delegate void StopwatchDeltaEventHandler(IReadOnlyStopwatch sender, double delta); + readonly record struct StopwatchDeltaArguments(double Delta); } diff --git a/Engine.Systems/Time/IReadOnlyTicker.cs b/Engine.Systems/Time/IReadOnlyTicker.cs index 9ffec3b..665671f 100644 --- a/Engine.Systems/Time/IReadOnlyTicker.cs +++ b/Engine.Systems/Time/IReadOnlyTicker.cs @@ -1,11 +1,11 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Systems.Time; public interface IReadOnlyTicker : IReadOnlyStopwatch { - event TickerTickEventHandler? OnTick; + Event OnTick { get; } int TickCounter { get; } double TickPeriod { get; set; } - - delegate void TickerTickEventHandler(IReadOnlyTicker sender); } diff --git a/Engine.Systems/Time/IReadOnlyTimer.cs b/Engine.Systems/Time/IReadOnlyTimer.cs index 660ccb7..c1e2a51 100644 --- a/Engine.Systems/Time/IReadOnlyTimer.cs +++ b/Engine.Systems/Time/IReadOnlyTimer.cs @@ -1,13 +1,15 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Systems.Time; public interface IReadOnlyTimer { - event TimerEventHandler? OnStarted; - event TimerDeltaEventHandler? OnDelta; - event TimerEventHandler? OnStopped; + Event OnStarted { get; } + Event OnDelta { get; } + Event OnStopped { get; } - event TimerEventHandler? OnPaused; - event TimerEventHandler? OnResumed; + Event OnPaused { get; } + Event OnResumed { get; } double StartTime { get; } double Remaining { get; } @@ -16,7 +18,6 @@ public interface IReadOnlyTimer TimerState State { get; } - delegate void TimerEventHandler(IReadOnlyTimer sender); - delegate void TimerDeltaEventHandler(IReadOnlyTimer sender, double delta); + readonly record struct TimerDeltaArguments(double delta); } diff --git a/Engine.Systems/Time/ITicker.cs b/Engine.Systems/Time/ITicker.cs index 8bb1fc2..1d88e4a 100644 --- a/Engine.Systems/Time/ITicker.cs +++ b/Engine.Systems/Time/ITicker.cs @@ -1,11 +1,11 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Systems.Time; public interface ITicker : IStopwatch { - event TickerTickEventHandler? OnTick; + Event OnTick { get; } int TickCounter { get; } double Period { get; set; } - - delegate void TickerTickEventHandler(ITicker sender); } diff --git a/Engine.Systems/Time/StopwatchBehaviour.cs b/Engine.Systems/Time/StopwatchBehaviour.cs index 96bcb8a..cb71327 100644 --- a/Engine.Systems/Time/StopwatchBehaviour.cs +++ b/Engine.Systems/Time/StopwatchBehaviour.cs @@ -4,11 +4,11 @@ namespace Syntriax.Engine.Systems.Time; public class StopwatchBehaviour : Behaviour, IStopwatch { - public event IReadOnlyStopwatch.StopwatchEventHandler? OnStarted = null; - public event IReadOnlyStopwatch.StopwatchDeltaEventHandler? OnDelta = null; - public event IReadOnlyStopwatch.StopwatchEventHandler? OnStopped = null; - public event IReadOnlyStopwatch.StopwatchEventHandler? OnPaused = null; - public event IReadOnlyStopwatch.StopwatchEventHandler? OnResumed = null; + public Event OnStarted { get; } = new(); + public Event OnDelta { get; } = new(); + public Event OnStopped { get; } = new(); + public Event OnPaused { get; } = new(); + public Event OnResumed { get; } = new(); public double Time { get; protected set; } = 0f; public TimerState State { get; protected set; } = TimerState.Idle; @@ -46,7 +46,7 @@ public class StopwatchBehaviour : Behaviour, IStopwatch double delta = Universe.Time.DeltaSpan.TotalSeconds; Time += delta; - OnDelta?.Invoke(this, delta); + OnDelta?.Invoke(this, new(delta)); } protected override void OnEnteredUniverse(IUniverse universe) diff --git a/Engine.Systems/Time/TickerBehaviour.cs b/Engine.Systems/Time/TickerBehaviour.cs index 9f82b30..4f47d1e 100644 --- a/Engine.Systems/Time/TickerBehaviour.cs +++ b/Engine.Systems/Time/TickerBehaviour.cs @@ -4,7 +4,7 @@ namespace Syntriax.Engine.Systems.Time; public class TickerBehaviour : StopwatchBehaviour, ITicker { - public event ITicker.TickerTickEventHandler? OnTick = null; + public Event OnTick { get; } = new(); public double Period { get; set; } = 1f; public int TickCounter { get; private set; } = 0; diff --git a/Engine.Systems/Time/TimerBehaviour.cs b/Engine.Systems/Time/TimerBehaviour.cs index 533fea4..93162fe 100644 --- a/Engine.Systems/Time/TimerBehaviour.cs +++ b/Engine.Systems/Time/TimerBehaviour.cs @@ -4,11 +4,11 @@ namespace Syntriax.Engine.Systems.Time; public class TimerBehaviour : Behaviour, ITimer { - public event IReadOnlyTimer.TimerEventHandler? OnStarted = null; - public event IReadOnlyTimer.TimerDeltaEventHandler? OnDelta = null; - public event IReadOnlyTimer.TimerEventHandler? OnStopped = null; - public event IReadOnlyTimer.TimerEventHandler? OnPaused = null; - public event IReadOnlyTimer.TimerEventHandler? OnResumed = null; + public Event OnStarted { get; } = new(); + public Event OnDelta { get; } = new(); + public Event OnStopped { get; } = new(); + public Event OnPaused { get; } = new(); + public Event OnResumed { get; } = new(); public TimerState State { get; protected set; } = TimerState.Idle; public double StartTime { get; protected set; } = 0f; @@ -61,7 +61,7 @@ public class TimerBehaviour : Behaviour, ITimer double delta = Universe.Time.DeltaSpan.TotalSeconds; Remaining -= delta; - OnDelta?.Invoke(this, delta); + OnDelta?.Invoke(this, new(delta)); if (Remaining <= .0f) Stop(); diff --git a/Engine.Systems/Tween/ITween.cs b/Engine.Systems/Tween/ITween.cs index 6f90137..f4d881b 100644 --- a/Engine.Systems/Tween/ITween.cs +++ b/Engine.Systems/Tween/ITween.cs @@ -1,16 +1,18 @@ +using Syntriax.Engine.Core; + namespace Syntriax.Engine.Systems.Tween; public interface ITween { - event TweenEventHandler? OnStarted; - event TweenEventHandler? OnPaused; - event TweenEventHandler? OnResumed; - event TweenEventHandler? OnCancelled; - event TweenEventHandler? OnCompleted; - event TweenEventHandler? OnEnded; + Event OnStarted { get; } + Event OnPaused { get; } + Event OnResumed { get; } + Event OnCancelled { get; } + Event OnCompleted { get; } + Event OnEnded { get; } - event TweenEventHandler? OnUpdated; - event TweenDeltaEventHandler? OnDeltaUpdated; + Event OnUpdated { get; } + Event OnDeltaUpdated { get; } TweenState State { get; set; } @@ -19,7 +21,6 @@ public interface ITween float Progress { get; } float Value { get; } - delegate void TweenEventHandler(ITween sender); - delegate void TweenDeltaEventHandler(ITween sender, float delta); + readonly record struct TweenDeltaArguments(float Delta); } diff --git a/Engine.Systems/Tween/Tween.cs b/Engine.Systems/Tween/Tween.cs index 5a4d48a..c92aa94 100644 --- a/Engine.Systems/Tween/Tween.cs +++ b/Engine.Systems/Tween/Tween.cs @@ -4,14 +4,14 @@ namespace Syntriax.Engine.Systems.Tween; internal class Tween : ITween { - public event ITween.TweenEventHandler? OnStarted = null; - public event ITween.TweenEventHandler? OnPaused = null; - public event ITween.TweenEventHandler? OnResumed = null; - public event ITween.TweenEventHandler? OnCancelled = null; - public event ITween.TweenEventHandler? OnCompleted = null; - public event ITween.TweenEventHandler? OnEnded = null; - public event ITween.TweenEventHandler? OnUpdated = null; - public event ITween.TweenDeltaEventHandler? OnDeltaUpdated = null; + public Event OnStarted { get; } = new(); + public Event OnPaused { get; } = new(); + public Event OnResumed { get; } = new(); + public Event OnCancelled { get; } = new(); + public Event OnCompleted { get; } = new(); + public Event OnEnded { get; } = new(); + public Event OnUpdated { get; } = new(); + public Event OnDeltaUpdated { get; } = new(); private TweenState _state = TweenState.Idle; public TweenState State @@ -60,7 +60,7 @@ internal class Tween : ITween Progress = Counter / Duration; OnUpdated?.Invoke(this); - OnDeltaUpdated?.Invoke(this, Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress)); + OnDeltaUpdated?.Invoke(this, new(Easing.Evaluate(Progress) - Easing.Evaluate(previousProgress))); if (_counter >= Duration) State = TweenState.Completed; @@ -74,6 +74,22 @@ internal class Tween : ITween State = TweenState.Idle; } + internal void Wipe() + { + OnStarted.Clear(); + OnPaused.Clear(); + OnResumed.Clear(); + OnCancelled.Clear(); + OnCompleted.Clear(); + OnEnded.Clear(); + OnUpdated.Clear(); + OnDeltaUpdated.Clear(); + + Easing = EaseLinear.Instance; + + Reset(); + } + public Tween() { } public Tween(float duration) { diff --git a/Engine.Systems/Tween/TweenExtensions.cs b/Engine.Systems/Tween/TweenExtensions.cs index aa10375..4b02cac 100644 --- a/Engine.Systems/Tween/TweenExtensions.cs +++ b/Engine.Systems/Tween/TweenExtensions.cs @@ -1,7 +1,5 @@ using System; -using Syntriax.Engine.Core; - namespace Syntriax.Engine.Systems.Tween; public static class TweenExtensions @@ -11,14 +9,14 @@ public static class TweenExtensions Tween tweenConcrete = (Tween)tween; int counter = count; - tweenConcrete.OnCompleted += _ => + tweenConcrete.OnCompleted.AddListener(_ => { if (counter-- <= 0) return; tweenConcrete.Reset(); tweenConcrete.State = TweenState.Playing; - }; + }); return tween; } @@ -26,11 +24,11 @@ public static class TweenExtensions public static ITween LoopInfinitely(this ITween tween) { Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnCompleted += _ => + tweenConcrete.OnCompleted.AddListener(_ => { tweenConcrete.Reset(); tweenConcrete.State = TweenState.Playing; - }; + }); return tween; } @@ -45,57 +43,49 @@ public static class TweenExtensions public static ITween OnStart(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnStarted += _ => callback.Invoke(); + tween.OnStarted.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnPause(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnPaused += _ => callback.Invoke(); + tween.OnPaused.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnResume(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnResumed += _ => callback.Invoke(); + tween.OnResumed.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnCancel(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnCancelled += _ => callback.Invoke(); + tween.OnCancelled.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnComplete(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnCompleted += _ => callback.Invoke(); + tween.OnCompleted.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnEnd(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnEnded += _ => callback.Invoke(); + tween.OnEnded.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnUpdate(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnUpdated += _ => callback.Invoke(); + tween.OnUpdated.AddListener(_ => callback.Invoke()); return tween; } public static ITween OnDeltaUpdate(this ITween tween, Action callback) { - Tween tweenConcrete = (Tween)tween; - tweenConcrete.OnDeltaUpdated += (_, delta) => callback.Invoke(delta); + tween.OnDeltaUpdated.AddListener((_, arguments) => callback.Invoke(arguments.Delta)); return tween; } } diff --git a/Engine.Systems/Tween/TweenManager.cs b/Engine.Systems/Tween/TweenManager.cs index 7bd052d..f547042 100644 --- a/Engine.Systems/Tween/TweenManager.cs +++ b/Engine.Systems/Tween/TweenManager.cs @@ -15,7 +15,7 @@ public class TweenManager : UniverseObject, ITweenManager public ITween StartTween(float duration, ITweenManager.TweenSetCallback? setCallback = null) { Tween tween = Get(duration); - tween.OnUpdated += tween => setCallback?.Invoke(tween.Value); + tween.OnUpdated.AddListener(tween => setCallback?.Invoke(tween.Value)); runningCoroutines.Add(tween, coroutineManager.StartCoroutine(RunTween(tween))); return tween; } @@ -59,6 +59,7 @@ public class TweenManager : UniverseObject, ITweenManager } runningCoroutines.Remove(tween); + Return(tween); } public void CancelTween(ITween tween)