2024-01-30 19:21:45 +03:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
using Syntriax.Engine.Core.Abstract;
|
|
|
|
|
|
|
|
namespace Syntriax.Engine.Core;
|
|
|
|
|
2024-02-09 09:43:15 +03:00
|
|
|
public class BehaviourCollector<T> : IAssignableGameManager, IEnumerable<T>
|
2024-01-30 19:21:45 +03:00
|
|
|
{
|
|
|
|
public Action<IAssignable>? OnUnassigned { get; set; } = null;
|
|
|
|
public Action<IAssignableGameManager>? OnGameManagerAssigned { get; set; } = null;
|
|
|
|
|
2024-02-09 09:43:15 +03:00
|
|
|
public Action<BehaviourCollector<T>, T>? OnCollected { get; set; } = null;
|
|
|
|
public Action<BehaviourCollector<T>, T>? OnRemoved { get; set; } = null;
|
2024-01-30 19:21:45 +03:00
|
|
|
|
|
|
|
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];
|
|
|
|
|
2024-02-09 09:43:15 +03:00
|
|
|
public BehaviourCollector() { }
|
|
|
|
public BehaviourCollector(IGameManager gameManager) => Assign(gameManager);
|
2024-01-30 19:21:45 +03:00
|
|
|
|
|
|
|
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);
|
2024-02-09 09:43:15 +03:00
|
|
|
OnCollected?.Invoke(this, tBehaviour);
|
2024-01-30 19:21:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour)
|
|
|
|
{
|
|
|
|
if (behaviour is not T tBehaviour)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!_behaviours.Remove(tBehaviour))
|
|
|
|
return;
|
|
|
|
|
2024-02-09 09:43:15 +03:00
|
|
|
OnRemoved?.Invoke(this, tBehaviour);
|
2024-01-30 19:21:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|