using System; namespace Syntriax.Engine.Core; public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, IPreUpdate, IUpdate, IPostUpdate, IPreDraw, IDraw, IPostDraw { protected IUniverse Universe => BehaviourController.UniverseObject.Universe; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject; private readonly Action cachedEnteredUniverse = null!; private readonly Action cachedExitedUniverse = null!; public Behaviour() { OnInitialized.AddListener(OnInitialize); OnFinalized.AddListener(OnFinalize); OnUnassigned.AddListener(OnUnassign); cachedEnteredUniverse = EnteredUniverse; cachedExitedUniverse = ExitedUniverse; } protected virtual void OnUnassign() { } protected virtual void OnUnassign(IAssignable assignable) => OnUnassign(); protected virtual void OnInitialize() { } protected virtual void OnInitialize(IInitializable _) { BehaviourController.UniverseObject.OnEnteredUniverse.AddListener(cachedEnteredUniverse); BehaviourController.UniverseObject.OnExitedUniverse.AddListener(cachedExitedUniverse); OnInitialize(); if (UniverseObject.IsInUniverse) EnteredUniverse(UniverseObject, Universe); } protected virtual void OnFinalize() { } protected virtual void OnFinalize(IInitializable _) { BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(cachedEnteredUniverse); BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(cachedExitedUniverse); OnFinalize(); if (UniverseObject.IsInUniverse) ExitedUniverse(UniverseObject, Universe); } protected virtual void OnFirstActiveFrame() { } void IFirstFrameUpdate.FirstActiveFrame() { Debug.Assert.AssertInitialized(this); OnFirstActiveFrame(); } protected virtual void OnPreUpdatePreActiveCheck() { } protected virtual void OnPreUpdate() { } void IPreUpdate.PreUpdate() { Debug.Assert.AssertInitialized(this); OnPreUpdatePreActiveCheck(); if (!IsActive) return; OnPreUpdate(); } protected virtual void OnUpdatePreActiveCheck() { } protected virtual void OnUpdate() { } void IUpdate.Update() { Debug.Assert.AssertInitialized(this); OnUpdatePreActiveCheck(); if (!IsActive) return; OnUpdate(); } protected virtual void OnPostUpdatePreActiveCheck() { } protected virtual void OnPostUpdate() { } void IPostUpdate.PostUpdate() { Debug.Assert.AssertInitialized(this); OnPostUpdatePreActiveCheck(); if (!StateEnable.Enabled) return; OnPostUpdate(); } protected virtual void OnPreDrawPreActiveCheck() { } protected virtual void OnPreDraw() { } void IPreDraw.PreDraw() { Debug.Assert.AssertInitialized(this); OnPreDrawPreActiveCheck(); if (!StateEnable.Enabled) return; OnPreDraw(); } protected virtual void OnDrawPreActiveCheck() { } protected virtual void OnDraw() { } void IDraw.Draw() { Debug.Assert.AssertInitialized(this); OnDrawPreActiveCheck(); if (!StateEnable.Enabled) return; OnDraw(); } protected virtual void OnPostDrawPreActiveCheck() { } protected virtual void OnPostDraw() { } void IPostDraw.PostDraw() { Debug.Assert.AssertInitialized(this); OnPostDrawPreActiveCheck(); if (!StateEnable.Enabled) return; OnPostDraw(); } protected virtual void OnEnteredUniverse(IUniverse universe) { } protected virtual void EnteredUniverse(IUniverseObject sender, IUniverse universe) => OnEnteredUniverse(universe); protected virtual void OnExitedUniverse(IUniverse universe) { } protected virtual void ExitedUniverse(IUniverseObject sender, IUniverse universe) => OnExitedUniverse(universe); }