81 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			3.8 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 readonly List<IEnterUniverse> toCallEnterUniverses = new(32);
 | 
						|
    private readonly List<IExitUniverse> toCallExitUniverses = new(32);
 | 
						|
 | 
						|
    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);
 | 
						|
 | 
						|
        foreach (IUniverseObject universeObject in universe)
 | 
						|
            OnUniverseObjectRegistered(universe, new(universeObject));
 | 
						|
 | 
						|
        universe.OnUniverseObjectRegistered.AddListener(OnUniverseObjectRegistered);
 | 
						|
        universe.OnUniverseObjectUnRegistered.AddListener(OnUniverseObjectUnRegistered);
 | 
						|
    }
 | 
						|
 | 
						|
    protected override void OnExitedUniverse(IUniverse universe)
 | 
						|
    {
 | 
						|
        enterUniverses.Unassign();
 | 
						|
        exitUniverses.Unassign();
 | 
						|
 | 
						|
        foreach (IUniverseObject universeObject in universe)
 | 
						|
            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--)
 | 
						|
        {
 | 
						|
            IExitUniverse exitUniverse = toCallExitUniverses[i];
 | 
						|
            toCallExitUniverses.RemoveAt(i);
 | 
						|
            exitUniverse.ExitUniverse(Universe);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnUniverseObjectRegistered(IUniverse sender, IUniverse.UniverseObjectRegisteredArguments args)
 | 
						|
    {
 | 
						|
        for (int i = toCallEnterUniverses.Count - 1; i >= 0; i--)
 | 
						|
        {
 | 
						|
            IEnterUniverse enterUniverse = toCallEnterUniverses[i];
 | 
						|
            toCallEnterUniverses.RemoveAt(i);
 | 
						|
            enterUniverse.EnterUniverse(Universe);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnEnterUniverseCollected(IBehaviourCollector<IEnterUniverse> sender, IBehaviourCollector<IEnterUniverse>.BehaviourCollectedArguments args)
 | 
						|
    {
 | 
						|
        toCallEnterUniverses.Add(args.BehaviourCollected);
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnExitUniverseCollected(IBehaviourCollector<IExitUniverse> sender, IBehaviourCollector<IExitUniverse>.BehaviourCollectedArguments args)
 | 
						|
    {
 | 
						|
        toCallExitUniverses.Add(args.BehaviourCollected);
 | 
						|
    }
 | 
						|
 | 
						|
    public UniverseEntranceManager()
 | 
						|
    {
 | 
						|
        enterUniverses.OnCollected.AddListener(OnEnterUniverseCollected);
 | 
						|
        exitUniverses.OnCollected.AddListener(OnExitUniverseCollected);
 | 
						|
    }
 | 
						|
}
 |