perf: regular events to custom events

This commit is contained in:
Syntriax 2025-05-30 12:58:08 +03:00
parent b1b5af94d3
commit 846aa75dd5
42 changed files with 342 additions and 198 deletions

View File

@ -8,7 +8,7 @@ public interface IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle. /// Event triggered when the <see cref="IAssignable"/>'s fields are unassigned and completely ready to recycle.
/// </summary> /// </summary>
event UnassignEventHandler? OnUnassigned; Event<IAssignable>? OnUnassigned { get; }
/// <summary> /// <summary>
/// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle. /// Unassign <see cref="IAssignable"/>'s all fields and make it ready to recycle.

View File

@ -8,7 +8,7 @@ public interface IHasBehaviourController : IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value. /// Event triggered when the <see cref="IBehaviourController"/> value has has been assigned a new value.
/// </summary> /// </summary>
event BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned; Event<IHasBehaviourController> OnBehaviourControllerAssigned { get; }
/// <inheritdoc cref="IBehaviourController" /> /// <inheritdoc cref="IBehaviourController" />
IBehaviourController BehaviourController { get; } IBehaviourController BehaviourController { get; }

View File

@ -8,7 +8,7 @@ public interface IHasEntity : IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value. /// Event triggered when the <see cref="IEntity"/> value has has been assigned a new value.
/// </summary> /// </summary>
event EntityAssignedEventHandler? OnEntityAssigned; Event<IHasEntity> OnEntityAssigned { get; }
/// <inheritdoc cref="IEntity" /> /// <inheritdoc cref="IEntity" />
IEntity Entity { get; } IEntity Entity { get; }

View File

@ -8,7 +8,7 @@ public interface IHasStateEnable : IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value. /// Event triggered when the <see cref="IStateEnable"/> value has has been assigned a new value.
/// </summary> /// </summary>
event StateEnableAssignedEventHandler? OnStateEnableAssigned; Event<IHasStateEnable> OnStateEnableAssigned { get; }
/// <inheritdoc cref="IStateEnable" /> /// <inheritdoc cref="IStateEnable" />
IStateEnable StateEnable { get; } IStateEnable StateEnable { get; }

View File

@ -8,7 +8,7 @@ public interface IHasUniverse : IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IUniverse"/> value has has been assigned a new value. /// Event triggered when the <see cref="IUniverse"/> value has has been assigned a new value.
/// </summary> /// </summary>
event UniverseAssignedEventHandler? OnUniverseAssigned; Event<IHasUniverse> OnUniverseAssigned { get; }
/// <inheritdoc cref="IUniverse" /> /// <inheritdoc cref="IUniverse" />
IUniverse Universe { get; } IUniverse Universe { get; }

View File

@ -8,7 +8,7 @@ public interface IHasUniverseObject : IAssignable
/// <summary> /// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> value has has been assigned a new value. /// Event triggered when the <see cref="IUniverseObject"/> value has has been assigned a new value.
/// </summary> /// </summary>
event UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned; Event<IHasUniverseObject> OnUniverseObjectAssigned { get; }
/// <inheritdoc cref="IUniverseObject" /> /// <inheritdoc cref="IUniverseObject" />
IUniverseObject UniverseObject { get; } IUniverseObject UniverseObject { get; }

View File

@ -8,7 +8,7 @@ public interface IActive
/// <summary> /// <summary>
/// Event triggered when the <see cref="IsActive"/> state of the <see cref="IActive"/> changes. /// Event triggered when the <see cref="IsActive"/> state of the <see cref="IActive"/> changes.
/// </summary> /// </summary>
event ActiveChangedEventHandler? OnActiveChanged; Event<IActive, bool> OnActiveChanged { get; }
/// <summary> /// <summary>
/// The value indicating whether the <see cref="IActive"/> is enabled. /// The value indicating whether the <see cref="IActive"/> is enabled.

View File

@ -8,7 +8,7 @@ public interface IBehaviour : IEntity, IActive, IHasBehaviourController, IHasSta
/// <summary> /// <summary>
/// Event triggered when the priority of the <see cref="IBehaviour"/> changes. /// Event triggered when the priority of the <see cref="IBehaviour"/> changes.
/// </summary> /// </summary>
event PriorityChangedEventHandler? OnPriorityChanged; Event<IBehaviour, int> OnPriorityChanged { get; }
/// <summary> /// <summary>
/// The priority of the <see cref="IBehaviour"/>. /// The priority of the <see cref="IBehaviour"/>.

View File

@ -10,12 +10,12 @@ public interface IBehaviourCollector<T> : IHasUniverse where T : class
/// <summary> /// <summary>
/// Event triggered when an object of type <typeparamref name="T"/> is added to the collector. /// Event triggered when an object of type <typeparamref name="T"/> is added to the collector.
/// </summary> /// </summary>
event CollectedEventHandler? OnCollected; Event<IBehaviourCollector<T>, T> OnCollected { get; }
/// <summary> /// <summary>
/// Event triggered when an object of type <typeparamref name="T"/> is removed from the collector. /// Event triggered when an object of type <typeparamref name="T"/> is removed from the collector.
/// </summary> /// </summary>
event RemovedEventHandler? OnRemoved; Event<IBehaviourCollector<T>, T> OnRemoved { get; }
/// <summary> /// <summary>
/// Amount of <typeparamref name="T"/> collected. /// Amount of <typeparamref name="T"/> collected.

View File

@ -10,12 +10,12 @@ public interface IBehaviourController : IEntity, IHasUniverseObject
/// <summary> /// <summary>
/// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>. /// Event triggered when a <see cref="IBehaviour"/> is added to the <see cref="IBehaviourController"/>.
/// </summary> /// </summary>
event BehaviourAddedEventHandler? OnBehaviourAdded; Event<IBehaviourController, IBehaviour> OnBehaviourAdded { get; }
/// <summary> /// <summary>
/// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>. /// Event triggered when a <see cref="IBehaviour"/> is removed from the <see cref="IBehaviourController"/>.
/// </summary> /// </summary>
event BehaviourRemovedEventHandler? OnBehaviourRemoved; Event<IBehaviourController, IBehaviour> OnBehaviourRemoved { get; }
/// <summary> /// <summary>
/// Amount of <see cref="IBehaviour"/> collected. /// Amount of <see cref="IBehaviour"/> collected.

View File

@ -9,7 +9,7 @@ public interface IEntity : IInitializable, IHasStateEnable
/// Event triggered when the <see cref="Id"/> of the <see cref="IEntity"/> changes. /// Event triggered when the <see cref="Id"/> of the <see cref="IEntity"/> changes.
/// The string action parameter is the previous <see cref="Id"/> of the <see cref="IEntity"/>. /// The string action parameter is the previous <see cref="Id"/> of the <see cref="IEntity"/>.
/// </summary> /// </summary>
event IdChangedEventHandler? OnIdChanged; Event<IEntity, string> OnIdChanged { get; }
/// <summary> /// <summary>
/// The ID of the <see cref="IEntity"/>. /// The ID of the <see cref="IEntity"/>.

View File

@ -8,12 +8,12 @@ public interface IInitializable
/// <summary> /// <summary>
/// Event triggered when the <see cref="Initialize"/> method is called successfully. /// Event triggered when the <see cref="Initialize"/> method is called successfully.
/// </summary> /// </summary>
event InitializedEventHandler? OnInitialized; Event<IInitializable> OnInitialized { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="IInitializable"/> method is called successfully. /// Event triggered when the <see cref="IInitializable"/> method is called successfully.
/// </summary> /// </summary>
event FinalizedEventHandler? OnFinalized; Event<IInitializable> OnFinalized { get; }
/// <summary> /// <summary>
/// The value indicating whether the entity has been initialized. /// The value indicating whether the entity has been initialized.

View File

@ -8,7 +8,7 @@ public interface INameable
/// <summary> /// <summary>
/// Event triggered when the name of the entity changes. /// Event triggered when the name of the entity changes.
/// </summary> /// </summary>
event NameChangedEventHandler? OnNameChanged; Event<INameable, string> OnNameChanged { get; }
/// <summary> /// <summary>
/// The name of the entity. /// The name of the entity.

View File

@ -8,7 +8,7 @@ public interface IStateEnable : IHasEntity
/// <summary> /// <summary>
/// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes. /// Event triggered when the <see cref="Enabled"/> state of the <see cref="IStateEnable"/> changes.
/// </summary> /// </summary>
event EnabledChangedEventHandler? OnEnabledChanged; Event<IStateEnable, bool> OnEnabledChanged { get; }
/// <summary> /// <summary>
/// The value indicating whether the <see cref="IStateEnable"/> is enabled. /// The value indicating whether the <see cref="IStateEnable"/> is enabled.

View File

@ -8,17 +8,17 @@ public interface ITransform2D : IBehaviour
/// <summary> /// <summary>
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform2D"/> changes. /// Event triggered when the <see cref="Position"/> of the <see cref="ITransform2D"/> changes.
/// </summary> /// </summary>
event PositionChangedEventHandler? OnPositionChanged; Event<ITransform2D, Vector2D> OnPositionChanged { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform2D"/> changes. /// Event triggered when the <see cref="Scale"/> of the <see cref="ITransform2D"/> changes.
/// </summary> /// </summary>
event ScaleChangedEventHandler? OnScaleChanged; Event<ITransform2D, Vector2D> OnScaleChanged { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes. /// Event triggered when the <see cref="Rotation"/> of the <see cref="ITransform"/> changes.
/// </summary> /// </summary>
event RotationChangedEventHandler? OnRotationChanged; Event<ITransform2D, float> OnRotationChanged { get; }
/// <summary> /// <summary>
/// The world position of the <see cref="ITransform2D"/> in 2D space. /// The world position of the <see cref="ITransform2D"/> in 2D space.

View File

@ -10,47 +10,47 @@ public interface IUniverse : IEntity, IEnumerable<IUniverseObject>
/// <summary> /// <summary>
/// Event triggered when <see cref="Update(UniverseTime)"/> is about to be called called on the <see cref="IUniverse"/>. /// Event triggered when <see cref="Update(UniverseTime)"/> is about to be called called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event UpdateEventHandler? OnPreUpdate; Event<IUniverse, UniverseTime> OnPreUpdate { get; }
/// <summary> /// <summary>
/// Event triggered when <see cref="Update(UniverseTime)"/> is called on the <see cref="IUniverse"/>. /// Event triggered when <see cref="Update(UniverseTime)"/> is called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event UpdateEventHandler? OnUpdate; Event<IUniverse, UniverseTime> OnUpdate { get; }
/// <summary> /// <summary>
/// Event triggered after <see cref="Update(UniverseTime)"/> is called on the <see cref="IUniverse"/>. /// Event triggered after <see cref="Update(UniverseTime)"/> is called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event UpdateEventHandler? OnPostUpdate; Event<IUniverse, UniverseTime> OnPostUpdate { get; }
/// <summary> /// <summary>
/// Event triggered when <see cref="Draw"/> is about to be called called on the <see cref="IUniverse"/>. /// Event triggered when <see cref="Draw"/> is about to be called called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event DrawEventHandler? OnPreDraw; Event<IUniverse> OnPreDraw { get; }
/// <summary> /// <summary>
/// Event triggered when <see cref="Draw"/> is called on the <see cref="IUniverse"/>. /// Event triggered when <see cref="Draw"/> is called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event DrawEventHandler? OnDraw; Event<IUniverse> OnDraw { get; }
/// <summary> /// <summary>
/// Event triggered after <see cref="Draw"/> is called on the <see cref="IUniverse"/>. /// Event triggered after <see cref="Draw"/> is called on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event DrawEventHandler? OnPostDraw; Event<IUniverse> OnPostDraw { get; }
/// <summary> /// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>. /// Event triggered when a <see cref="IUniverseObject"/> is registered to the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered; Event<IUniverse, IUniverseObject> OnUniverseObjectRegistered { get; }
/// <summary> /// <summary>
/// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>. /// Event triggered when a <see cref="IUniverseObject"/> is unregistered from the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered; Event<IUniverse, IUniverseObject> OnUniverseObjectUnRegistered { get; }
/// <summary> /// <summary>
/// Event triggered when <see cref="TimeScale"/> is changed on the <see cref="IUniverse"/>. /// Event triggered when <see cref="TimeScale"/> is changed on the <see cref="IUniverse"/>.
/// </summary> /// </summary>
event TimeScaleChangedEventHandler? OnTimeScaleChanged; Event<IUniverse, float> OnTimeScaleChanged { get; }
/// <summary> /// <summary>
/// Current time scale the <see cref="IUniverse"/> operates on. /// Current time scale the <see cref="IUniverse"/> operates on.

View File

@ -12,27 +12,27 @@ public interface IUniverseObject : IEntity, IActive, INameable, IHasBehaviourCon
/// <summary> /// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> enters the universe. /// Event triggered when the <see cref="IUniverseObject"/> enters the universe.
/// </summary> /// </summary>
event EnteredUniverseEventHandler? OnEnteredUniverse; Event<IUniverseObject, IUniverse> OnEnteredUniverse { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="IUniverseObject"/> exits the universe. /// Event triggered when the <see cref="IUniverseObject"/> exits the universe.
/// </summary> /// </summary>
event ExitedUniverseEventHandler? OnExitedUniverse; Event<IUniverseObject, IUniverse> OnExitedUniverse { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="Parent"/> of the <see cref="IUniverseObject"/> changes. The second parameter is the old <see cref="IUniverseObject"/>. /// Event triggered when the <see cref="Parent"/> of the <see cref="IUniverseObject"/> changes. The second parameter is the old <see cref="IUniverseObject"/>.
/// </summary> /// </summary>
event ParentChangedEventHandler? OnParentChanged; Event<IUniverseObject, IUniverseObject?, IUniverseObject?> OnParentChanged { get; }
/// <summary> /// <summary>
/// Event triggered when a new <see cref="IUniverseObject"/> is added to the <see cref="Children"/>. /// Event triggered when a new <see cref="IUniverseObject"/> is added to the <see cref="Children"/>.
/// </summary> /// </summary>
event ChildrenAddedEventHandler? OnChildrenAdded; Event<IUniverseObject, IUniverseObject> OnChildrenAdded { get; }
/// <summary> /// <summary>
/// Event triggered when an <see cref="IUniverseObject"/> is removed from the <see cref="Children"/>. /// Event triggered when an <see cref="IUniverseObject"/> is removed from the <see cref="Children"/>.
/// </summary> /// </summary>
event ChildrenRemovedEventHandler? OnChildrenRemoved; Event<IUniverseObject, IUniverseObject> OnChildrenRemoved { get; }
/// <summary> /// <summary>
/// Gets the <see cref="IUniverse"/> this <see cref="IUniverseObject"/> is connected to, if any. /// Gets the <see cref="IUniverse"/> this <see cref="IUniverseObject"/> is connected to, if any.

View File

@ -1,15 +1,20 @@
using System.Collections; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : class, IBehaviour
{ {
public event IAssignable.UnassignEventHandler? OnUnassigned = null; public Event<IBehaviourCollector<T>, T> OnCollected { get; private set; } = new();
public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null; public Event<IBehaviourCollector<T>, T> OnRemoved { get; private set; } = new();
public Event<IHasUniverse> OnUniverseAssigned { get; private set; } = new();
public Event<IAssignable>? OnUnassigned { get; private set; } = new();
public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null; private readonly Action<IBehaviourController, IBehaviour> cachedOnBehaviourAdded = null!;
public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null; private readonly Action<IBehaviourController, IBehaviour> cachedOnBehaviourRemoved = null!;
private readonly Action<IActive, bool> cachedOnBehaviourStateChanged = null!;
private readonly Action<IUniverse, IUniverseObject> cachedOnUniverseObjectRegistered = null!;
private readonly Action<IUniverse, IUniverseObject> cachedOnUniverseObjectUnregistered = null!;
private readonly List<T> monitoringBehaviours = new(32); private readonly List<T> monitoringBehaviours = new(32);
protected readonly List<T> activeBehaviours = new(32); protected readonly List<T> activeBehaviours = new(32);
@ -17,13 +22,10 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
public IUniverse Universe { get; private set; } = null!; 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, IUniverseObject universeObject)
{ {
universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded.AddListener(cachedOnBehaviourAdded);
universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved.AddListener(cachedOnBehaviourRemoved);
for (int i = 0; i < universeObject.BehaviourController.Count; i++) for (int i = 0; i < universeObject.BehaviourController.Count; i++)
OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]);
@ -31,8 +33,8 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject)
{ {
universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(cachedOnBehaviourAdded);
universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(cachedOnBehaviourRemoved);
for (int i = 0; i < universeObject.BehaviourController.Count; i++) for (int i = 0; i < universeObject.BehaviourController.Count; i++)
OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]);
@ -46,7 +48,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
monitoringBehaviours.Add(tBehaviour); monitoringBehaviours.Add(tBehaviour);
monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour); monitoringActiveToBehaviour.Add(tBehaviour, tBehaviour);
tBehaviour.OnActiveChanged += OnBehaviourStateChanged; tBehaviour.OnActiveChanged.AddListener(cachedOnBehaviourStateChanged);
OnBehaviourStateChanged(tBehaviour, !tBehaviour.IsActive); OnBehaviourStateChanged(tBehaviour, !tBehaviour.IsActive);
} }
@ -75,7 +77,7 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour)) if (!monitoringBehaviours.Remove(tBehaviour) || !monitoringActiveToBehaviour.Remove(tBehaviour))
return; return;
tBehaviour.OnActiveChanged -= OnBehaviourStateChanged; tBehaviour.OnActiveChanged.RemoveListener(cachedOnBehaviourStateChanged);
if (activeBehaviours.Remove(tBehaviour)) if (activeBehaviours.Remove(tBehaviour))
{ {
OnBehaviourRemove(tBehaviour); OnBehaviourRemove(tBehaviour);
@ -91,8 +93,8 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
foreach (IUniverseObject universeObject in universe.UniverseObjects) foreach (IUniverseObject universeObject in universe.UniverseObjects)
OnUniverseObjectRegistered(universe, universeObject); OnUniverseObjectRegistered(universe, universeObject);
universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; universe.OnUniverseObjectRegistered.AddListener(cachedOnUniverseObjectRegistered);
universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; universe.OnUniverseObjectUnRegistered.AddListener(cachedOnUniverseObjectUnregistered);
Universe = universe; Universe = universe;
OnUniverseAssigned?.Invoke(this); OnUniverseAssigned?.Invoke(this);
@ -108,8 +110,8 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
foreach (IUniverseObject universeObject in Universe.UniverseObjects) foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnUniverseObjectUnregistered(Universe, universeObject); OnUniverseObjectUnregistered(Universe, universeObject);
Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; Universe.OnUniverseObjectRegistered.RemoveListener(cachedOnUniverseObjectRegistered);
Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; Universe.OnUniverseObjectUnRegistered.RemoveListener(cachedOnUniverseObjectUnregistered);
Universe = null!; Universe = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.Invoke(this);
@ -117,5 +119,14 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
} }
public int Count => activeBehaviours.Count; public int Count => activeBehaviours.Count;
public T this[System.Index index] => activeBehaviours[index]; public T this[Index index] => activeBehaviours[index];
public ActiveBehaviourCollector()
{
cachedOnBehaviourAdded = OnBehaviourAdded;
cachedOnBehaviourRemoved = OnBehaviourRemoved;
cachedOnBehaviourStateChanged = OnBehaviourStateChanged;
cachedOnUniverseObjectRegistered = OnUniverseObjectRegistered;
cachedOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
}
} }

View File

@ -22,7 +22,4 @@ public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> whe
if (SortBy is not null) if (SortBy is not null)
activeBehaviours.Sort(SortBy); activeBehaviours.Sort(SortBy);
} }
public ActiveBehaviourCollectorSorted() { }
public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy;
} }

View File

@ -4,13 +4,11 @@ namespace Syntriax.Engine.Core;
public abstract class BaseEntity : IEntity public abstract class BaseEntity : IEntity
{ {
public event IEntity.IdChangedEventHandler? OnIdChanged = null; public Event<IEntity, string> OnIdChanged { get; private set; } = new();
public Event<IInitializable> OnInitialized { get; private set; } = new();
public event IInitializable.InitializedEventHandler? OnInitialized = null; public Event<IInitializable> OnFinalized { get; private set; } = new();
public event IInitializable.FinalizedEventHandler? OnFinalized = null; public Event<IHasStateEnable> OnStateEnableAssigned { get; private set; } = new();
public Event<IAssignable> OnUnassigned { get; private set; } = new();
public event IHasStateEnable.StateEnableAssignedEventHandler? OnStateEnableAssigned = null;
public event IAssignable.UnassignEventHandler? OnUnassigned = null;
private IStateEnable _stateEnable = null!; private IStateEnable _stateEnable = null!;

View File

@ -1,3 +1,5 @@
using System;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate,
@ -7,11 +9,17 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate,
protected IUniverse Universe => BehaviourController.UniverseObject.Universe; protected IUniverse Universe => BehaviourController.UniverseObject.Universe;
protected IUniverseObject UniverseObject => BehaviourController.UniverseObject; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject;
private readonly Action<IUniverseObject, IUniverse> cachedEnteredUniverse = null!;
private readonly Action<IUniverseObject, IUniverse> cachedExitedUniverse = null!;
public Behaviour() public Behaviour()
{ {
OnInitialized += OnInitialize; OnInitialized.AddListener(OnInitialize);
OnFinalized += OnFinalize; OnFinalized.AddListener(OnFinalize);
OnUnassigned += OnUnassign; OnUnassigned.AddListener(OnUnassign);
cachedEnteredUniverse = EnteredUniverse;
cachedExitedUniverse = ExitedUniverse;
} }
protected virtual void OnUnassign() { } protected virtual void OnUnassign() { }
@ -20,8 +28,8 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate,
protected virtual void OnInitialize() { } protected virtual void OnInitialize() { }
protected virtual void OnInitialize(IInitializable _) protected virtual void OnInitialize(IInitializable _)
{ {
BehaviourController.UniverseObject.OnEnteredUniverse += EnteredUniverse; BehaviourController.UniverseObject.OnEnteredUniverse.AddListener(cachedEnteredUniverse);
BehaviourController.UniverseObject.OnExitedUniverse += ExitedUniverse; BehaviourController.UniverseObject.OnExitedUniverse.AddListener(cachedExitedUniverse);
OnInitialize(); OnInitialize();
@ -32,8 +40,8 @@ public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate,
protected virtual void OnFinalize() { } protected virtual void OnFinalize() { }
protected virtual void OnFinalize(IInitializable _) protected virtual void OnFinalize(IInitializable _)
{ {
BehaviourController.UniverseObject.OnEnteredUniverse -= EnteredUniverse; BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(cachedEnteredUniverse);
BehaviourController.UniverseObject.OnExitedUniverse -= ExitedUniverse; BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(cachedExitedUniverse);
OnFinalize(); OnFinalize();

View File

@ -1,11 +1,17 @@
using System;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] [System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")]
public abstract class BehaviourBase : BaseEntity, IBehaviour public abstract class BehaviourBase : BaseEntity, IBehaviour
{ {
public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; public Event<IBehaviour, int> OnPriorityChanged { get; private set; } = new();
public event IBehaviour.PriorityChangedEventHandler? OnPriorityChanged = null; public Event<IActive, bool> OnActiveChanged { get; private set; } = new();
public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; public Event<IHasBehaviourController> OnBehaviourControllerAssigned { get; private set; } = new();
private Action<IHasUniverseObject> cachedOnUniverseObjectAssigned = null!;
private Action<IActive, bool> cachedOnUniverseObjectActiveChanged = null!;
private Action<IStateEnable, bool> cachedOnStateEnabledChanged = null!;
private IBehaviourController _behaviourController = null!; private IBehaviourController _behaviourController = null!;
public IBehaviourController BehaviourController => _behaviourController; public IBehaviourController BehaviourController => _behaviourController;
@ -36,7 +42,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
_behaviourController = behaviourController; _behaviourController = behaviourController;
OnAssign(behaviourController); OnAssign(behaviourController);
behaviourController.OnUniverseObjectAssigned += OnUniverseObjectAssigned; behaviourController.OnUniverseObjectAssigned.AddListener(cachedOnUniverseObjectAssigned);
if (behaviourController.UniverseObject is not null) if (behaviourController.UniverseObject is not null)
OnUniverseObjectAssigned(behaviourController); OnUniverseObjectAssigned(behaviourController);
OnBehaviourControllerAssigned?.Invoke(this); OnBehaviourControllerAssigned?.Invoke(this);
@ -45,7 +51,7 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
private void OnUniverseObjectAssigned(IHasUniverseObject sender) private void OnUniverseObjectAssigned(IHasUniverseObject sender)
{ {
sender.UniverseObject.OnActiveChanged += OnUniverseObjectActiveChanged; sender.UniverseObject.OnActiveChanged.AddListener(cachedOnUniverseObjectActiveChanged);
UpdateActive(); UpdateActive();
} }
@ -53,13 +59,14 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
{ {
base.OnAssign(stateEnable); base.OnAssign(stateEnable);
stateEnable.OnEnabledChanged += OnStateEnabledChanged; stateEnable.OnEnabledChanged.AddListener(cachedOnStateEnabledChanged);
} }
protected override void UnassignInternal() protected override void UnassignInternal()
{ {
StateEnable.OnEnabledChanged -= OnStateEnabledChanged; BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(cachedOnUniverseObjectActiveChanged);
BehaviourController.OnUniverseObjectAssigned -= OnUniverseObjectAssigned; StateEnable.OnEnabledChanged.RemoveListener(cachedOnStateEnabledChanged);
BehaviourController.OnUniverseObjectAssigned.RemoveListener(cachedOnUniverseObjectAssigned);
base.UnassignInternal(); base.UnassignInternal();
_behaviourController = null!; _behaviourController = null!;
} }
@ -81,4 +88,11 @@ public abstract class BehaviourBase : BaseEntity, IBehaviour
if (previousActive != IsActive) if (previousActive != IsActive)
OnActiveChanged?.Invoke(this, previousActive); OnActiveChanged?.Invoke(this, previousActive);
} }
protected BehaviourBase()
{
cachedOnUniverseObjectAssigned = OnUniverseObjectAssigned;
cachedOnUniverseObjectActiveChanged = OnUniverseObjectActiveChanged;
cachedOnStateEnabledChanged = OnStateEnabledChanged;
}
} }

View File

@ -1,27 +1,28 @@
using System.Collections; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
{ {
public event IAssignable.UnassignEventHandler? OnUnassigned = null; public Event<IBehaviourCollector<T>, T> OnCollected { get; private set; } = new();
public event IHasUniverse.UniverseAssignedEventHandler? OnUniverseAssigned = null; public Event<IBehaviourCollector<T>, T> OnRemoved { get; private set; } = new();
public Event<IHasUniverse> OnUniverseAssigned { get; private set; } = new();
public Event<IAssignable>? OnUnassigned { get; private set; } = new();
public event IBehaviourCollector<T>.CollectedEventHandler? OnCollected = null; private readonly Action<IBehaviourController, IBehaviour> cachedOnBehaviourAdded = null!;
public event IBehaviourCollector<T>.RemovedEventHandler? OnRemoved = null; private readonly Action<IBehaviourController, IBehaviour> cachedOnBehaviourRemoved = null!;
private readonly Action<IUniverse, IUniverseObject> cachedOnUniverseObjectRegistered = null!;
private readonly Action<IUniverse, IUniverseObject> cachedOnUniverseObjectUnregistered = null!;
protected readonly List<T> behaviours = new(32); protected readonly List<T> behaviours = new(32);
public IUniverse Universe { get; private set; } = null!; 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, IUniverseObject universeObject)
{ {
universeObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded.AddListener(cachedOnBehaviourAdded);
universeObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved.AddListener(cachedOnBehaviourRemoved);
for (int i = 0; i < universeObject.BehaviourController.Count; i++) for (int i = 0; i < universeObject.BehaviourController.Count; i++)
OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]); OnBehaviourAdded(universeObject.BehaviourController, universeObject.BehaviourController[i]);
@ -29,8 +30,8 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject) private void OnUniverseObjectUnregistered(IUniverse manager, IUniverseObject universeObject)
{ {
universeObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded; universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(cachedOnBehaviourAdded);
universeObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved; universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(cachedOnBehaviourRemoved);
for (int i = 0; i < universeObject.BehaviourController.Count; i++) for (int i = 0; i < universeObject.BehaviourController.Count; i++)
OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]); OnBehaviourRemoved(universeObject.BehaviourController, universeObject.BehaviourController[i]);
@ -69,8 +70,8 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
foreach (IUniverseObject universeObject in universe.UniverseObjects) foreach (IUniverseObject universeObject in universe.UniverseObjects)
OnUniverseObjectRegistered(universe, universeObject); OnUniverseObjectRegistered(universe, universeObject);
universe.OnUniverseObjectRegistered += OnUniverseObjectRegistered; universe.OnUniverseObjectRegistered.AddListener(cachedOnUniverseObjectRegistered);
universe.OnUniverseObjectUnRegistered += OnUniverseObjectUnregistered; universe.OnUniverseObjectUnRegistered.AddListener(cachedOnUniverseObjectUnregistered);
Universe = universe; Universe = universe;
OnAssign(universe); OnAssign(universe);
@ -87,8 +88,8 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
foreach (IUniverseObject universeObject in Universe.UniverseObjects) foreach (IUniverseObject universeObject in Universe.UniverseObjects)
OnUniverseObjectUnregistered(Universe, universeObject); OnUniverseObjectUnregistered(Universe, universeObject);
Universe.OnUniverseObjectRegistered -= OnUniverseObjectRegistered; Universe.OnUniverseObjectRegistered.RemoveListener(cachedOnUniverseObjectRegistered);
Universe.OnUniverseObjectUnRegistered -= OnUniverseObjectUnregistered; Universe.OnUniverseObjectUnRegistered.RemoveListener(cachedOnUniverseObjectUnregistered);
Universe = null!; Universe = null!;
OnUnassigned?.Invoke(this); OnUnassigned?.Invoke(this);
@ -96,5 +97,13 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
} }
public int Count => behaviours.Count; public int Count => behaviours.Count;
public T this[System.Index index] => behaviours[index]; public T this[Index index] => behaviours[index];
public BehaviourCollector()
{
cachedOnBehaviourAdded = OnBehaviourAdded;
cachedOnBehaviourRemoved = OnBehaviourRemoved;
cachedOnUniverseObjectRegistered = OnUniverseObjectRegistered;
cachedOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
}
} }

View File

@ -22,7 +22,4 @@ public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
if (SortBy is not null) if (SortBy is not null)
behaviours.Sort(SortBy); behaviours.Sort(SortBy);
} }
public BehaviourCollectorSorted() { }
public BehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy;
} }

View File

@ -8,9 +8,9 @@ namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")] [System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")]
public class BehaviourController : BaseEntity, IBehaviourController public class BehaviourController : BaseEntity, IBehaviourController
{ {
public event IBehaviourController.BehaviourAddedEventHandler? OnBehaviourAdded = null; public Event<IBehaviourController, IBehaviour> OnBehaviourAdded { get; private set; } = new();
public event IBehaviourController.BehaviourRemovedEventHandler? OnBehaviourRemoved = null; public Event<IBehaviourController, IBehaviour> OnBehaviourRemoved { get; private set; } = new();
public event IHasUniverseObject.UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned = null; public Event<IHasUniverseObject> OnUniverseObjectAssigned { get; private set; } = new();
private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL); private readonly IList<IBehaviour> behaviours = new List<IBehaviour>(Constants.BEHAVIOURS_SIZE_INITIAL);
@ -20,6 +20,9 @@ public class BehaviourController : BaseEntity, IBehaviourController
public int Count => behaviours.Count; public int Count => behaviours.Count;
public IBehaviour this[Index index] => behaviours[index]; public IBehaviour this[Index index] => behaviours[index];
public int Count => behaviours.Count;
public IBehaviour this[Index index] => behaviours[index];
public T AddBehaviour<T>(T behaviour) where T : class, IBehaviour public T AddBehaviour<T>(T behaviour) where T : class, IBehaviour
{ {
InsertBehaviourByPriority(behaviour); InsertBehaviourByPriority(behaviour);
@ -28,7 +31,7 @@ public class BehaviourController : BaseEntity, IBehaviourController
if (IsInitialized) if (IsInitialized)
behaviour.Initialize(); behaviour.Initialize();
behaviour.OnPriorityChanged += OnPriorityChange; behaviour.OnPriorityChanged.AddListener(OnPriorityChange);
OnBehaviourAdded?.Invoke(this, behaviour); OnBehaviourAdded?.Invoke(this, behaviour);
return behaviour; return behaviour;
} }
@ -94,7 +97,7 @@ public class BehaviourController : BaseEntity, IBehaviourController
if (!behaviours.Contains(behaviour)) if (!behaviours.Contains(behaviour))
throw new Exception($"{behaviour.GetType().Name} does not exist in {UniverseObject.Name}'s {nameof(IBehaviourController)}."); throw new Exception($"{behaviour.GetType().Name} does not exist in {UniverseObject.Name}'s {nameof(IBehaviourController)}.");
behaviour.OnPriorityChanged -= OnPriorityChange; behaviour.OnPriorityChanged.RemoveListener(OnPriorityChange);
behaviour.Finalize(); behaviour.Finalize();
behaviours.Remove(behaviour); behaviours.Remove(behaviour);
OnBehaviourRemoved?.Invoke(this, behaviour); OnBehaviourRemoved?.Invoke(this, behaviour);

View File

@ -20,12 +20,12 @@ public class CoroutineManager : UniverseObject
protected override void OnEnteringUniverse(IUniverse universe) protected override void OnEnteringUniverse(IUniverse universe)
{ {
universe.OnUpdate += OnUpdate; universe.OnUpdate.AddListener(OnUpdate);
} }
protected override void OnExitingUniverse(IUniverse universe) 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, UniverseTime time)

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
namespace Syntriax.Engine.Core;
public class Event
{
private readonly List<Action> listeners = new(1000);
public void AddListener(Action listener) => listeners.Add(listener);
public void RemoveListener(Action listener) => listeners.Remove(listener);
public void Invoke()
{
for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Invoke(); }
catch (Exception exception)
{
string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}()";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}
public class Event<T1>
{
private readonly List<Action<T1>> listeners = new(1000);
public void AddListener(Action<T1> listener) => listeners.Add(listener);
public void RemoveListener(Action<T1> listener) => listeners.Remove(listener);
public void Invoke(T1 argument)
{
for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Invoke(argument); }
catch (Exception exception)
{
string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({argument})";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}
public class Event<T1, T2>
{
private readonly List<Action<T1, T2>> listeners = new(1000);
public void AddListener(Action<T1, T2> listener) => listeners.Add(listener);
public void RemoveListener(Action<T1, T2> listener) => listeners.Remove(listener);
public void Invoke(T1 argument1, T2 argument2)
{
for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Invoke(argument1, argument2); }
catch (Exception exception)
{
string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2)})";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}
public class Event<T1, T2, T3>
{
private readonly List<Action<T1, T2, T3>> listeners = new(1000);
public void AddListener(Action<T1, T2, T3> listener) => listeners.Add(listener);
public void RemoveListener(Action<T1, T2, T3> listener) => listeners.Remove(listener);
public void Invoke(T1 argument1, T2 argument2, T3 argument3)
{
for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Invoke(argument1, argument2, argument3); }
catch (Exception exception)
{
string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2, argument3)})";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}
public class Event<T1, T2, T3, T4>
{
private readonly List<Action<T1, T2, T3, T4>> listeners = new(1000);
public void AddListener(Action<T1, T2, T3, T4> listener) => listeners.Add(listener);
public void RemoveListener(Action<T1, T2, T3, T4> listener) => listeners.Remove(listener);
public void Invoke(T1 argument1, T2 argument2, T3 argument3, T4 argument4)
{
for (int i = 0; i < listeners.Count; i++)
try { listeners[i].Invoke(argument1, argument2, argument3, argument4); }
catch (Exception exception)
{
string methodCallRepresentation = $"{listeners[i].Method.DeclaringType?.FullName}.{listeners[i].Method.Name}({string.Join(", ", argument1, argument2, argument3, argument4)})";
Console.WriteLine($"Unexpected exception on invocation of method {methodCallRepresentation}:{Environment.NewLine}{exception.InnerException}");
}
}
}

View File

@ -18,7 +18,7 @@ public class Shape2D(List<Vector2D> vertices) : IEnumerable<Vector2D>
public static Shape2D Pentagon => CreateNgon(5, Vector2D.Up); public static Shape2D Pentagon => CreateNgon(5, Vector2D.Up);
public static Shape2D Hexagon => CreateNgon(6, Vector2D.Right); public static Shape2D Hexagon => CreateNgon(6, Vector2D.Right);
public event ShapeUpdatedEventHandler? OnShapeUpdated = null; public Event<Shape2D> OnShapeUpdated { get; private set; } = new();
private List<Vector2D> _vertices = vertices; private List<Vector2D> _vertices = vertices;

View File

@ -2,9 +2,9 @@ namespace Syntriax.Engine.Core;
public class StateEnable : IStateEnable public class StateEnable : IStateEnable
{ {
public event IAssignable.UnassignEventHandler? OnUnassigned = null; public Event<IStateEnable, bool> OnEnabledChanged { get; private set; } = new();
public event IHasEntity.EntityAssignedEventHandler? OnEntityAssigned = null; public Event<IHasEntity> OnEntityAssigned { get; private set; } = new();
public event IStateEnable.EnabledChangedEventHandler? OnEnabledChanged = null; public Event<IAssignable>? OnUnassigned { get; private set; } = new();
private bool _enabled = true; private bool _enabled = true;
private IEntity _entity = null!; private IEntity _entity = null!;

View File

@ -33,9 +33,9 @@ public class DrawManager : UniverseObject
drawEntities.Assign(universe); drawEntities.Assign(universe);
postDrawEntities.Assign(universe); postDrawEntities.Assign(universe);
universe.OnPreDraw += OnPreDraw; universe.OnPreDraw.AddListener(OnPreDraw);
universe.OnDraw += OnDraw; universe.OnDraw.AddListener(OnDraw);
universe.OnPostDraw += OnPostDraw; universe.OnPostDraw.AddListener(OnPostDraw);
} }
protected override void OnExitingUniverse(IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
@ -44,8 +44,8 @@ public class DrawManager : UniverseObject
drawEntities.Unassign(); drawEntities.Unassign();
postDrawEntities.Unassign(); postDrawEntities.Unassign();
universe.OnPreDraw -= OnPreDraw; universe.OnPreDraw.RemoveListener(OnPreDraw);
universe.OnDraw -= OnDraw; universe.OnDraw.RemoveListener(OnDraw);
universe.OnPostDraw -= OnPostDraw; universe.OnPostDraw.RemoveListener(OnPostDraw);
} }
} }

View File

@ -21,9 +21,9 @@ public class UpdateManager : UniverseObject
updateEntities.Assign(universe); updateEntities.Assign(universe);
postUpdateEntities.Assign(universe); postUpdateEntities.Assign(universe);
universe.OnPreUpdate += OnPreUpdate; universe.OnPreUpdate.AddListener(OnPreUpdate);
universe.OnUpdate += OnUpdate; universe.OnUpdate.AddListener(OnUpdate);
universe.OnPostUpdate += OnPostUpdate; universe.OnPostUpdate.AddListener(OnPostUpdate);
} }
protected override void OnExitingUniverse(IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
@ -33,9 +33,9 @@ public class UpdateManager : UniverseObject
updateEntities.Unassign(); updateEntities.Unassign();
postUpdateEntities.Unassign(); postUpdateEntities.Unassign();
universe.OnPreUpdate -= OnPreUpdate; universe.OnPreUpdate.RemoveListener(OnPreUpdate);
universe.OnUpdate -= OnUpdate; universe.OnUpdate.RemoveListener(OnUpdate);
universe.OnPostUpdate -= OnPostUpdate; universe.OnPostUpdate.RemoveListener(OnPostUpdate);
} }
private void OnPreUpdate(IUniverse sender, UniverseTime engineTime) private void OnPreUpdate(IUniverse sender, UniverseTime engineTime)
@ -69,6 +69,6 @@ public class UpdateManager : UniverseObject
public UpdateManager() public UpdateManager()
{ {
firstFrameUpdates.OnCollected += OnFirstFrameCollected; firstFrameUpdates.OnCollected.AddListener(OnFirstFrameCollected);
} }
} }

View File

@ -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}")] [System.Diagnostics.DebuggerDisplay("Name: {UniverseObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
public class Transform2D : Behaviour, ITransform2D public class Transform2D : Behaviour, ITransform2D
{ {
public event ITransform2D.PositionChangedEventHandler? OnPositionChanged = null; public Event<ITransform2D, Vector2D> OnPositionChanged { get; private set; } = new();
public event ITransform2D.ScaleChangedEventHandler? OnScaleChanged = null; public Event<ITransform2D, Vector2D> OnScaleChanged { get; private set; } = new();
public event ITransform2D.RotationChangedEventHandler? OnRotationChanged = null; public Event<ITransform2D, float> OnRotationChanged { get; private set; } = new();
private Vector2D _position = Vector2D.Zero; private Vector2D _position = Vector2D.Zero;
private Vector2D _scale = Vector2D.One; private Vector2D _scale = Vector2D.One;
@ -207,12 +207,12 @@ public class Transform2D : Behaviour, ITransform2D
protected override void InitializeInternal() protected override void InitializeInternal()
{ {
UpdateReferences(UniverseObject.Parent); UpdateReferences(UniverseObject.Parent);
UniverseObject.OnParentChanged += OnParentChanged; UniverseObject.OnParentChanged.AddListener(OnParentChanged);
} }
protected override void FinalizeInternal() protected override void FinalizeInternal()
{ {
UniverseObject.OnParentChanged -= OnParentChanged; UniverseObject.OnParentChanged.RemoveListener(OnParentChanged);
} }
private void UpdateReferences(IUniverseObject? parent) private void UpdateReferences(IUniverseObject? parent)
@ -220,28 +220,28 @@ public class Transform2D : Behaviour, ITransform2D
ITransform2D? previousParent = parentTransform; ITransform2D? previousParent = parentTransform;
if (previousParent is not null) if (previousParent is not null)
{ {
previousParent.OnPositionChanged -= RecalculatePosition; previousParent.OnPositionChanged.RemoveListener(RecalculatePosition);
previousParent.OnScaleChanged -= RecalculateScale; previousParent.OnScaleChanged.RemoveListener(RecalculateScale);
previousParent.OnRotationChanged -= RecalculateRotation; previousParent.OnRotationChanged.RemoveListener(RecalculateRotation);
previousParent.BehaviourController.UniverseObject.OnParentChanged -= OnParentChanged; previousParent.BehaviourController.UniverseObject.OnParentChanged.RemoveListener(OnParentChanged);
previousParent.BehaviourController.OnBehaviourAdded -= LookForTransform2D; previousParent.BehaviourController.OnBehaviourAdded.RemoveListener(LookForTransform2D);
} }
parentTransform = parent?.BehaviourController.GetBehaviour<ITransform2D>(); parentTransform = parent?.BehaviourController.GetBehaviour<ITransform2D>();
if (parentTransform is not null) if (parentTransform is not null)
{ {
parentTransform.OnPositionChanged += RecalculatePosition; parentTransform.OnPositionChanged.AddListener(RecalculatePosition);
parentTransform.OnScaleChanged += RecalculateScale; parentTransform.OnScaleChanged.AddListener(RecalculateScale);
parentTransform.OnRotationChanged += RecalculateRotation; parentTransform.OnRotationChanged.AddListener(RecalculateRotation);
parentTransform.BehaviourController.UniverseObject.OnParentChanged += OnParentChanged; parentTransform.BehaviourController.UniverseObject.OnParentChanged.AddListener(OnParentChanged);
UpdatePosition(); UpdatePosition();
UpdateScale(); UpdateScale();
UpdateRotation(); UpdateRotation();
} }
else if (UniverseObject.Parent is not null) else if (UniverseObject.Parent is not null)
UniverseObject.Parent.BehaviourController.OnBehaviourAdded += LookForTransform2D; UniverseObject.Parent.BehaviourController.OnBehaviourAdded.AddListener(LookForTransform2D);
UpdateLocalPosition(); UpdateLocalPosition();
UpdateLocalScale(); UpdateLocalScale();

View File

@ -7,21 +7,28 @@ namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")] [System.Diagnostics.DebuggerDisplay("UniverseObject Count: {_universeObjects.Count}")]
public class Universe : BaseEntity, IUniverse public class Universe : BaseEntity, IUniverse
{ {
public event IUniverse.UpdateEventHandler? OnPreUpdate = null; public Event<IUniverse, UniverseTime> OnPreUpdate { get; set; } = new();
public event IUniverse.UpdateEventHandler? OnUpdate = null; public Event<IUniverse, UniverseTime> OnUpdate { get; set; } = new();
public event IUniverse.UpdateEventHandler? OnPostUpdate = null; public Event<IUniverse, UniverseTime> OnPostUpdate { get; set; } = new();
public event IUniverse.DrawEventHandler? OnPreDraw = null; public Event<IUniverse> OnPreDraw { get; set; } = new();
public event IUniverse.DrawEventHandler? OnDraw = null; public Event<IUniverse> OnDraw { get; set; } = new();
public event IUniverse.DrawEventHandler? OnPostDraw = null; public Event<IUniverse> OnPostDraw { get; set; } = new();
public Event<IUniverse, IUniverseObject> OnUniverseObjectRegistered { get; set; } = new();
public Event<IUniverse, IUniverseObject> OnUniverseObjectUnRegistered { get; set; } = new();
public Event<IUniverse, float> OnTimeScaleChanged { get; set; } = new();
public event IUniverse.UniverseObjectRegisteredEventHandler? OnUniverseObjectRegistered = null; private readonly Action<IInitializable> cachedOnUniverseObjectFinalize = null!;
public event IUniverse.UniverseObjectUnRegisteredEventHandler? OnUniverseObjectUnRegistered = null; private readonly Action<IUniverseObject, IUniverse> cachedOnUniverseObjectExitedUniverse = null!;
public event IUniverse.TimeScaleChangedEventHandler? OnTimeScaleChanged = null;
private readonly List<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL); private readonly List<IUniverseObject> _universeObjects = new(Constants.UNIVERSE_OBJECTS_SIZE_INITIAL);
private float _timeScale = 1f; private float _timeScale = 1f;
public Universe()
{
cachedOnUniverseObjectFinalize = OnUniverseObjectFinalize;
cachedOnUniverseObjectExitedUniverse = OnUniverseObjectExitedUniverse;
}
public IReadOnlyList<IUniverseObject> UniverseObjects => _universeObjects; public IReadOnlyList<IUniverseObject> UniverseObjects => _universeObjects;
public UniverseTime Time { get; private set; } = new(); public UniverseTime Time { get; private set; } = new();
@ -46,8 +53,8 @@ public class Universe : BaseEntity, IUniverse
if (_universeObjects.Contains(universeObject)) if (_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}."); throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is already registered to the {nameof(Universe)}.");
universeObject.OnFinalized += OnUniverseObjectFinalize; universeObject.OnFinalized.AddListener(cachedOnUniverseObjectFinalize);
universeObject.OnExitedUniverse += OnUniverseObjectExitedUniverse; universeObject.OnExitedUniverse.AddListener(cachedOnUniverseObjectExitedUniverse);
if (!universeObject.Initialize()) if (!universeObject.Initialize())
throw new Exception($"{universeObject.Name} can't be initialized"); throw new Exception($"{universeObject.Name} can't be initialized");
@ -81,8 +88,8 @@ public class Universe : BaseEntity, IUniverse
if (!_universeObjects.Contains(universeObject)) if (!_universeObjects.Contains(universeObject))
throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}."); throw new Exception($"{nameof(IUniverseObject)} named {universeObject.Name} is not registered to the {nameof(Universe)}.");
universeObject.OnFinalized -= OnUniverseObjectFinalize; universeObject.OnFinalized.RemoveListener(cachedOnUniverseObjectFinalize);
universeObject.OnExitedUniverse -= OnUniverseObjectExitedUniverse; universeObject.OnExitedUniverse.RemoveListener(cachedOnUniverseObjectExitedUniverse);
for (int i = universeObject.Children.Count - 1; i >= 0; i--) for (int i = universeObject.Children.Count - 1; i >= 0; i--)
Remove(universeObject.Children[i]); Remove(universeObject.Children[i]);

View File

@ -6,14 +6,14 @@ namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")] [System.Diagnostics.DebuggerDisplay("Name: {Name}, Initialized: {Initialized}")]
public class UniverseObject : BaseEntity, IUniverseObject public class UniverseObject : BaseEntity, IUniverseObject
{ {
public event IUniverseObject.EnteredUniverseEventHandler? OnEnteredUniverse = null; public Event<IUniverseObject, IUniverse> OnEnteredUniverse { get; private set; } = new();
public event IUniverseObject.ExitedUniverseEventHandler? OnExitedUniverse = null; public Event<IUniverseObject, IUniverse> OnExitedUniverse { get; private set; } = new();
public event IUniverseObject.ParentChangedEventHandler? OnParentChanged = null; public Event<IUniverseObject, IUniverseObject?, IUniverseObject?> OnParentChanged { get; private set; } = new();
public event IUniverseObject.ChildrenAddedEventHandler? OnChildrenAdded = null; public Event<IUniverseObject, IUniverseObject> OnChildrenAdded { get; private set; } = new();
public event IUniverseObject.ChildrenRemovedEventHandler? OnChildrenRemoved = null; public Event<IUniverseObject, IUniverseObject> OnChildrenRemoved { get; private set; } = new();
public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; public Event<IActive, bool> OnActiveChanged { get; private set; } = new();
public event INameable.NameChangedEventHandler? OnNameChanged = null; public Event<INameable, string> OnNameChanged { get; private set; } = new();
public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; public Event<IHasBehaviourController> OnBehaviourControllerAssigned { get; private set; } = new();
private string _name = nameof(UniverseObject); private string _name = nameof(UniverseObject);
private IUniverse _universe = null!; private IUniverse _universe = null!;
@ -78,7 +78,7 @@ public class UniverseObject : BaseEntity, IUniverseObject
if (previousParent is not null) if (previousParent is not null)
{ {
previousParent.RemoveChild(this); previousParent.RemoveChild(this);
previousParent.OnActiveChanged -= OnParentActiveChanged; previousParent.OnActiveChanged.RemoveListener(OnParentActiveChanged);
} }
Parent = parent; Parent = parent;
@ -89,7 +89,7 @@ public class UniverseObject : BaseEntity, IUniverseObject
parent.Universe.Register(this); parent.Universe.Register(this);
parent.AddChild(this); parent.AddChild(this);
parent.OnActiveChanged += OnParentActiveChanged; parent.OnActiveChanged.AddListener(OnParentActiveChanged);
} }
UpdateActive(); UpdateActive();
@ -131,7 +131,7 @@ public class UniverseObject : BaseEntity, IUniverseObject
{ {
base.OnAssign(stateEnable); base.OnAssign(stateEnable);
stateEnable.OnEnabledChanged += OnStateEnabledChanged; stateEnable.OnEnabledChanged.AddListener(OnStateEnabledChanged);
} }
private void OnParentActiveChanged(IActive sender, bool previousState) => UpdateActive(); private void OnParentActiveChanged(IActive sender, bool previousState) => UpdateActive();
@ -149,7 +149,7 @@ public class UniverseObject : BaseEntity, IUniverseObject
protected override void UnassignInternal() protected override void UnassignInternal()
{ {
base.UnassignInternal(); base.UnassignInternal();
StateEnable.OnEnabledChanged -= OnStateEnabledChanged; StateEnable.OnEnabledChanged.RemoveListener(OnStateEnabledChanged);
} }
protected override void InitializeInternal() protected override void InitializeInternal()

View File

@ -10,17 +10,17 @@ public interface ICollider2D : IBehaviour
/// <summary> /// <summary>
/// Event triggered when a collision is detected. /// Event triggered when a collision is detected.
/// </summary> /// </summary>
event CollisionDetectedEventHandler? OnCollisionDetected; Event<ICollider2D, CollisionDetectionInformation> OnCollisionDetected { get; }
/// <summary> /// <summary>
/// Event triggered when a collision is resolved. /// Event triggered when a collision is resolved.
/// </summary> /// </summary>
event CollisionResolvedEventHandler? OnCollisionResolved; Event<ICollider2D, CollisionDetectionInformation> OnCollisionResolved { get; }
/// <summary> /// <summary>
/// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>. /// Event triggered when another <see cref="ICollider2D"/> triggers this <see cref="ICollider2D"/>.
/// </summary> /// </summary>
event TriggeredEventHandler? OnTriggered; Event<ICollider2D, ICollider2D> OnTriggered { get; }
/// <inheritdoc cref="ITransform2D" /> /// <inheritdoc cref="ITransform2D" />
ITransform2D Transform { get; } ITransform2D Transform { get; }

View File

@ -1,3 +1,5 @@
using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
/// <summary> /// <summary>
@ -8,12 +10,12 @@ public interface IPhysicsEngine2D
/// <summary> /// <summary>
/// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a single physics iteration. /// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a single physics iteration.
/// </summary> /// </summary>
event PhysicsIterationEventHandler? OnPhysicsIteration; Event<IPhysicsEngine2D, float> OnPhysicsIteration { get; }
/// <summary> /// <summary>
/// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a full physics step/>. /// Event triggered when the <see cref="IPhysicsEngine2D"/> has done a full physics step/>.
/// </summary> /// </summary>
event PhysicsStepEventHandler? OnPhysicsStep; Event<IPhysicsEngine2D, float> OnPhysicsStep { get; }
/// <summary> /// <summary>
/// The number of iterations the <see cref="IPhysicsEngine2D"/> performs per step. /// The number of iterations the <see cref="IPhysicsEngine2D"/> performs per step.

View File

@ -4,9 +4,9 @@ namespace Syntriax.Engine.Physics2D;
public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
{ {
public event ICollider2D.CollisionDetectedEventHandler? OnCollisionDetected = null; public Event<ICollider2D, CollisionDetectionInformation> OnCollisionDetected { get; private set; } = new();
public event ICollider2D.CollisionResolvedEventHandler? OnCollisionResolved = null; public Event<ICollider2D, CollisionDetectionInformation> OnCollisionResolved { get; private set; } = new();
public event ICollider2D.TriggeredEventHandler? OnTriggered = null; public Event<ICollider2D, ICollider2D> OnTriggered { get; private set; } = new();
protected bool NeedsRecalculation { get; set; } = true; protected bool NeedsRecalculation { get; set; } = true;
protected IRigidBody2D? _rigidBody2D = null; protected IRigidBody2D? _rigidBody2D = null;
@ -29,13 +29,13 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
{ {
BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController; BehaviourController.OnBehaviourAdded.AddListener(OnBehaviourAddedToController);
BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController; BehaviourController.OnBehaviourRemoved.AddListener(OnBehaviourRemovedFromController);
Transform.OnPositionChanged += SetNeedsRecalculationFromPosition; Transform.OnPositionChanged.AddListener(SetNeedsRecalculationFromPosition);
Transform.OnRotationChanged += SetNeedsRecalculationFromRotation; Transform.OnRotationChanged.AddListener(SetNeedsRecalculationFromRotation);
Transform.OnScaleChanged += SetNeedsRecalculationFromScale; Transform.OnScaleChanged.AddListener(SetNeedsRecalculationFromScale);
UniverseObject.OnParentChanged += UpdateRigidBody2D; UniverseObject.OnParentChanged.AddListener(UpdateRigidBody2D);
} }
private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent) private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent)
@ -61,12 +61,12 @@ public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D
protected override void OnFinalize() protected override void OnFinalize()
{ {
BehaviourController.OnBehaviourAdded -= OnBehaviourAddedToController; BehaviourController.OnBehaviourAdded.RemoveListener(OnBehaviourAddedToController);
BehaviourController.OnBehaviourRemoved -= OnBehaviourRemovedFromController; BehaviourController.OnBehaviourRemoved.RemoveListener(OnBehaviourRemovedFromController);
Transform.OnScaleChanged -= SetNeedsRecalculationFromScale; Transform.OnScaleChanged.RemoveListener(SetNeedsRecalculationFromScale);
Transform.OnPositionChanged -= SetNeedsRecalculationFromPosition; Transform.OnPositionChanged.RemoveListener(SetNeedsRecalculationFromPosition);
Transform.OnRotationChanged -= SetNeedsRecalculationFromRotation; Transform.OnRotationChanged.RemoveListener(SetNeedsRecalculationFromRotation);
} }
public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation);

View File

@ -25,9 +25,9 @@ public class PhysicsCoroutineManager : UniverseObject
{ {
physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>(); physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; foundPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep);
else else
universe.OnUpdate += OnUpdate; universe.OnUpdate.AddListener(OnUpdate);
} }
private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime) private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime)
@ -45,8 +45,8 @@ public class PhysicsCoroutineManager : UniverseObject
protected override void OnExitingUniverse(IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
{ {
if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine) if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine)
existingPhysicsEngine.OnPhysicsStep -= OnPhysicsStep; existingPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep);
universe.OnUpdate -= OnUpdate; universe.OnUpdate.RemoveListener(OnUpdate);
} }
private void OnUpdate(IUniverse sender, UniverseTime engineTime) private void OnUpdate(IUniverse sender, UniverseTime engineTime)
@ -57,8 +57,8 @@ public class PhysicsCoroutineManager : UniverseObject
physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>(); physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine) if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
{ {
foundPhysicsEngine.OnPhysicsStep += OnPhysicsStep; foundPhysicsEngine.OnPhysicsStep.AddListener(OnPhysicsStep);
universe.OnUpdate -= OnUpdate; universe.OnUpdate.RemoveListener(OnUpdate);
} }
} }
} }

View File

@ -4,8 +4,8 @@ namespace Syntriax.Engine.Physics2D;
public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D
{ {
public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; public Event<IPhysicsEngine2D, float> OnPhysicsIteration { get; private set; } = new();
public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; public Event<IPhysicsEngine2D, float> OnPhysicsStep { get; private set; } = new();
private float physicsTicker = 0f; private float physicsTicker = 0f;
private int _iterationPerStep = 1; private int _iterationPerStep = 1;
@ -178,7 +178,7 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D
colliderCollector.Assign(universe); colliderCollector.Assign(universe);
rigidBodyCollector.Assign(universe); rigidBodyCollector.Assign(universe);
universe.OnPreUpdate += OnEnginePreUpdate; universe.OnPreUpdate.AddListener(OnEnginePreUpdate);
} }
protected override void OnExitingUniverse(IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
@ -189,7 +189,7 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D
colliderCollector.Unassign(); colliderCollector.Unassign();
rigidBodyCollector.Unassign(); rigidBodyCollector.Unassign();
universe.OnPreUpdate -= OnEnginePreUpdate; universe.OnPreUpdate.RemoveListener(OnEnginePreUpdate);
} }
private void OnEnginePreUpdate(IUniverse sender, UniverseTime engineTime) private void OnEnginePreUpdate(IUniverse sender, UniverseTime engineTime)

View File

@ -6,8 +6,8 @@ namespace Syntriax.Engine.Physics2D;
public class PhysicsEngine2DStandalone : IPhysicsEngine2D public class PhysicsEngine2DStandalone : IPhysicsEngine2D
{ {
public event IPhysicsEngine2D.PhysicsIterationEventHandler? OnPhysicsIteration = null; public Event<IPhysicsEngine2D, float> OnPhysicsIteration { get; private set; } = new();
public event IPhysicsEngine2D.PhysicsStepEventHandler? OnPhysicsStep = null; public Event<IPhysicsEngine2D, float> OnPhysicsStep { get; private set; } = new();
private readonly List<IRigidBody2D> rigidBodies = new(32); private readonly List<IRigidBody2D> rigidBodies = new(32);
private readonly List<ICollider2D> colliders = new(64); private readonly List<ICollider2D> colliders = new(64);
@ -29,13 +29,16 @@ public class PhysicsEngine2DStandalone : IPhysicsEngine2D
foreach (ICollider2D collider2D in rigidBody.BehaviourController.GetBehaviours<ICollider2D>()) foreach (ICollider2D collider2D in rigidBody.BehaviourController.GetBehaviours<ICollider2D>())
colliders.Add(collider2D); colliders.Add(collider2D);
rigidBody.BehaviourController.OnBehaviourAdded += OnBehaviourAdded; rigidBody.BehaviourController.OnBehaviourAdded.AddListener(OnBehaviourAdded);
rigidBody.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved; rigidBody.BehaviourController.OnBehaviourRemoved.AddListener(OnBehaviourRemoved);
} }
public void RemoveRigidBody(IRigidBody2D rigidBody) public void RemoveRigidBody(IRigidBody2D rigidBody)
{ {
rigidBodies.Remove(rigidBody); rigidBodies.Remove(rigidBody);
rigidBody.BehaviourController.OnBehaviourAdded.RemoveListener(OnBehaviourAdded);
rigidBody.BehaviourController.OnBehaviourRemoved.RemoveListener(OnBehaviourRemoved);
} }
public void Step(float deltaTime) public void Step(float deltaTime)

View File

@ -10,7 +10,7 @@ public class State : BaseEntity, IState
public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null; public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null;
public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null; public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null;
public event IState.StateTransitionReadyEventHandler? OnStateTransitionReady = null; public event IState.StateTransitionReadyEventHandler? OnStateTransitionReady = null;
public event INameable.NameChangedEventHandler? OnNameChanged = null; public Event<INameable, string> OnNameChanged { get; private set; } = new();
private readonly List<StateTransition> transitions = []; private readonly List<StateTransition> transitions = [];
private readonly Dictionary<string, StateTransition> possibleTransitions = []; private readonly Dictionary<string, StateTransition> possibleTransitions = [];

View File

@ -7,7 +7,8 @@ public abstract class StateBehaviourBase : Behaviour, IState
public event IState.StateUpdateEventHandler? OnStateUpdate = null; public event IState.StateUpdateEventHandler? OnStateUpdate = null;
public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null; public event IState.StateTransitionedFromEventHandler? OnStateTransitionedFrom = null;
public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null; public event IState.StateTransitionedToEventHandler? OnStateTransitionedTo = null;
public event INameable.NameChangedEventHandler? OnNameChanged = null;
public Event<INameable, string> OnNameChanged { get; private set; } = new();
public abstract event IState.StateTransitionReadyEventHandler? OnStateTransitionReady; public abstract event IState.StateTransitionReadyEventHandler? OnStateTransitionReady;