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 SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); private static System.Func GetPriority() => (b) => b.Priority; private readonly ActiveBehaviourCollectorOrdered enterUniverses = new(GetPriority(), SortByAscendingPriority()); private readonly ActiveBehaviourCollectorOrdered exitUniverses = new(GetPriority(), SortByAscendingPriority()); protected override void OnEnteredUniverse(IUniverse universe) { // FIXME: This causes an issue when the UniverseEntranceManager is already attached to a UniverseObject then registered into a Universe, // the enter/exit universe collectors call OnUniverseObjectRegistered internally on Assign, but since the Universe calls the OnUniverseObjectRegistered // event it tries to call OnUniverseObjectRegistered again on the same object, causing a duplicate entry error. Debug.Assert.AssertTrue(BehaviourController.Count == 1, $"{nameof(UniverseEntranceManager)} must be in it's own {nameof(IUniverseObject)} with no other {nameof(IBehaviour)}s attached at the moment. Failing to do so might cause instantiation or serialization issues."); enterUniverses.Assign(universe); exitUniverses.Assign(universe); } protected override void OnExitedUniverse(IUniverse universe) { enterUniverses.Unassign(); exitUniverses.Unassign(); } private void OnEnterUniverseCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) => args.BehaviourCollected.EnterUniverse(Universe); private void OnExitUniverseRemoved(IBehaviourCollector sender, IBehaviourCollector.BehaviourRemovedArguments args) => args.BehaviourRemoved.ExitUniverse(Universe); public UniverseEntranceManager() { enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected); exitUniverses.OnRemoved.AddListener(OnExitUniverseRemoved); } }