All delegate events are refactored to use the Event<TSender> and Event<TSender, TArgument> for performance issues regarding delegate events creating garbage, also this gives us better control on event invocation since C# Delegates did also create unnecessary garbage during Delegate.DynamicInvoke
72 lines
2.1 KiB
C#
72 lines
2.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
using Syntriax.Engine.Core;
|
|
|
|
namespace Syntriax.Engine.Physics2D;
|
|
|
|
public class PhysicsCoroutineManager : UniverseObject
|
|
{
|
|
private readonly Event<IUniverse, IUniverse.UpdateArguments>.EventHandler delegateOnUpdate = null!;
|
|
|
|
private readonly List<IEnumerator> enumerators = [];
|
|
private IPhysicsEngine2D? physicsEngine = null;
|
|
|
|
public IEnumerator CreateCoroutine(IEnumerator enumerator)
|
|
{
|
|
enumerators.Add(enumerator);
|
|
return enumerator;
|
|
}
|
|
|
|
public void StopCoroutine(IEnumerator enumerator)
|
|
{
|
|
enumerators.Remove(enumerator);
|
|
}
|
|
|
|
protected override void OnEnteringUniverse(IUniverse universe)
|
|
{
|
|
physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
|
|
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
|
|
foundPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep);
|
|
else
|
|
universe.OnUpdate.AddListener(OnUpdate);
|
|
}
|
|
|
|
private void OnPhysicsStep(IPhysicsEngine2D sender, float stepDeltaTime)
|
|
{
|
|
for (int i = enumerators.Count - 1; i >= 0; i--)
|
|
{
|
|
if (enumerators[i].Current is ICoroutineYield coroutineYield && coroutineYield.Yield())
|
|
continue;
|
|
|
|
if (!enumerators[i].MoveNext())
|
|
enumerators.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
protected override void OnExitingUniverse(IUniverse universe)
|
|
{
|
|
if (physicsEngine is IPhysicsEngine2D existingPhysicsEngine)
|
|
existingPhysicsEngine.OnPhysicsStep.RemoveListener(OnPhysicsStep);
|
|
universe.OnUpdate.RemoveListener(OnUpdate);
|
|
}
|
|
|
|
private void OnUpdate(IUniverse sender, IUniverse.UpdateArguments args)
|
|
{
|
|
if (Universe is not IUniverse universe)
|
|
return;
|
|
|
|
physicsEngine = universe.GetUniverseObject<IPhysicsEngine2D>();
|
|
if (physicsEngine is IPhysicsEngine2D foundPhysicsEngine)
|
|
{
|
|
foundPhysicsEngine.OnPhysicsStep.AddListener(OnPhysicsStep);
|
|
universe.OnUpdate.RemoveListener(OnUpdate);
|
|
}
|
|
}
|
|
|
|
public PhysicsCoroutineManager()
|
|
{
|
|
delegateOnUpdate = OnUpdate;
|
|
}
|
|
}
|