using System.Collections.Generic; namespace Engine.Core; public class UniverseEntranceManager : Behaviour { // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.Priority.CompareTo(y.Priority)); private readonly ActiveBehaviourCollectorSorted enterUniverses = new() { SortBy = SortByAscendingPriority() }; private readonly ActiveBehaviourCollectorSorted exitUniverses = new() { SortBy = SortByAscendingPriority() }; private readonly List toCallEnterUniverses = new(32); private readonly List toCallExitUniverses = new(32); protected override void OnEnteredUniverse(IUniverse universe) { enterUniverses.Assign(universe); foreach (IUniverseObject universeObject in universe.UniverseObjects) OnUniverseObjectRegistered(universe, new(universeObject)); universe.OnUniverseObjectRegistered.AddListener(OnUniverseObjectRegistered); universe.OnUniverseObjectUnRegistered.AddListener(OnUniverseObjectUnRegistered); } protected override void OnExitedUniverse(IUniverse universe) { enterUniverses.Unassign(); foreach (IUniverseObject universeObject in universe.UniverseObjects) OnUniverseObjectUnRegistered(universe, new(universeObject)); universe.OnUniverseObjectRegistered.RemoveListener(OnUniverseObjectRegistered); universe.OnUniverseObjectUnRegistered.RemoveListener(OnUniverseObjectUnRegistered); } private void OnUniverseObjectUnRegistered(IUniverse sender, IUniverse.UniverseObjectUnRegisteredArguments args) { for (int i = toCallExitUniverses.Count - 1; i >= 0; i--) { toCallExitUniverses[i].ExitUniverse(Universe); toCallExitUniverses.RemoveAt(i); } } private void OnUniverseObjectRegistered(IUniverse sender, IUniverse.UniverseObjectRegisteredArguments args) { for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--) { toCallEnterUniverses[i].EnterUniverse(Universe); toCallEnterUniverses.RemoveAt(i); } } private void OnEnterUniverseCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) { toCallEnterUniverses.Add(args.BehaviourCollected); } private void OnExitUniverseCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) { toCallExitUniverses.Add(args.BehaviourCollected); } public UniverseEntranceManager() { enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected); exitUniverses.OnCollected.AddListener(OnExitUniverseCollected); } }