using Syntriax.Engine.Core.Abstract; using Syntriax.Engine.Core.Exceptions; namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] public abstract class BehaviourBase : BaseEntity, IBehaviour { public event IHasBehaviourController.BehaviourControllerAssignedEventHandler? OnBehaviourControllerAssigned = null; public event IBehaviour.PriorityChangedEventHandler? OnPriorityChanged = null; public event IActive.ActiveChangedEventHandler? OnActiveChanged = null; private IBehaviourController _behaviourController = null!; public IBehaviourController BehaviourController => _behaviourController; private int _priority = 0; public int Priority { get => _priority; set { if (value == _priority) return; int previousPriority = _priority; _priority = value; OnPriorityChanged?.Invoke(this, previousPriority); } } public bool IsActive { get; private set; } = false; protected virtual void OnAssign(IBehaviourController behaviourController) { } public bool Assign(IBehaviourController behaviourController) { if (IsInitialized) return false; _behaviourController = behaviourController; OnAssign(behaviourController); behaviourController.OnHierarchyObjectAssigned += OnHierarchyObjectAssigned; if (behaviourController.HierarchyObject is not null) OnHierarchyObjectAssigned(behaviourController); OnBehaviourControllerAssigned?.Invoke(this); return true; } private void OnHierarchyObjectAssigned(IHasHierarchyObject sender) { sender.HierarchyObject.OnActiveChanged += OnHierarchyObjectActiveChanged; UpdateActive(); } protected override void OnAssign(IStateEnable stateEnable) { base.OnAssign(stateEnable); stateEnable.OnEnabledChanged += OnStateEnabledChanged; } protected override void UnassignInternal() { StateEnable.OnEnabledChanged -= OnStateEnabledChanged; BehaviourController.OnHierarchyObjectAssigned -= OnHierarchyObjectAssigned; base.UnassignInternal(); _behaviourController = null!; } protected override void InitializeInternal() { base.InitializeInternal(); NotAssignedException.Check(this, _behaviourController); NotAssignedException.Check(this, StateEnable); } private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive(); private void OnHierarchyObjectActiveChanged(IActive sender, bool previousState) => UpdateActive(); private void UpdateActive() { bool previousActive = IsActive; IsActive = StateEnable.Enabled && _behaviourController.HierarchyObject.IsActive; if (previousActive != IsActive) OnActiveChanged?.Invoke(this, previousActive); } }