4 Commits

9 changed files with 129 additions and 23 deletions

View File

@@ -56,12 +56,13 @@ public class ActiveBehaviourCollector<T> : IBehaviourCollector<T> where T : clas
OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive)); OnBehaviourStateChanged(tBehaviour, new(!tBehaviour.IsActive));
} }
protected virtual void AddBehaviour(T behaviour) => activeBehaviours.Add(behaviour);
private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args) private void OnBehaviourStateChanged(IActive sender, IActive.ActiveChangedArguments args)
{ {
T behaviour = monitoringActiveToBehaviour[sender]; T behaviour = monitoringActiveToBehaviour[sender];
if (sender.IsActive) if (sender.IsActive)
{ {
activeBehaviours.Add(behaviour); AddBehaviour(behaviour);
OnBehaviourAdd(behaviour); OnBehaviourAdd(behaviour);
OnCollected?.Invoke(this, new(behaviour)); OnCollected?.Invoke(this, new(behaviour));
} }

View File

@@ -1,11 +1,14 @@
using System; using System;
using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> where T : class, IBehaviour public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> where T : class, IBehaviour
{ {
private Comparison<T>? _sortBy = null; private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
public Comparison<T>? SortBy
private IComparer<T>? _sortBy = null;
public IComparer<T>? SortBy
{ {
get => _sortBy; get => _sortBy;
set set
@@ -17,12 +20,48 @@ public class ActiveBehaviourCollectorSorted<T> : ActiveBehaviourCollector<T> whe
} }
} }
protected override void OnBehaviourAdd(IBehaviour behaviour) protected override void AddBehaviour(T behaviour)
{ {
if (SortBy is not null) if (SortBy is null)
activeBehaviours.Sort(SortBy); {
activeBehaviours.Add(behaviour);
return;
}
int insertionIndex = activeBehaviours.BinarySearch(behaviour, SortBy);
if (insertionIndex < 0)
insertionIndex = ~insertionIndex;
activeBehaviours.Insert(insertionIndex, behaviour);
} }
public ActiveBehaviourCollectorSorted() { } protected override void OnBehaviourAdd(IBehaviour behaviour)
public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy; {
behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
}
protected override void OnBehaviourRemove(IBehaviour behaviour)
{
behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
}
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
{
T behaviour = (T)sender;
activeBehaviours.Remove(behaviour);
AddBehaviour(behaviour);
}
public ActiveBehaviourCollectorSorted()
{
delegateOnPriorityChanged = OnPriorityChanged;
}
public ActiveBehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe)
{
delegateOnPriorityChanged = OnPriorityChanged;
SortBy = Comparer<T>.Create(sortBy);
}
} }

View File

@@ -41,13 +41,14 @@ public class BehaviourCollector<T> : IBehaviourCollector<T> where T : class
OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i])); OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
} }
protected virtual void AddBehaviour(T behaviour) => behaviours.Add(behaviour);
protected virtual void OnBehaviourAdd(IBehaviour behaviour) { } protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args) private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
{ {
if (args.BehaviourAdded is not T tBehaviour) if (args.BehaviourAdded is not T tBehaviour)
return; return;
behaviours.Add(tBehaviour); AddBehaviour(tBehaviour);
OnBehaviourAdd(args.BehaviourAdded); OnBehaviourAdd(args.BehaviourAdded);
OnCollected?.Invoke(this, new(tBehaviour)); OnCollected?.Invoke(this, new(tBehaviour));
} }

View File

@@ -1,11 +1,14 @@
using System; using System;
using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
{ {
private Comparison<T>? _sortBy = null; private readonly Event<IBehaviour, IBehaviour.PriorityChangedArguments>.EventHandler delegateOnPriorityChanged = null!;
public Comparison<T>? SortBy
private IComparer<T>? _sortBy = null;
public IComparer<T>? SortBy
{ {
get => _sortBy; get => _sortBy;
set set
@@ -17,12 +20,48 @@ public class BehaviourCollectorSorted<T> : BehaviourCollector<T> where T : class
} }
} }
protected override void OnBehaviourAdd(IBehaviour behaviour) protected override void AddBehaviour(T behaviour)
{ {
if (SortBy is not null) if (SortBy is null)
behaviours.Sort(SortBy); {
behaviours.Add(behaviour);
return;
}
int insertionIndex = behaviours.BinarySearch(behaviour, SortBy);
if (insertionIndex < 0)
insertionIndex = ~insertionIndex;
behaviours.Insert(insertionIndex, behaviour);
} }
public BehaviourCollectorSorted() { } protected override void OnBehaviourAdd(IBehaviour behaviour)
public BehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe) => SortBy = sortBy; {
behaviour.OnPriorityChanged.AddListener(delegateOnPriorityChanged);
}
protected override void OnBehaviourRemove(IBehaviour behaviour)
{
behaviour.OnPriorityChanged.RemoveListener(delegateOnPriorityChanged);
}
private void OnPriorityChanged(IBehaviour sender, IBehaviour.PriorityChangedArguments args)
{
T behaviour = (T)sender;
behaviours.Remove(behaviour);
AddBehaviour(behaviour);
}
public BehaviourCollectorSorted()
{
delegateOnPriorityChanged = OnPriorityChanged;
}
public BehaviourCollectorSorted(IUniverse universe, Comparison<T> sortBy) : base(universe)
{
delegateOnPriorityChanged = OnPriorityChanged;
SortBy = Comparer<T>.Create(sortBy);
}
} }

View File

@@ -3,6 +3,27 @@ using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class Event
{
private readonly List<EventHandler> 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()
{
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 delegate void EventHandler();
}
public class Event<TSender> public class Event<TSender>
{ {
private readonly List<EventHandler> listeners = new(8); private readonly List<EventHandler> listeners = new(8);

View File

@@ -1,8 +1,10 @@
using System.Collections.Generic;
namespace Syntriax.Engine.Core; namespace Syntriax.Engine.Core;
public class DrawManager : UniverseObject public class DrawManager : UniverseObject
{ {
private static System.Comparison<IBehaviour> SortByPriority() => (x, y) => y.Priority.CompareTo(x.Priority); private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
private readonly ActiveBehaviourCollectorSorted<IPreDraw> preDrawEntities = new() { SortBy = SortByPriority() }; private readonly ActiveBehaviourCollectorSorted<IPreDraw> preDrawEntities = new() { SortBy = SortByPriority() };
private readonly ActiveBehaviourCollectorSorted<IDraw> drawEntities = new() { SortBy = SortByPriority() }; private readonly ActiveBehaviourCollectorSorted<IDraw> drawEntities = new() { SortBy = SortByPriority() };

View File

@@ -4,7 +4,7 @@ namespace Syntriax.Engine.Core;
public class UpdateManager : UniverseObject public class UpdateManager : UniverseObject
{ {
private static System.Comparison<IBehaviour> SortByPriority() => (x, y) => y.Priority.CompareTo(x.Priority); private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
private readonly ActiveBehaviourCollectorSorted<IFirstFrameUpdate> firstFrameUpdates = new() { SortBy = SortByPriority() }; private readonly ActiveBehaviourCollectorSorted<IFirstFrameUpdate> firstFrameUpdates = new() { SortBy = SortByPriority() };
private readonly ActiveBehaviourCollectorSorted<IPreUpdate> preUpdateEntities = new() { SortBy = SortByPriority() }; private readonly ActiveBehaviourCollectorSorted<IPreUpdate> preUpdateEntities = new() { SortBy = SortByPriority() };

View File

@@ -1,3 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
@@ -16,7 +18,7 @@ public class PhysicsEngine2D : UniverseObject, IPhysicsEngine2D
protected readonly ICollisionDetector2D collisionDetector = null!; protected readonly ICollisionDetector2D collisionDetector = null!;
protected readonly ICollisionResolver2D collisionResolver = null!; protected readonly ICollisionResolver2D collisionResolver = null!;
private static System.Comparison<IBehaviour> SortByPriority() => (x, y) => y.Priority.CompareTo(x.Priority); private static Comparer<IBehaviour> SortByPriority() => Comparer<IBehaviour>.Create((x, y) => y.Priority.CompareTo(x.Priority));
protected ActiveBehaviourCollectorSorted<IPrePhysicsUpdate> physicsPreUpdateCollector = new() { SortBy = SortByPriority() }; protected ActiveBehaviourCollectorSorted<IPrePhysicsUpdate> physicsPreUpdateCollector = new() { SortBy = SortByPriority() };
protected ActiveBehaviourCollectorSorted<IPhysicsUpdate> physicsUpdateCollector = new() { SortBy = SortByPriority() }; protected ActiveBehaviourCollectorSorted<IPhysicsUpdate> physicsUpdateCollector = new() { SortBy = SortByPriority() };
protected ActiveBehaviourCollectorSorted<IPostPhysicsUpdate> physicsPostUpdateCollector = new() { SortBy = SortByPriority() }; protected ActiveBehaviourCollectorSorted<IPostPhysicsUpdate> physicsPostUpdateCollector = new() { SortBy = SortByPriority() };

View File

@@ -8,9 +8,9 @@ namespace Syntriax.Engine.Systems.Tween;
public class TweenManager : UniverseObject, ITweenManager public class TweenManager : UniverseObject, ITweenManager
{ {
private CoroutineManager coroutineManager = null!; private CoroutineManager coroutineManager = null!;
private readonly Queue<Tween> queue = new();
private readonly Dictionary<ITween, IEnumerator> runningCoroutines = []; private readonly Dictionary<ITween, IEnumerator> runningCoroutines = [];
private readonly Queue<Tween> pool = new();
public ITween StartTween(float duration, ITweenManager.TweenSetCallback? setCallback = null) public ITween StartTween(float duration, ITweenManager.TweenSetCallback? setCallback = null)
{ {
@@ -22,7 +22,7 @@ public class TweenManager : UniverseObject, ITweenManager
private Tween Get(float duration) private Tween Get(float duration)
{ {
if (!queue.TryDequeue(out Tween? result)) if (!pool.TryDequeue(out Tween? result))
result = new(duration); result = new(duration);
result.Duration = duration; result.Duration = duration;
@@ -31,11 +31,11 @@ public class TweenManager : UniverseObject, ITweenManager
private void Return(Tween tween) private void Return(Tween tween)
{ {
if (queue.Contains(tween)) if (pool.Contains(tween))
return; return;
tween.Wipe(); tween.Wipe();
queue.Enqueue(tween); pool.Enqueue(tween);
} }
private IEnumerator RunTween(Tween tween) private IEnumerator RunTween(Tween tween)
@@ -70,6 +70,7 @@ public class TweenManager : UniverseObject, ITweenManager
tween.State = TweenState.Cancelled; tween.State = TweenState.Cancelled;
coroutineManager.StopCoroutine(runningCoroutine); coroutineManager.StopCoroutine(runningCoroutine);
runningCoroutines.Remove(tween); runningCoroutines.Remove(tween);
Return((Tween)tween);
} }
protected override void OnEnteringUniverse(IUniverse universe) protected override void OnEnteringUniverse(IUniverse universe)