65 lines
2.9 KiB
C#
65 lines
2.9 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace Engine.Core;
|
|
|
|
public class UniverseEntranceManager : Internal.BehaviourIndependent
|
|
{
|
|
// We use Ascending order because we are using reverse for loop to call them
|
|
private static Comparer<int> SortByAscendingPriority() => Comparer<int>.Create((x, y) => x.CompareTo(y));
|
|
private static System.Func<IBehaviour, int> GetPriority() => (b) => b.Priority;
|
|
|
|
private readonly ActiveBehaviourCollectorOrdered<int, IEnterUniverse> enterUniverses = new(GetPriority(), SortByAscendingPriority());
|
|
private readonly ActiveBehaviourCollectorOrdered<int, IExitUniverse> exitUniverses = new(GetPriority(), SortByAscendingPriority());
|
|
|
|
private bool isInitialCollectionDone = false;
|
|
private readonly FastListOrdered<int, IEnterUniverse> toCallEnterUniverses = new(GetPriority(), SortByAscendingPriority());
|
|
|
|
protected override void OnEnteredUniverse(IUniverse universe)
|
|
{
|
|
exitUniverses.Assign(universe);
|
|
|
|
// FIXME: the isInitialCollectionDone is for the sole reason of some behaviours
|
|
// adding more behaviours during entrance calls and the internal workings of
|
|
// behaviour collector not being able to tell which behaviour was already called
|
|
// (because it just runs a for loop with the behaviour count, and priority ordering doesn't help as well)
|
|
// so it sometimes double processes or misses behaviours. A more elegant way of
|
|
// handling this would be nice but for now it works good enough.
|
|
//
|
|
// SIDE NOTE: This same issue has the potential to occur on exitUniverses as well, but I've yet to run
|
|
// into an instance of it actually happening so... I'm not gonna touch it until the edge case happens.
|
|
isInitialCollectionDone = false;
|
|
enterUniverses.Assign(universe);
|
|
isInitialCollectionDone = true;
|
|
|
|
for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--)
|
|
toCallEnterUniverses[i].EnterUniverse(universe);
|
|
toCallEnterUniverses.Clear();
|
|
}
|
|
|
|
protected override void OnExitedUniverse(IUniverse universe)
|
|
{
|
|
enterUniverses.Unassign();
|
|
exitUniverses.Unassign();
|
|
}
|
|
|
|
private void OnEnterUniverseCollected(IBehaviourCollector<IEnterUniverse> sender, IBehaviourCollector<IEnterUniverse>.BehaviourCollectedArguments args)
|
|
{
|
|
if (!isInitialCollectionDone)
|
|
{
|
|
toCallEnterUniverses.Add(args.BehaviourCollected);
|
|
return;
|
|
}
|
|
|
|
args.BehaviourCollected.EnterUniverse(Universe);
|
|
}
|
|
|
|
private void OnExitUniverseRemoved(IBehaviourCollector<IExitUniverse> sender, IBehaviourCollector<IExitUniverse>.BehaviourRemovedArguments args)
|
|
=> args.BehaviourRemoved.ExitUniverse(Universe);
|
|
|
|
public UniverseEntranceManager()
|
|
{
|
|
enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected);
|
|
exitUniverses.OnRemoved.AddListener(OnExitUniverseRemoved);
|
|
}
|
|
}
|