From 21eaaa4900a4437b87171c73050ba80874b4c8fe Mon Sep 17 00:00:00 2001 From: Michel Fedde Date: Wed, 17 Mar 2021 14:12:31 +0100 Subject: [PATCH] Added FixedUpdates --- SMCode/SM.Base/SM.Base.csproj | 2 + SMCode/SM.Base/Scene/GenericItemCollection.cs | 21 ++++++++++- SMCode/SM.Base/Scene/GenericScene.cs | 7 ++++ SMCode/SM.Base/Scene/IFixedScriptable.cs | 15 ++++++++ SMCode/SM.Base/Shaders/MaterialShader.cs | 20 ++++++++-- SMCode/SM.Base/Utility/Deltatime.cs | 33 +++++++++-------- .../Window/Contexts/FixedUpdateContext.cs | 13 +++++++ SMCode/SM.Base/Window/GLWindow.cs | 37 +++++++++++++++++-- 8 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 SMCode/SM.Base/Scene/IFixedScriptable.cs create mode 100644 SMCode/SM.Base/Window/Contexts/FixedUpdateContext.cs diff --git a/SMCode/SM.Base/SM.Base.csproj b/SMCode/SM.Base/SM.Base.csproj index 6faa593..c0887a0 100644 --- a/SMCode/SM.Base/SM.Base.csproj +++ b/SMCode/SM.Base/SM.Base.csproj @@ -66,6 +66,7 @@ + @@ -76,6 +77,7 @@ + diff --git a/SMCode/SM.Base/Scene/GenericItemCollection.cs b/SMCode/SM.Base/Scene/GenericItemCollection.cs index bc23520..e2694fa 100644 --- a/SMCode/SM.Base/Scene/GenericItemCollection.cs +++ b/SMCode/SM.Base/Scene/GenericItemCollection.cs @@ -5,6 +5,7 @@ using System.Collections.ObjectModel; using OpenTK; using SM.Base; using SM.Base.Drawing; +using SM.Base.Window.Contexts; using SM.Base.Windows; #endregion @@ -14,9 +15,10 @@ namespace SM.Base.Scene /// /// Contains a list of show items. /// - public abstract class GenericItemCollection : List, IShowItem, IShowCollection, IScriptable + public abstract class GenericItemCollection : List, IShowItem, IShowCollection, IScriptable, IFixedScriptable { private List _scriptableObjects = new List(); + private List _fixedScriptables = new List(); /// /// Currently active script objects. @@ -50,6 +52,16 @@ namespace SM.Base.Scene } } + public virtual void FixedUpdate(FixedUpdateContext context) + { + if (!Active || !UpdateActive) return; + + for (int i = 0; i < _fixedScriptables.Count; i++) + { + _fixedScriptables[i].FixedUpdate(context); + } + } + /// public virtual void Draw(DrawContext context) { @@ -83,6 +95,8 @@ namespace SM.Base.Scene if (item is IScriptable scriptable) AddScript(scriptable); + + if (item is IFixedScriptable fixedScriptable) _fixedScriptables.Add(fixedScriptable); } } @@ -103,6 +117,7 @@ namespace SM.Base.Scene public void AddScript(IScriptable item) { _scriptableObjects.Add(item); + if (item is IFixedScriptable fs) _fixedScriptables.Add(fs); } public new void Remove(params IShowItem[] items) @@ -113,6 +128,9 @@ namespace SM.Base.Scene if (item is IScriptable scriptable) RemoveScript(scriptable); + + if (item is IFixedScriptable fixedScriptable) + _fixedScriptables.Remove(fixedScriptable); } } @@ -134,6 +152,7 @@ namespace SM.Base.Scene public void RemoveScript(IScriptable item) { _scriptableObjects.Remove(item); + if (item is IFixedScriptable fs) _fixedScriptables.Remove(fs); } public ICollection GetAllItems(bool includeCollections = false) diff --git a/SMCode/SM.Base/Scene/GenericScene.cs b/SMCode/SM.Base/Scene/GenericScene.cs index 8c2796b..8777fe7 100644 --- a/SMCode/SM.Base/Scene/GenericScene.cs +++ b/SMCode/SM.Base/Scene/GenericScene.cs @@ -6,6 +6,7 @@ using System.Dynamic; using System.Windows.Controls; using SM.Base; using SM.Base.Drawing; +using SM.Base.Window.Contexts; using SM.Base.Windows; using SM.Utility; @@ -105,6 +106,12 @@ namespace SM.Base.Scene _hud?.Update(context); } + public virtual void FixedUpdate(FixedUpdateContext context) + { + _objectCollection?.FixedUpdate(context); + _hud?.FixedUpdate(context); + } + /// /// Draws this scene. /// diff --git a/SMCode/SM.Base/Scene/IFixedScriptable.cs b/SMCode/SM.Base/Scene/IFixedScriptable.cs new file mode 100644 index 0000000..e29f4ac --- /dev/null +++ b/SMCode/SM.Base/Scene/IFixedScriptable.cs @@ -0,0 +1,15 @@ +using SM.Base.Window.Contexts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SM.Base.Scene +{ + public interface IFixedScriptable + { + void FixedUpdate(FixedUpdateContext context); + + } +} diff --git a/SMCode/SM.Base/Shaders/MaterialShader.cs b/SMCode/SM.Base/Shaders/MaterialShader.cs index 504aea6..0798cbd 100644 --- a/SMCode/SM.Base/Shaders/MaterialShader.cs +++ b/SMCode/SM.Base/Shaders/MaterialShader.cs @@ -15,6 +15,8 @@ namespace SM.Base.Drawing /// public abstract class MaterialShader : GenericShader { + static bool _canLineWidth = true; + /// protected MaterialShader(string combinedData) : base(combinedData) {} @@ -39,10 +41,20 @@ namespace SM.Base.Drawing context.Mesh.Activate(); - if (context.Mesh is ILineMesh lineMesh) - GL.LineWidth(context.Material.ShaderArguments.Get("LineWidth", lineMesh.LineWidth)); - else if (context.Material.ShaderArguments.ContainsKey("LineWidth")) - GL.LineWidth((float)context.Material.ShaderArguments["LineWidth"]); + if (_canLineWidth) + { + try + { + if (context.Mesh is ILineMesh lineMesh) + GL.LineWidth(context.Material.ShaderArguments.Get("LineWidth", lineMesh.LineWidth)); + else if (context.Material.ShaderArguments.ContainsKey("LineWidth")) + GL.LineWidth((float)context.Material.ShaderArguments["LineWidth"]); + } + catch + { + _canLineWidth = false; + } + } if (context.Material.Blending) { diff --git a/SMCode/SM.Base/Utility/Deltatime.cs b/SMCode/SM.Base/Utility/Deltatime.cs index 125ab79..996f596 100644 --- a/SMCode/SM.Base/Utility/Deltatime.cs +++ b/SMCode/SM.Base/Utility/Deltatime.cs @@ -17,6 +17,24 @@ /// public bool UseRender; + + /// + /// The current update delta time. + /// + public static float UpdateDelta { get; internal set; } + + public static float FixedUpdateDelta { get; set; } + + /// + /// The current render delta time. + /// + public static float RenderDelta { get; internal set; } + + /// + /// The calculated delta time. + /// + public float DeltaTime => (UseRender ? RenderDelta : UpdateDelta) * Scale; + /// /// Creates a delta time assistant. /// @@ -30,20 +48,5 @@ UseRender = useRender; Scale = scale; } - - /// - /// The current update delta time. - /// - public static float UpdateDelta { get; internal set; } - - /// - /// The current render delta time. - /// - public static float RenderDelta { get; internal set; } - - /// - /// The calculated delta time. - /// - public float DeltaTime => (UseRender ? RenderDelta : UpdateDelta) * Scale; } } \ No newline at end of file diff --git a/SMCode/SM.Base/Window/Contexts/FixedUpdateContext.cs b/SMCode/SM.Base/Window/Contexts/FixedUpdateContext.cs new file mode 100644 index 0000000..f2b22e7 --- /dev/null +++ b/SMCode/SM.Base/Window/Contexts/FixedUpdateContext.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SM.Base.Window.Contexts +{ + public struct FixedUpdateContext + { + + } +} diff --git a/SMCode/SM.Base/Window/GLWindow.cs b/SMCode/SM.Base/Window/GLWindow.cs index 6f2521a..0a761d6 100644 --- a/SMCode/SM.Base/Window/GLWindow.cs +++ b/SMCode/SM.Base/Window/GLWindow.cs @@ -1,4 +1,7 @@ using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Threading; using System.Windows; using System.Windows.Forms; using OpenTK; @@ -6,7 +9,9 @@ using OpenTK.Graphics; using OpenTK.Input; using SM.Base.Controls; using SM.Base.Scene; +using SM.Base.Window.Contexts; using SM.OGL; +using SM.Utility; using Mouse = SM.Base.Controls.Mouse; namespace SM.Base.Windows @@ -14,6 +19,7 @@ namespace SM.Base.Windows public class GLWindow : GameWindow, IGenericWindow { private Vector2 _flagWindowSize; + private Thread _fixedUpdateThread; public bool Loading { get; private set; } = true; public float AspectRatio { get; set; } @@ -98,6 +104,12 @@ namespace SM.Base.Windows Mouse.MouseMoveEvent(e, this); } + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + _fixedUpdateThread.Abort(); + } + public void Update(UpdateContext context) { @@ -163,12 +175,29 @@ namespace SM.Base.Windows default: throw new ArgumentOutOfRangeException(nameof(newFlag), newFlag, null); } + } - if (newFlag == WindowFlags.BorderlessWindow) + public void RunFixedUpdate(float updatesPerSecond) + { + Deltatime.FixedUpdateDelta = 1 / (float)updatesPerSecond; + + _fixedUpdateThread = new Thread(ExecuteFixedUpdate); + _fixedUpdateThread.Start(); + } + + private void ExecuteFixedUpdate() + { + Stopwatch deltaStop = new Stopwatch(); + while (Thread.CurrentThread.ThreadState != System.Threading.ThreadState.AbortRequested) { - WindowBorder = WindowBorder.Hidden; - X = Screen.PrimaryScreen.Bounds.X; - Y = Screen.PrimaryScreen.Bounds.Y; + deltaStop.Restart(); + + FixedUpdateContext context = new FixedUpdateContext(); + + CurrentScene?.FixedUpdate(context); + + long delta = deltaStop.ElapsedMilliseconds; + Thread.Sleep(Math.Max((int)(Deltatime.FixedUpdateDelta * 1000) - (int)delta, 0)); } } }