using Syntriax.Engine.Core.Abstract; 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?.InvokeSafe(this, previousPriority); } } private bool _isActive = false; public bool IsActive => _isActive; protected virtual void OnAssign(IBehaviourController behaviourController) { } public bool Assign(IBehaviourController behaviourController) { if (IsInitialized) return false; _behaviourController = behaviourController; OnAssign(behaviourController); behaviourController.OnUniverseObjectAssigned += OnUniverseObjectAssigned; if (behaviourController.UniverseObject is not null) OnUniverseObjectAssigned(behaviourController); OnBehaviourControllerAssigned?.InvokeSafe(this); return true; } private void OnUniverseObjectAssigned(IHasUniverseObject sender) { sender.UniverseObject.OnActiveChanged += OnUniverseObjectActiveChanged; UpdateActive(); } protected override void OnAssign(IStateEnable stateEnable) { base.OnAssign(stateEnable); stateEnable.OnEnabledChanged += OnStateEnabledChanged; } protected override void UnassignInternal() { StateEnable.OnEnabledChanged -= OnStateEnabledChanged; BehaviourController.OnUniverseObjectAssigned -= OnUniverseObjectAssigned; base.UnassignInternal(); _behaviourController = null!; } protected override void InitializeInternal() { Debug.AssertHelpers.AssertBehaviourControllerAssigned(this); Debug.AssertHelpers.AssertStateEnableAssigned(this); } private void OnStateEnabledChanged(IStateEnable sender, bool previousState) => UpdateActive(); private void OnUniverseObjectActiveChanged(IActive sender, bool previousState) => UpdateActive(); private void UpdateActive() { bool previousActive = IsActive; _isActive = StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; if (previousActive != IsActive) OnActiveChanged?.InvokeSafe(this, previousActive); } }