Syntriax.Engine/Engine.Core/BehaviourCollector.cs

107 lines
3.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core;
public class BehaviourCollector<T> : IAssignableGameManager, IEnumerable<T>
{
public event IAssignable.OnUnassignedDelegate? OnUnassigned = null;
public event IAssignableGameManager.OnGameManagerAssignedDelegate? OnGameManagerAssigned = null;
public event OnCollectedDelegate? OnCollected = null;
public event OnRemovedDelegate? OnRemoved = null;
private readonly List<T> _behaviours = new(32);
public IReadOnlyList<T> Behaviours => _behaviours;
public IGameManager GameManager { get; private set; } = null!;
public T this[Index index] => _behaviours[index];
public BehaviourCollector() { }
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager);
private void OnGameObjectRegistered(IGameManager manager, IGameObject gameObject)
{
gameObject.BehaviourController.OnBehaviourAdded += OnBehaviourAdded;
gameObject.BehaviourController.OnBehaviourRemoved += OnBehaviourRemoved;
}
private void OnGameObjectUnregistered(IGameManager manager, IGameObject gameObject)
{
gameObject.BehaviourController.OnBehaviourAdded -= OnBehaviourAdded;
gameObject.BehaviourController.OnBehaviourRemoved -= OnBehaviourRemoved;
}
private void OnBehaviourAdded(IBehaviourController controller, IBehaviour behaviour)
{
if (behaviour is not T tBehaviour)
return;
_behaviours.Add(tBehaviour);
OnCollected?.Invoke(this, tBehaviour);
}
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
{
if (behaviour is not T tBehaviour)
return;
if (!_behaviours.Remove(tBehaviour))
return;
OnRemoved?.Invoke(this, tBehaviour);
}
public bool Assign(IGameManager gameManager)
{
if (GameManager is not null)
return false;
foreach (IGameObject gameObject in gameManager)
{
OnGameObjectRegistered(gameManager, gameObject);
foreach (IBehaviour behaviour in gameObject.BehaviourController)
OnBehaviourAdded(gameObject.BehaviourController, behaviour);
}
gameManager.OnGameObjectRegistered += OnGameObjectRegistered;
gameManager.OnGameObjectUnRegistered += OnGameObjectUnregistered;
GameManager = gameManager;
OnGameManagerAssigned?.Invoke(this);
return true;
}
public bool Unassign()
{
if (GameManager is null)
return false;
foreach (IGameObject gameObject in GameManager)
{
OnGameObjectUnregistered(GameManager, gameObject);
foreach (IBehaviour behaviour in gameObject.BehaviourController)
OnBehaviourRemoved(gameObject.BehaviourController, behaviour);
}
GameManager.OnGameObjectRegistered -= OnGameObjectRegistered;
GameManager.OnGameObjectUnRegistered -= OnGameObjectUnregistered;
GameManager = null!;
OnUnassigned?.Invoke(this);
return true;
}
public IEnumerator<T> GetEnumerator() => _behaviours.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _behaviours.GetEnumerator();
public delegate void OnCollectedDelegate(BehaviourCollector<T> sender, T behaviourCollected);
public delegate void OnRemovedDelegate(BehaviourCollector<T> sender, T behaviourRemoved);
}