From 005c78a26e52dc905299bb66ba9bff49039ec02a Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 30 Jan 2024 19:21:45 +0300 Subject: [PATCH] feat: BehaviourCacher --- Engine.Core/BehaviourCacher.cs | 102 +++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Engine.Core/BehaviourCacher.cs diff --git a/Engine.Core/BehaviourCacher.cs b/Engine.Core/BehaviourCacher.cs new file mode 100644 index 0000000..57b6ba4 --- /dev/null +++ b/Engine.Core/BehaviourCacher.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using Syntriax.Engine.Core.Abstract; + +namespace Syntriax.Engine.Core; + +public class BehaviourCacher : IAssignableGameManager, IEnumerable +{ + public Action? OnUnassigned { get; set; } = null; + public Action? OnGameManagerAssigned { get; set; } = null; + + public Action, T>? OnCached { get; set; } = null; + public Action, T>? OnUncached { get; set; } = null; + + private readonly List _behaviours = new(32); + + public IReadOnlyList Behaviours => _behaviours; + public IGameManager GameManager { get; private set; } = null!; + + public T this[Index index] => _behaviours[index]; + + public BehaviourCacher() { } + public BehaviourCacher(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); + OnCached?.Invoke(this, tBehaviour); + } + + private void OnBehaviourRemoved(IBehaviourController controller, IBehaviour behaviour) + { + if (behaviour is not T tBehaviour) + return; + + if (!_behaviours.Remove(tBehaviour)) + return; + + OnUncached?.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 GetEnumerator() => _behaviours.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _behaviours.GetEnumerator(); +}