From 988a6f67f2cbbbf0324ee034adcb2a0b626d4cd6 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Wed, 22 Oct 2025 16:50:19 +0300 Subject: [PATCH] BREAKING CHANGE: renamed original Behaviour class to BehaviourInternal, and replaced it with BehaviourBase Original Behaviour was using old methods for detecting entering/exiting universe, they are now all under the same hood and the original is kept for UniverseEntranceManager because it needs to enter the universe without itself. The internal behaviour kept under a subnamespace of "Core.Internal" for the purpose that it might come in handy for other use cases. --- Engine.Core/Behaviour.cs | 117 +++++++++++++----- Engine.Core/Behaviour2D.cs | 3 +- Engine.Core/BehaviourBase.cs | 103 --------------- Engine.Core/BehaviourInternal.cs | 56 +++++++++ Engine.Core/Systems/DrawManager.cs | 6 +- .../Systems/UniverseEntranceManager.cs | 2 +- Engine.Core/Systems/UpdateManager.cs | 6 +- .../LiteNetLibClient.cs | 8 +- .../LiteNetLibCommunicatorBase.cs | 8 +- .../LiteNetLibServer.cs | 8 +- .../Behaviours/LoadContentManager.cs | 6 +- .../Behaviours/MonoGameCamera2D.cs | 2 +- .../Behaviours/MonoGameCamera3D.cs | 2 +- .../Behaviours/SpriteBatcher.cs | 2 +- .../Behaviours/TriangleBatcher.cs | 2 +- .../MonoGameWindowContainer.cs | 2 +- Engine.Physics2D/PhysicsEngine2D.cs | 6 +- Engine.Systems/Network/NetworkManager.cs | 6 +- Engine.Systems/Time/Stopwatch.cs | 10 +- Engine.Systems/Time/TickerStopwatch.cs | 4 +- Engine.Systems/Time/TickerTimer.cs | 4 +- Engine.Systems/Time/Timer.cs | 10 +- Engine.Systems/Tween/TweenManager.cs | 6 +- 23 files changed, 194 insertions(+), 185 deletions(-) delete mode 100644 Engine.Core/BehaviourBase.cs create mode 100644 Engine.Core/BehaviourInternal.cs diff --git a/Engine.Core/Behaviour.cs b/Engine.Core/Behaviour.cs index 06b628f..4f4caa2 100644 --- a/Engine.Core/Behaviour.cs +++ b/Engine.Core/Behaviour.cs @@ -1,50 +1,103 @@ namespace Engine.Core; -public abstract class Behaviour : BehaviourBase +[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] +public abstract class Behaviour : BaseEntity, IBehaviour { - private readonly Event.EventHandler delegateEnteredUniverse = null!; - private readonly Event.EventHandler delegateExitedUniverse = null!; + public Event OnPriorityChanged { get; } = new(); + public Event OnActiveChanged { get; } = new(); + public Event OnBehaviourControllerAssigned { get; } = new(); - public Behaviour() + private readonly Event.EventHandler delegateOnUniverseObjectAssigned = null!; + private readonly Event.EventHandler delegateOnUniverseObjectActiveChanged = null!; + private readonly Event.EventHandler delegateOnStateEnabledChanged = null!; + + public IUniverse Universe => BehaviourController.UniverseObject.Universe; + public IUniverseObject UniverseObject => BehaviourController.UniverseObject; + + private IBehaviourController _behaviourController = null!; + public IBehaviourController BehaviourController => _behaviourController; + + private int _priority = 0; + public int Priority { - OnInitialized.AddListener(OnInitialize); - OnFinalized.AddListener(OnFinalize); - OnUnassigned.AddListener(OnUnassign); + get => _priority; + set + { + if (value == _priority) + return; - delegateEnteredUniverse = EnteredUniverse; - delegateExitedUniverse = ExitedUniverse; + int previousPriority = _priority; + _priority = value; + OnPriorityChanged?.Invoke(this, new(previousPriority)); + } } - protected virtual void OnUnassign() { } - protected void OnUnassign(IAssignable assignable) => OnUnassign(); + private bool _isActive = false; + public bool IsActive => _isActive; - protected virtual void OnInitialize() { } - protected void OnInitialize(IInitializable _) + protected virtual void OnAssign(IBehaviourController behaviourController) { } + public bool Assign(IBehaviourController behaviourController) { - BehaviourController.UniverseObject.OnEnteredUniverse.AddListener(delegateEnteredUniverse); - BehaviourController.UniverseObject.OnExitedUniverse.AddListener(delegateExitedUniverse); + if (IsInitialized) + return false; - OnInitialize(); - - if (UniverseObject.IsInUniverse) - EnteredUniverse(UniverseObject, new(Universe)); + _behaviourController = behaviourController; + OnAssign(behaviourController); + behaviourController.OnUniverseObjectAssigned.AddListener(delegateOnUniverseObjectAssigned); + behaviourController.StateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); + if (behaviourController.UniverseObject is not null) + OnUniverseObjectAssigned(behaviourController); + OnBehaviourControllerAssigned?.Invoke(this); + return true; } - protected virtual void OnFinalize() { } - protected void OnFinalize(IInitializable _) + private void OnUniverseObjectAssigned(IHasUniverseObject sender) { - BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(delegateEnteredUniverse); - BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(delegateExitedUniverse); - - OnFinalize(); - - if (UniverseObject.IsInUniverse) - ExitedUniverse(UniverseObject, new(Universe)); + sender.UniverseObject.OnActiveChanged.AddListener(delegateOnUniverseObjectActiveChanged); + UpdateActive(); } - protected virtual void OnEnteredUniverse(IUniverse universe) { } - protected void EnteredUniverse(IUniverseObject sender, IUniverseObject.EnteredUniverseArguments args) => OnEnteredUniverse(args.Universe); + protected override void OnAssign(IStateEnable stateEnable) + { + base.OnAssign(stateEnable); - protected virtual void OnExitedUniverse(IUniverse universe) { } - protected void ExitedUniverse(IUniverseObject sender, IUniverseObject.ExitedUniverseArguments args) => OnExitedUniverse(args.Universe); + stateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); + } + + protected override void UnassignInternal() + { + BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged); + StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); + BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned); + BehaviourController.StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); + base.UnassignInternal(); + _behaviourController = null!; + } + + protected override void InitializeInternal() + { + Debug.Assert.AssertBehaviourControllerAssigned(this); + Debug.Assert.AssertStateEnableAssigned(this); + + UpdateActive(); + } + + private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); + private void OnUniverseObjectActiveChanged(IActive sender, IActive.ActiveChangedArguments args) => UpdateActive(); + + private void UpdateActive() + { + bool previousActive = IsActive; + _isActive = StateEnable.Enabled && _behaviourController.StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; + + if (previousActive != IsActive) + OnActiveChanged?.Invoke(this, new(previousActive)); + } + + protected Behaviour() + { + delegateOnUniverseObjectAssigned = OnUniverseObjectAssigned; + delegateOnUniverseObjectActiveChanged = OnUniverseObjectActiveChanged; + delegateOnStateEnabledChanged = OnStateEnabledChanged; + } } diff --git a/Engine.Core/Behaviour2D.cs b/Engine.Core/Behaviour2D.cs index 6622cc1..26b675a 100644 --- a/Engine.Core/Behaviour2D.cs +++ b/Engine.Core/Behaviour2D.cs @@ -1,6 +1,7 @@ namespace Engine.Core; -public abstract class Behaviour2D : Behaviour, IBehaviour2D +// TODO this should not use independent behaviour, the OnInitialize usage for getting the transform can cause very unexpected issues +public abstract class Behaviour2D : Internal.BehaviourIndependent, IBehaviour2D { public ITransform2D Transform { get; private set; } = null!; diff --git a/Engine.Core/BehaviourBase.cs b/Engine.Core/BehaviourBase.cs deleted file mode 100644 index 27012c0..0000000 --- a/Engine.Core/BehaviourBase.cs +++ /dev/null @@ -1,103 +0,0 @@ -namespace Engine.Core; - -[System.Diagnostics.DebuggerDisplay("{GetType().Name, nq}, Priority: {Priority}, Initialized: {Initialized}")] -public abstract class BehaviourBase : BaseEntity, IBehaviour -{ - public Event OnPriorityChanged { get; } = new(); - public Event OnActiveChanged { get; } = new(); - public Event OnBehaviourControllerAssigned { get; } = new(); - - private readonly Event.EventHandler delegateOnUniverseObjectAssigned = null!; - private readonly Event.EventHandler delegateOnUniverseObjectActiveChanged = null!; - private readonly Event.EventHandler delegateOnStateEnabledChanged = null!; - - public IUniverse Universe => BehaviourController.UniverseObject.Universe; - public IUniverseObject UniverseObject => BehaviourController.UniverseObject; - - 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, new(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.AddListener(delegateOnUniverseObjectAssigned); - behaviourController.StateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); - if (behaviourController.UniverseObject is not null) - OnUniverseObjectAssigned(behaviourController); - OnBehaviourControllerAssigned?.Invoke(this); - return true; - } - - private void OnUniverseObjectAssigned(IHasUniverseObject sender) - { - sender.UniverseObject.OnActiveChanged.AddListener(delegateOnUniverseObjectActiveChanged); - UpdateActive(); - } - - protected override void OnAssign(IStateEnable stateEnable) - { - base.OnAssign(stateEnable); - - stateEnable.OnEnabledChanged.AddListener(delegateOnStateEnabledChanged); - } - - protected override void UnassignInternal() - { - BehaviourController.UniverseObject.OnActiveChanged.RemoveListener(delegateOnUniverseObjectActiveChanged); - StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); - BehaviourController.OnUniverseObjectAssigned.RemoveListener(delegateOnUniverseObjectAssigned); - BehaviourController.StateEnable.OnEnabledChanged.RemoveListener(delegateOnStateEnabledChanged); - base.UnassignInternal(); - _behaviourController = null!; - } - - protected override void InitializeInternal() - { - Debug.Assert.AssertBehaviourControllerAssigned(this); - Debug.Assert.AssertStateEnableAssigned(this); - - UpdateActive(); - } - - private void OnStateEnabledChanged(IStateEnable sender, IStateEnable.EnabledChangedArguments args) => UpdateActive(); - private void OnUniverseObjectActiveChanged(IActive sender, IActive.ActiveChangedArguments args) => UpdateActive(); - - private void UpdateActive() - { - bool previousActive = IsActive; - _isActive = StateEnable.Enabled && _behaviourController.StateEnable.Enabled && _behaviourController.UniverseObject.IsActive; - - if (previousActive != IsActive) - OnActiveChanged?.Invoke(this, new(previousActive)); - } - - protected BehaviourBase() - { - delegateOnUniverseObjectAssigned = OnUniverseObjectAssigned; - delegateOnUniverseObjectActiveChanged = OnUniverseObjectActiveChanged; - delegateOnStateEnabledChanged = OnStateEnabledChanged; - } -} diff --git a/Engine.Core/BehaviourInternal.cs b/Engine.Core/BehaviourInternal.cs new file mode 100644 index 0000000..5850d2e --- /dev/null +++ b/Engine.Core/BehaviourInternal.cs @@ -0,0 +1,56 @@ +namespace Engine.Core.Internal; + +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +/// +/// This behaviour can be used for core managers like etc. which need to be able to work even +/// in a very bare minimum setup without the presence of to set themselves up on universe entrance. +/// I recommend not using this unless you know what you are doing but it might come in handy for some use cases. +/// +public abstract class BehaviourIndependent : Behaviour +{ + private readonly Event.EventHandler delegateEnteredUniverse = null!; + private readonly Event.EventHandler delegateExitedUniverse = null!; + + public BehaviourIndependent() + { + OnInitialized.AddListener(OnInitialize); + OnFinalized.AddListener(OnFinalize); + OnUnassigned.AddListener(OnUnassign); + + delegateEnteredUniverse = EnteredUniverse; + delegateExitedUniverse = ExitedUniverse; + } + + protected virtual void OnUnassign() { } + protected void OnUnassign(IAssignable assignable) => OnUnassign(); + + protected virtual void OnInitialize() { } + protected void OnInitialize(IInitializable _) + { + BehaviourController.UniverseObject.OnEnteredUniverse.AddListener(delegateEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.AddListener(delegateExitedUniverse); + + OnInitialize(); + + if (UniverseObject.IsInUniverse) + EnteredUniverse(UniverseObject, new(Universe)); + } + + protected virtual void OnFinalize() { } + protected void OnFinalize(IInitializable _) + { + BehaviourController.UniverseObject.OnEnteredUniverse.RemoveListener(delegateEnteredUniverse); + BehaviourController.UniverseObject.OnExitedUniverse.RemoveListener(delegateExitedUniverse); + + OnFinalize(); + + if (UniverseObject.IsInUniverse) + ExitedUniverse(UniverseObject, new(Universe)); + } + + protected virtual void OnEnteredUniverse(IUniverse universe) { } + protected void EnteredUniverse(IUniverseObject sender, IUniverseObject.EnteredUniverseArguments args) => OnEnteredUniverse(args.Universe); + + protected virtual void OnExitedUniverse(IUniverse universe) { } + protected void ExitedUniverse(IUniverseObject sender, IUniverseObject.ExitedUniverseArguments args) => OnExitedUniverse(args.Universe); +} diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs index 13706ae..2e15c07 100644 --- a/Engine.Core/Systems/DrawManager.cs +++ b/Engine.Core/Systems/DrawManager.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; namespace Engine.Core; -public class DrawManager : Behaviour +public class DrawManager : Behaviour, IEnterUniverse, IExitUniverse { // We use Descending order because draw calls are running from last to first private static Comparer SortByDescendingPriority() => Comparer.Create((x, y) => y.CompareTo(x)); @@ -30,7 +30,7 @@ public class DrawManager : Behaviour postDrawEntities[i].PostDraw(); } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { preDrawEntities.Assign(universe); drawEntities.Assign(universe); @@ -41,7 +41,7 @@ public class DrawManager : Behaviour universe.OnPostDraw.AddListener(OnPostDraw); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { preDrawEntities.Unassign(); drawEntities.Unassign(); diff --git a/Engine.Core/Systems/UniverseEntranceManager.cs b/Engine.Core/Systems/UniverseEntranceManager.cs index 502c6a6..64bf3a8 100644 --- a/Engine.Core/Systems/UniverseEntranceManager.cs +++ b/Engine.Core/Systems/UniverseEntranceManager.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; namespace Engine.Core; -public class UniverseEntranceManager : Behaviour +public class UniverseEntranceManager : Internal.BehaviourIndependent { // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs index f44076a..6af1be4 100644 --- a/Engine.Core/Systems/UpdateManager.cs +++ b/Engine.Core/Systems/UpdateManager.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; namespace Engine.Core; -public class UpdateManager : Behaviour +public class UpdateManager : Behaviour, IEnterUniverse, IExitUniverse { // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); @@ -16,7 +16,7 @@ public class UpdateManager : Behaviour private readonly List toCallFirstFrameUpdates = new(32); - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { firstFrameUpdates.Assign(universe); lastFrameUpdates.Assign(universe); @@ -30,7 +30,7 @@ public class UpdateManager : Behaviour universe.OnPostUpdate.AddListener(OnPostUpdate); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { firstFrameUpdates.Unassign(); lastFrameUpdates.Unassign(); diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs index 55887e6..cec0006 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibClient.cs @@ -56,17 +56,17 @@ public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicator return this; } - protected override void OnEnteredUniverse(IUniverse universe) + public override void EnterUniverse(IUniverse universe) { - base.OnEnteredUniverse(universe); + base.EnterUniverse(universe); cancellationTokenSource = new CancellationTokenSource(); PollEvents(cancellationTokenSource.Token); } - protected override void OnExitedUniverse(IUniverse universe) + public override void ExitUniverse(IUniverse universe) { - base.OnExitedUniverse(universe); + base.ExitUniverse(universe); cancellationTokenSource?.Cancel(); } diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs index d45cce4..4dd1016 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibCommunicatorBase.cs @@ -9,7 +9,7 @@ using LiteNetLib.Utils; namespace Engine.Systems.Network; -public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicator +public abstract class LiteNetLibCommunicatorBase : Behaviour, IEnterUniverse, IExitUniverse, INetworkCommunicator { protected readonly NetPacketProcessor netPacketProcessor = new(); @@ -33,15 +33,13 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat return this; } - protected override void OnEnteredUniverse(IUniverse universe) + public virtual void EnterUniverse(IUniverse universe) { - base.OnEnteredUniverse(universe); logger = universe.FindBehaviour(); } - protected override void OnExitedUniverse(IUniverse universe) + public virtual void ExitUniverse(IUniverse universe) { - base.OnExitedUniverse(universe); logger = null; Stop(); } diff --git a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs index f77d1e3..c9e8d62 100644 --- a/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs +++ b/Engine.Integration/Engine.Integration.LiteNetLib/LiteNetLibServer.cs @@ -88,15 +88,15 @@ public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicator private void PollEvents(IUniverse sender, IUniverse.UpdateArguments args) => Manager.PollEvents(); - protected override void OnEnteredUniverse(IUniverse universe) + public override void EnterUniverse(IUniverse universe) { - base.OnEnteredUniverse(universe); + base.EnterUniverse(universe); universe.OnPostUpdate.AddListener(PollEvents); } - protected override void OnExitedUniverse(IUniverse universe) + public override void ExitUniverse(IUniverse universe) { - base.OnExitedUniverse(universe); + base.ExitUniverse(universe); universe.OnPostUpdate.RemoveListener(PollEvents); } } diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs index 18fd80c..4646ed6 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/LoadContentManager.cs @@ -4,7 +4,7 @@ using Engine.Core; namespace Engine.Integration.MonoGame; -public class LoadContentManager : Behaviour, IFirstFrameUpdate +public class LoadContentManager : Behaviour, IEnterUniverse, IExitUniverse, IFirstFrameUpdate { // We use Ascending order because we are using reverse for loop to call them private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); @@ -20,14 +20,14 @@ public class LoadContentManager : Behaviour, IFirstFrameUpdate monoGameWindowContainer = Universe.FindRequiredBehaviour(); } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { loadContents.Assign(universe); universe.OnPreUpdate.AddListener(OnPreUpdate); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { loadContents.Unassign(); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs index 7858b3c..911a7af 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera2D.cs @@ -5,7 +5,7 @@ using Engine.Core; namespace Engine.Integration.MonoGame; -public class MonoGameCamera2D : BehaviourBase, ICamera2D, IFirstFrameUpdate, IPreDraw +public class MonoGameCamera2D : Behaviour, ICamera2D, IFirstFrameUpdate, IPreDraw { public Event OnMatrixTransformChanged { get; } = new(); public Event OnViewportChanged { get; } = new(); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera3D.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera3D.cs index 6a9440f..591ed3b 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera3D.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/MonoGameCamera3D.cs @@ -5,7 +5,7 @@ using Engine.Core; namespace Engine.Integration.MonoGame; -public class MonoGameCamera3D : BehaviourBase, ICamera3D, IFirstFrameUpdate, IPreDraw +public class MonoGameCamera3D : Behaviour, ICamera3D, IFirstFrameUpdate, IPreDraw { public Event OnViewChanged { get; } = new(); public Event OnProjectionChanged { get; } = new(); diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs index 9f39e1d..b9ca10e 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/SpriteBatcher.cs @@ -4,7 +4,7 @@ using Engine.Core; namespace Engine.Integration.MonoGame; -public class SpriteBatcher : BehaviourBase, IFirstFrameUpdate, IDraw +public class SpriteBatcher : Behaviour, IFirstFrameUpdate, IDraw { private static Comparer SortByPriority() => Comparer.Create((x, y) => y.CompareTo(x)); private static System.Func GetPriority() => (b) => b.Priority; diff --git a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs index 40827a3..b8bf5d0 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/Behaviours/TriangleBatcher.cs @@ -6,7 +6,7 @@ using Engine.Core; namespace Engine.Integration.MonoGame; -public class TriangleBatcher : BehaviourBase, ITriangleBatch, IFirstFrameUpdate, IDraw +public class TriangleBatcher : Behaviour, ITriangleBatch, IFirstFrameUpdate, IDraw { private static Comparer SortByAscendingPriority() => Comparer.Create((x, y) => x.CompareTo(y)); private static System.Func GetPriority() => (b) => b.Priority; diff --git a/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs b/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs index f4b8016..a9d6c7b 100644 --- a/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs +++ b/Engine.Integration/Engine.Integration.MonoGame/UniverseObjects/MonoGameWindowContainer.cs @@ -4,7 +4,7 @@ using Engine.Core.Serialization; namespace Engine.Integration.MonoGame; [IgnoreSerialization] -public class MonoGameWindowContainer(MonoGameWindow GameWindow) : BehaviourBase +public class MonoGameWindowContainer(MonoGameWindow GameWindow) : Behaviour { public MonoGameWindow Window { get; } = GameWindow; } diff --git a/Engine.Physics2D/PhysicsEngine2D.cs b/Engine.Physics2D/PhysicsEngine2D.cs index d2071c3..f36614c 100644 --- a/Engine.Physics2D/PhysicsEngine2D.cs +++ b/Engine.Physics2D/PhysicsEngine2D.cs @@ -4,7 +4,7 @@ using Engine.Core; namespace Engine.Physics2D; -public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D +public class PhysicsEngine2D : Behaviour, IEnterUniverse, IExitUniverse, IPreUpdate, IPhysicsEngine2D { public Event OnPhysicsIteration { get; } = new(); public Event OnPhysicsStep { get; } = new(); @@ -224,7 +224,7 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D rigidBody.Transform.Rotation += rigidBody.AngularVelocity * intervalDeltaTime; } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { physicsPreUpdateCollector.Assign(universe); physicsUpdateCollector.Assign(universe); @@ -234,7 +234,7 @@ public class PhysicsEngine2D : Behaviour, IPreUpdate, IPhysicsEngine2D rigidBodyCollector.Assign(universe); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { physicsPreUpdateCollector.Unassign(); physicsUpdateCollector.Unassign(); diff --git a/Engine.Systems/Network/NetworkManager.cs b/Engine.Systems/Network/NetworkManager.cs index 53d9c5c..a6534b4 100644 --- a/Engine.Systems/Network/NetworkManager.cs +++ b/Engine.Systems/Network/NetworkManager.cs @@ -10,7 +10,7 @@ namespace Engine.Systems.Network; /// /// Intermediary manager that looks up in it's hierarchy for a to route/broadcast it's received packets to their destinations. /// -public class NetworkManager : Behaviour, INetworkManager +public class NetworkManager : Behaviour, IEnterUniverse, IExitUniverse, INetworkManager { private readonly Dictionary>> clientPacketArrivalMethods = []; private readonly Dictionary>> serverPacketArrivalMethods = []; @@ -230,8 +230,8 @@ public class NetworkManager : Behaviour, INetworkManager UnregisterPacketRoutersFor(removedBehaviour, serverPacketRouters, serverPacketArrivalMethods); } - protected override void OnExitedUniverse(IUniverse universe) => _networkEntityCollector.Unassign(); - protected override void OnEnteredUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) => _networkEntityCollector.Unassign(); + public void EnterUniverse(IUniverse universe) { _networkEntityCollector.Assign(universe); NetworkCommunicator = BehaviourController.GetRequiredBehaviourInParent(); diff --git a/Engine.Systems/Time/Stopwatch.cs b/Engine.Systems/Time/Stopwatch.cs index 90e92f8..3e312f6 100644 --- a/Engine.Systems/Time/Stopwatch.cs +++ b/Engine.Systems/Time/Stopwatch.cs @@ -2,7 +2,7 @@ using Engine.Core; namespace Engine.Systems.Time; -public class Stopwatch : Behaviour, IUpdate, IStopwatch +public class Stopwatch : Behaviour, IUpdate, IEnterUniverse, IExitUniverse, IStopwatch { public Event OnStarted { get; } = new(); public Event OnDelta { get; } = new(); @@ -49,7 +49,7 @@ public class Stopwatch : Behaviour, IUpdate, IStopwatch OnDelta?.Invoke(this, new(delta)); } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { if (!shouldBeTicking || State is TimerState.Ticking) return; @@ -60,7 +60,7 @@ public class Stopwatch : Behaviour, IUpdate, IStopwatch StartStopwatch(); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { if (!shouldBeTicking || State is not TimerState.Ticking) return; @@ -88,8 +88,10 @@ public class Stopwatch : Behaviour, IUpdate, IStopwatch OnStarted?.Invoke(this); } - protected override void OnFinalize() + protected override void FinalizeInternal() { + base.FinalizeInternal(); + Time = 0f; State = TimerState.Idle; shouldBeTicking = false; diff --git a/Engine.Systems/Time/TickerStopwatch.cs b/Engine.Systems/Time/TickerStopwatch.cs index c41f5b7..79ead92 100644 --- a/Engine.Systems/Time/TickerStopwatch.cs +++ b/Engine.Systems/Time/TickerStopwatch.cs @@ -30,9 +30,9 @@ public class TickerStopwatch : Stopwatch, ITicker } } - protected override void OnFinalize() + protected override void FinalizeInternal() { - base.OnFinalize(); + base.FinalizeInternal(); TickCounter = 0; nextTick = 0f; diff --git a/Engine.Systems/Time/TickerTimer.cs b/Engine.Systems/Time/TickerTimer.cs index 4e17115..6b58299 100644 --- a/Engine.Systems/Time/TickerTimer.cs +++ b/Engine.Systems/Time/TickerTimer.cs @@ -30,9 +30,9 @@ public class TickerTimer : Timer, ITicker } } - protected override void OnFinalize() + protected override void FinalizeInternal() { - base.OnFinalize(); + base.FinalizeInternal(); TickCounter = 0; nextTick = 0f; diff --git a/Engine.Systems/Time/Timer.cs b/Engine.Systems/Time/Timer.cs index 42d2e03..9207bf0 100644 --- a/Engine.Systems/Time/Timer.cs +++ b/Engine.Systems/Time/Timer.cs @@ -2,7 +2,7 @@ using Engine.Core; namespace Engine.Systems.Time; -public class Timer : Behaviour, IUpdate, ITimer +public class Timer : Behaviour, IUpdate, IEnterUniverse, IExitUniverse, ITimer { public Event OnStarted { get; } = new(); public Event OnDelta { get; } = new(); @@ -67,7 +67,7 @@ public class Timer : Behaviour, IUpdate, ITimer Stop(); } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { if (!shouldBeTicking || State is TimerState.Ticking) return; @@ -78,7 +78,7 @@ public class Timer : Behaviour, IUpdate, ITimer StartTimer(); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { if (!shouldBeTicking || State is not TimerState.Ticking) return; @@ -106,8 +106,10 @@ public class Timer : Behaviour, IUpdate, ITimer OnStarted?.Invoke(this); } - protected override void OnFinalize() + protected override void FinalizeInternal() { + base.FinalizeInternal(); + StartTime = 0f; Remaining = 0f; State = TimerState.Idle; diff --git a/Engine.Systems/Tween/TweenManager.cs b/Engine.Systems/Tween/TweenManager.cs index 53f830d..7a6793e 100644 --- a/Engine.Systems/Tween/TweenManager.cs +++ b/Engine.Systems/Tween/TweenManager.cs @@ -5,7 +5,7 @@ using Engine.Core; namespace Engine.Systems.Tween; -public class TweenManager : Behaviour, ITweenManager +public class TweenManager : Behaviour, IEnterUniverse, IExitUniverse, ITweenManager { private CoroutineManager coroutineManager = null!; @@ -73,12 +73,12 @@ public class TweenManager : Behaviour, ITweenManager Return((Tween)tween); } - protected override void OnEnteredUniverse(IUniverse universe) + public void EnterUniverse(IUniverse universe) { coroutineManager = universe.FindRequiredBehaviour(); } - protected override void OnExitedUniverse(IUniverse universe) + public void ExitUniverse(IUniverse universe) { coroutineManager = null!; }