From e7bd9244943ba489669b60956859f14d0a5a8161 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 22 May 2025 23:51:08 +0300 Subject: [PATCH] refactor: update & draw calls have been refactored into systems --- Engine.Core/Abstract/IBehaviourController.cs | 31 +------- Engine.Core/Behaviour.cs | 79 +++++++++++++------ Engine.Core/Behaviour2D.cs | 4 - Engine.Core/BehaviourController.cs | 25 ------ Engine.Core/Systems/Abstract/IDraw.cs | 6 ++ .../Systems/Abstract/IFirstFrameUpdate.cs | 6 ++ Engine.Core/Systems/Abstract/IPostDraw.cs | 6 ++ Engine.Core/Systems/Abstract/IPostUpdate.cs | 6 ++ Engine.Core/Systems/Abstract/IPreDraw.cs | 6 ++ Engine.Core/Systems/Abstract/IPreUpdate.cs | 6 ++ Engine.Core/Systems/Abstract/IUpdate.cs | 6 ++ Engine.Core/Systems/DrawManager.cs | 49 ++++++++++++ Engine.Core/Systems/UpdateManager.cs | 69 ++++++++++++++++ Engine.Core/Universe.cs | 7 -- 14 files changed, 216 insertions(+), 90 deletions(-) create mode 100644 Engine.Core/Systems/Abstract/IDraw.cs create mode 100644 Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs create mode 100644 Engine.Core/Systems/Abstract/IPostDraw.cs create mode 100644 Engine.Core/Systems/Abstract/IPostUpdate.cs create mode 100644 Engine.Core/Systems/Abstract/IPreDraw.cs create mode 100644 Engine.Core/Systems/Abstract/IPreUpdate.cs create mode 100644 Engine.Core/Systems/Abstract/IUpdate.cs create mode 100644 Engine.Core/Systems/DrawManager.cs create mode 100644 Engine.Core/Systems/UpdateManager.cs diff --git a/Engine.Core/Abstract/IBehaviourController.cs b/Engine.Core/Abstract/IBehaviourController.cs index 2736820..3fe1e3a 100644 --- a/Engine.Core/Abstract/IBehaviourController.cs +++ b/Engine.Core/Abstract/IBehaviourController.cs @@ -3,25 +3,10 @@ using System.Collections.Generic; namespace Syntriax.Engine.Core; /// -/// Represents a controller for managing s and notify them accordingly about the engine's updates. Connected to an . +/// Represents a controller for managing s. Connected to an . /// public interface IBehaviourController : IEntity, IHasUniverseObject, IEnumerable { - /// - /// Event triggered before the update of s. - /// - event PreUpdateEventHandler? OnPreUpdate; - - /// - /// Event triggered during the update of s. - /// - event UpdateEventHandler? OnUpdate; - - /// - /// Event triggered before the drawing phase. - /// - event PreDrawEventHandler? OnPreDraw; - /// /// Event triggered when a is added to the . /// @@ -83,20 +68,6 @@ public interface IBehaviourController : IEntity, IHasUniverseObject, IEnumerable /// The to remove. void RemoveBehaviour(T behaviour) where T : class, IBehaviour; - /// - /// Updates all s in the . - /// - void Update(); - - /// - /// Performs pre-draw operations. - /// - void UpdatePreDraw(); - - delegate void PreUpdateEventHandler(IBehaviourController sender); - delegate void UpdateEventHandler(IBehaviourController sender); - delegate void PreDrawEventHandler(IBehaviourController sender); delegate void BehaviourAddedEventHandler(IBehaviourController sender, IBehaviour behaviourAdded); delegate void BehaviourRemovedEventHandler(IBehaviourController sender, IBehaviour behaviourRemoved); - } diff --git a/Engine.Core/Behaviour.cs b/Engine.Core/Behaviour.cs index 25a7edb..4a9976f 100644 --- a/Engine.Core/Behaviour.cs +++ b/Engine.Core/Behaviour.cs @@ -1,9 +1,9 @@ namespace Syntriax.Engine.Core; -public abstract class Behaviour : BehaviourBase +public abstract class Behaviour : BehaviourBase, IFirstFrameUpdate, + IPreUpdate, IUpdate, IPostUpdate, + IPreDraw, IDraw, IPostDraw { - private bool isInitializedThisFrame = false; - protected IUniverse Universe => BehaviourController.UniverseObject.Universe; protected IUniverseObject UniverseObject => BehaviourController.UniverseObject; @@ -20,11 +20,6 @@ public abstract class Behaviour : BehaviourBase protected virtual void OnInitialize() { } protected virtual void OnInitialize(IInitializable _) { - isInitializedThisFrame = true; - - BehaviourController.OnPreUpdate += PreUpdate; - BehaviourController.OnPreDraw += PreDraw; - BehaviourController.OnUpdate += Update; BehaviourController.UniverseObject.OnEnteredUniverse += EnteredUniverse; BehaviourController.UniverseObject.OnExitedUniverse += ExitedUniverse; @@ -37,9 +32,6 @@ public abstract class Behaviour : BehaviourBase protected virtual void OnFinalize() { } protected virtual void OnFinalize(IInitializable _) { - BehaviourController.OnPreUpdate -= PreUpdate; - BehaviourController.OnPreDraw -= PreDraw; - BehaviourController.OnUpdate -= Update; BehaviourController.UniverseObject.OnEnteredUniverse -= EnteredUniverse; BehaviourController.UniverseObject.OnExitedUniverse -= ExitedUniverse; @@ -49,9 +41,16 @@ public abstract class Behaviour : BehaviourBase ExitedUniverse(UniverseObject, Universe); } + protected virtual void OnFirstActiveFrame() { } + void IFirstFrameUpdate.FirstActiveFrame() + { + Debug.Assert.AssertInitialized(this); + OnFirstActiveFrame(); + } + protected virtual void OnPreUpdatePreActiveCheck() { } protected virtual void OnPreUpdate() { } - protected virtual void PreUpdate(IBehaviourController _) + void IPreUpdate.PreUpdate() { Debug.Assert.AssertInitialized(this); @@ -60,22 +59,12 @@ public abstract class Behaviour : BehaviourBase if (!IsActive) return; - if (isInitializedThisFrame) - FirstActiveFrame(); - OnPreUpdate(); } - protected virtual void OnFirstActiveFrame() { } - protected virtual void FirstActiveFrame() - { - OnFirstActiveFrame(); - isInitializedThisFrame = false; - } - protected virtual void OnUpdatePreActiveCheck() { } protected virtual void OnUpdate() { } - protected virtual void Update(IBehaviourController _) + void IUpdate.Update() { Debug.Assert.AssertInitialized(this); @@ -87,9 +76,23 @@ public abstract class Behaviour : BehaviourBase 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() { } - protected virtual void PreDraw(IBehaviourController _) + void IPreDraw.PreDraw() { Debug.Assert.AssertInitialized(this); @@ -101,6 +104,34 @@ public abstract class Behaviour : BehaviourBase 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); diff --git a/Engine.Core/Behaviour2D.cs b/Engine.Core/Behaviour2D.cs index e82177c..f7be439 100644 --- a/Engine.Core/Behaviour2D.cs +++ b/Engine.Core/Behaviour2D.cs @@ -17,10 +17,6 @@ public abstract class Behaviour2D : Behaviour, IBehaviour2D } protected sealed override void OnUnassign(IAssignable assignable) => base.OnUnassign(assignable); - protected sealed override void PreUpdate(IBehaviourController behaviourController) => base.PreUpdate(behaviourController); - protected sealed override void FirstActiveFrame() => base.FirstActiveFrame(); - protected sealed override void Update(IBehaviourController behaviourController) => base.Update(behaviourController); - protected sealed override void PreDraw(IBehaviourController behaviourController) => base.PreDraw(behaviourController); protected sealed override void EnteredUniverse(IUniverseObject sender, IUniverse universe) => base.EnteredUniverse(sender, universe); protected sealed override void ExitedUniverse(IUniverseObject sender, IUniverse universe) => base.ExitedUniverse(sender, universe); } diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 3e70684..b99aad7 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -8,10 +8,6 @@ namespace Syntriax.Engine.Core; [System.Diagnostics.DebuggerDisplay("Behaviour Count: {behaviours.Count}")] public class BehaviourController : BaseEntity, IBehaviourController { - public event IBehaviourController.PreUpdateEventHandler? OnPreUpdate = null; - public event IBehaviourController.UpdateEventHandler? OnUpdate = null; - public event IBehaviourController.PreDrawEventHandler? OnPreDraw = null; - public event IBehaviourController.BehaviourAddedEventHandler? OnBehaviourAdded = null; public event IBehaviourController.BehaviourRemovedEventHandler? OnBehaviourRemoved = null; public event IHasUniverseObject.UniverseObjectAssignedEventHandler? OnUniverseObjectAssigned = null; @@ -128,27 +124,6 @@ public class BehaviourController : BaseEntity, IBehaviourController behaviour.Finalize(); } - public void Update() - { - Debug.Assert.AssertInitialized(this); - - if (!UniverseObject.StateEnable.Enabled || !StateEnable.Enabled) - return; - - OnPreUpdate?.InvokeSafe(this); - OnUpdate?.InvokeSafe(this); - } - - public void UpdatePreDraw() - { - Debug.Assert.AssertInitialized(this); - - if (!UniverseObject.StateEnable.Enabled || !StateEnable.Enabled) - return; - - OnPreDraw?.InvokeSafe(this); - } - public BehaviourController() { } public BehaviourController(IUniverseObject universeObject) => Assign(universeObject); diff --git a/Engine.Core/Systems/Abstract/IDraw.cs b/Engine.Core/Systems/Abstract/IDraw.cs new file mode 100644 index 0000000..7347895 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IDraw.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IDraw : IBehaviour +{ + void Draw(); +} diff --git a/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs b/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs new file mode 100644 index 0000000..d3abd57 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IFirstFrameUpdate.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IFirstFrameUpdate : IBehaviour +{ + void FirstActiveFrame(); +} diff --git a/Engine.Core/Systems/Abstract/IPostDraw.cs b/Engine.Core/Systems/Abstract/IPostDraw.cs new file mode 100644 index 0000000..e1b140f --- /dev/null +++ b/Engine.Core/Systems/Abstract/IPostDraw.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IPostDraw : IBehaviour +{ + void PostDraw(); +} diff --git a/Engine.Core/Systems/Abstract/IPostUpdate.cs b/Engine.Core/Systems/Abstract/IPostUpdate.cs new file mode 100644 index 0000000..e86f2e9 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IPostUpdate.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IPostUpdate : IBehaviour +{ + void PostUpdate(); +} diff --git a/Engine.Core/Systems/Abstract/IPreDraw.cs b/Engine.Core/Systems/Abstract/IPreDraw.cs new file mode 100644 index 0000000..81596d9 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IPreDraw.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IPreDraw : IBehaviour +{ + void PreDraw(); +} diff --git a/Engine.Core/Systems/Abstract/IPreUpdate.cs b/Engine.Core/Systems/Abstract/IPreUpdate.cs new file mode 100644 index 0000000..31d62e7 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IPreUpdate.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IPreUpdate : IBehaviour +{ + void PreUpdate(); +} diff --git a/Engine.Core/Systems/Abstract/IUpdate.cs b/Engine.Core/Systems/Abstract/IUpdate.cs new file mode 100644 index 0000000..989ebf1 --- /dev/null +++ b/Engine.Core/Systems/Abstract/IUpdate.cs @@ -0,0 +1,6 @@ +namespace Syntriax.Engine.Core; + +public interface IUpdate : IBehaviour +{ + void Update(); +} diff --git a/Engine.Core/Systems/DrawManager.cs b/Engine.Core/Systems/DrawManager.cs new file mode 100644 index 0000000..bad774c --- /dev/null +++ b/Engine.Core/Systems/DrawManager.cs @@ -0,0 +1,49 @@ + +namespace Syntriax.Engine.Core; + +public class DrawManager : UniverseObject +{ + private readonly BehaviourCollector preDrawEntities = new(); + private readonly BehaviourCollector drawEntities = new(); + private readonly BehaviourCollector postDrawEntities = new(); + + private void OnPreDraw(IUniverse sender) + { + for (int i = preDrawEntities.Behaviours.Count - 1; i >= 0; i--) + preDrawEntities.Behaviours[i].PreDraw(); + } + + private void OnDraw(IUniverse sender) + { + for (int i = drawEntities.Behaviours.Count - 1; i >= 0; i--) + drawEntities.Behaviours[i].Draw(); + } + + private void OnPostDraw(IUniverse sender) + { + for (int i = postDrawEntities.Behaviours.Count - 1; i >= 0; i--) + postDrawEntities.Behaviours[i].PostDraw(); + } + + protected override void OnEnteringUniverse(IUniverse universe) + { + preDrawEntities.Assign(universe); + drawEntities.Assign(universe); + postDrawEntities.Assign(universe); + + universe.OnPreDraw += OnPreDraw; + universe.OnDraw += OnDraw; + universe.OnPostDraw += OnPostDraw; + } + + protected override void OnExitingUniverse(IUniverse universe) + { + preDrawEntities.Unassign(); + drawEntities.Unassign(); + postDrawEntities.Unassign(); + + universe.OnPreDraw -= OnPreDraw; + universe.OnDraw -= OnDraw; + universe.OnPostDraw -= OnPostDraw; + } +} diff --git a/Engine.Core/Systems/UpdateManager.cs b/Engine.Core/Systems/UpdateManager.cs new file mode 100644 index 0000000..a2371f5 --- /dev/null +++ b/Engine.Core/Systems/UpdateManager.cs @@ -0,0 +1,69 @@ + +using System.Collections.Generic; + +namespace Syntriax.Engine.Core; + +public class UpdateManager : UniverseObject +{ + private readonly BehaviourCollector firstFrameUpdates = new(); + private readonly BehaviourCollector preUpdateEntities = new(); + private readonly BehaviourCollector updateEntities = new(); + private readonly BehaviourCollector postUpdateEntities = new(); + + private readonly List toCallFirstFrameUpdates = []; + + protected override void OnEnteringUniverse(IUniverse universe) + { + firstFrameUpdates.Assign(universe); + preUpdateEntities.Assign(universe); + updateEntities.Assign(universe); + postUpdateEntities.Assign(universe); + + universe.OnPreUpdate += OnPreUpdate; + universe.OnUpdate += OnUpdate; + universe.OnPostUpdate += OnPostUpdate; + } + + protected override void OnExitingUniverse(IUniverse universe) + { + firstFrameUpdates.Unassign(); + preUpdateEntities.Unassign(); + updateEntities.Unassign(); + postUpdateEntities.Unassign(); + + universe.OnPreUpdate -= OnPreUpdate; + universe.OnUpdate -= OnUpdate; + universe.OnPostUpdate -= OnPostUpdate; + } + + private void OnPreUpdate(IUniverse sender, UniverseTime engineTime) + { + for (int i = toCallFirstFrameUpdates.Count - 1; i >= 0; i--) + toCallFirstFrameUpdates[i].FirstActiveFrame(); + + for (int i = preUpdateEntities.Behaviours.Count - 1; i >= 0; i--) + preUpdateEntities.Behaviours[i].PreUpdate(); + } + + private void OnUpdate(IUniverse sender, UniverseTime engineTime) + { + for (int i = updateEntities.Behaviours.Count - 1; i >= 0; i--) + updateEntities.Behaviours[i].Update(); + } + + private void OnPostUpdate(IUniverse sender, UniverseTime engineTime) + { + for (int i = postUpdateEntities.Behaviours.Count - 1; i >= 0; i--) + postUpdateEntities.Behaviours[i].PostUpdate(); + } + + private void OnFirstFrameCollected(IBehaviourCollector sender, IFirstFrameUpdate behaviourCollected) + { + toCallFirstFrameUpdates.Add(behaviourCollected); + } + + public UpdateManager() + { + firstFrameUpdates.OnCollected += OnFirstFrameCollected; + } +} diff --git a/Engine.Core/Universe.cs b/Engine.Core/Universe.cs index c94237a..72c938f 100644 --- a/Engine.Core/Universe.cs +++ b/Engine.Core/Universe.cs @@ -119,10 +119,6 @@ public class Universe : BaseEntity, IUniverse Time = new(TimeSpan.FromTicks((long)(Time.TimeSinceStart.Ticks + engineTime.DeltaSpan.Ticks * TimeScale)), TimeSpan.FromTicks((long)(engineTime.DeltaSpan.Ticks * TimeScale))); OnPreUpdate?.InvokeSafe(this, Time); - - for (int i = 0; i < UniverseObjects.Count; i++) - UniverseObjects[i].BehaviourController.Update(); - OnUpdate?.InvokeSafe(this, Time); OnPostUpdate?.InvokeSafe(this, Time); } @@ -131,9 +127,6 @@ public class Universe : BaseEntity, IUniverse { Debug.Assert.AssertInitialized(this); - for (int i = 0; i < UniverseObjects.Count; i++) - UniverseObjects[i].BehaviourController.UpdatePreDraw(); - OnPreDraw?.InvokeSafe(this); OnDraw?.InvokeSafe(this); OnPostDraw?.InvokeSafe(this);