125 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
 | 
						|
namespace Engine.Core;
 | 
						|
 | 
						|
public abstract class BehaviourCollectorBase<T> : IBehaviourCollector<T> where T : class
 | 
						|
{
 | 
						|
    private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAdded = null!;
 | 
						|
    private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemoved = null!;
 | 
						|
    private readonly Event<IUniverse, IUniverse.UniverseObjectRegisteredArguments>.EventHandler delegateOnUniverseObjectRegistered = null!;
 | 
						|
    private readonly Event<IUniverse, IUniverse.UniverseObjectUnRegisteredArguments>.EventHandler delegateOnUniverseObjectUnregistered = null!;
 | 
						|
 | 
						|
    public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourCollectedArguments> OnCollected { get; } = new();
 | 
						|
    public Event<IBehaviourCollector<T>, IBehaviourCollector<T>.BehaviourRemovedArguments> OnRemoved { get; } = new();
 | 
						|
    public Event<IHasUniverse> OnUniverseAssigned { get; } = new();
 | 
						|
    public Event<IAssignable>? OnUnassigned { get; } = new();
 | 
						|
 | 
						|
    public IUniverse Universe { get; private set; } = null!;
 | 
						|
 | 
						|
    public abstract int Count { get; }
 | 
						|
 | 
						|
    public abstract T this[Index index] { get; }
 | 
						|
 | 
						|
    public bool Assign(IUniverse universe)
 | 
						|
    {
 | 
						|
        if (Universe is not null)
 | 
						|
            return false;
 | 
						|
 | 
						|
        foreach (IUniverseObject universeObject in universe.UniverseObjects)
 | 
						|
            OnUniverseObjectRegistered(universe, new(universeObject));
 | 
						|
 | 
						|
        universe.OnUniverseObjectRegistered.AddListener(delegateOnUniverseObjectRegistered);
 | 
						|
        universe.OnPreUniverseObjectUnRegistered.AddListener(delegateOnUniverseObjectUnregistered);
 | 
						|
 | 
						|
        Universe = universe;
 | 
						|
        OnAssign(universe);
 | 
						|
        OnUniverseAssigned?.Invoke(this);
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    public bool Unassign()
 | 
						|
    {
 | 
						|
        if (Universe is null)
 | 
						|
            return false;
 | 
						|
 | 
						|
        foreach (IUniverseObject universeObject in Universe.UniverseObjects)
 | 
						|
            OnUniverseObjectUnregistered(Universe, new(universeObject));
 | 
						|
 | 
						|
        Universe.OnUniverseObjectRegistered.RemoveListener(delegateOnUniverseObjectRegistered);
 | 
						|
        Universe.OnPreUniverseObjectUnRegistered.RemoveListener(delegateOnUniverseObjectUnregistered);
 | 
						|
 | 
						|
        Universe = null!;
 | 
						|
        OnUnassigned?.Invoke(this);
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    protected virtual void OnAssign(IUniverse universe) { }
 | 
						|
 | 
						|
    protected abstract void AddBehaviour(T behaviour);
 | 
						|
    protected virtual void OnBehaviourAdd(IBehaviour behaviour) { }
 | 
						|
    private void OnBehaviourAdded(IBehaviourController controller, IBehaviourController.BehaviourAddedArguments args)
 | 
						|
    {
 | 
						|
        if (args.BehaviourAdded is not T tBehaviour)
 | 
						|
            return;
 | 
						|
 | 
						|
        AddBehaviour(tBehaviour);
 | 
						|
        OnBehaviourAdd(args.BehaviourAdded);
 | 
						|
        OnCollected?.Invoke(this, new(tBehaviour));
 | 
						|
    }
 | 
						|
 | 
						|
    protected abstract bool RemoveBehaviour(T tBehaviour);
 | 
						|
    protected virtual void OnBehaviourRemove(IBehaviour behaviour) { }
 | 
						|
    private void OnBehaviourRemoved(IBehaviourController controller, IBehaviourController.BehaviourRemovedArguments args)
 | 
						|
    {
 | 
						|
        if (args.BehaviourRemoved is not T tBehaviour)
 | 
						|
            return;
 | 
						|
 | 
						|
        if (!RemoveBehaviour(tBehaviour))
 | 
						|
            return;
 | 
						|
 | 
						|
        OnBehaviourRemove(args.BehaviourRemoved);
 | 
						|
        OnRemoved?.Invoke(this, new(tBehaviour));
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnUniverseObjectRegistered(IUniverse manager, IUniverse.UniverseObjectRegisteredArguments args)
 | 
						|
    {
 | 
						|
        IUniverseObject universeObject = args.UniverseObjectRegistered;
 | 
						|
 | 
						|
        universeObject.BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAdded);
 | 
						|
        universeObject.BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemoved);
 | 
						|
 | 
						|
        for (int i = 0; i < universeObject.BehaviourController.Count; i++)
 | 
						|
            OnBehaviourAdded(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnUniverseObjectUnregistered(IUniverse manager, IUniverse.UniverseObjectUnRegisteredArguments args)
 | 
						|
    {
 | 
						|
        IUniverseObject universeObject = args.UniverseObjectUnregistered;
 | 
						|
 | 
						|
        universeObject.BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAdded);
 | 
						|
        universeObject.BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemoved);
 | 
						|
 | 
						|
        for (int i = 0; i < universeObject.BehaviourController.Count; i++)
 | 
						|
            OnBehaviourRemoved(universeObject.BehaviourController, new(universeObject.BehaviourController[i]));
 | 
						|
    }
 | 
						|
 | 
						|
    public BehaviourCollectorBase()
 | 
						|
    {
 | 
						|
        delegateOnBehaviourAdded = OnBehaviourAdded;
 | 
						|
        delegateOnBehaviourRemoved = OnBehaviourRemoved;
 | 
						|
        delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered;
 | 
						|
        delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
 | 
						|
    }
 | 
						|
 | 
						|
    public BehaviourCollectorBase(IUniverse universe)
 | 
						|
    {
 | 
						|
        delegateOnBehaviourAdded = OnBehaviourAdded;
 | 
						|
        delegateOnBehaviourRemoved = OnBehaviourRemoved;
 | 
						|
        delegateOnUniverseObjectRegistered = OnUniverseObjectRegistered;
 | 
						|
        delegateOnUniverseObjectUnregistered = OnUniverseObjectUnregistered;
 | 
						|
 | 
						|
        Assign(universe);
 | 
						|
    }
 | 
						|
}
 |