Syntriax.Engine/Engine.Core/BehaviourBase.cs

87 lines
2.9 KiB
C#

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);
}
}