From 66dddbcf71a00a7c71abccc2be9a846bb407add1 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 10 Feb 2024 15:44:09 -0500 Subject: [PATCH] Create `IOpenDreamGameTiming` --- Content.Tests/ContentUnitTest.cs | 5 ++-- Content.Tests/DMTests.cs | 12 ++++++++- Content.Tests/DummyOpenDreamGameTiming.cs | 26 +++++++++++++++++++ .../Rendering/ClientImagesSystem.cs | 1 - OpenDreamRuntime/DreamManager.cs | 2 +- .../Objects/Types/DreamObjectWorld.cs | 5 ++-- .../Procs/IOpenDreamGameTiming.cs | 15 +++++++++++ OpenDreamRuntime/Procs/OpenDreamGameTiming.cs | 20 ++++++++++++++ .../Procs/ProcScheduler.Delays.cs | 2 +- OpenDreamRuntime/ServerContentIoC.cs | 1 + 10 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 Content.Tests/DummyOpenDreamGameTiming.cs create mode 100644 OpenDreamRuntime/Procs/IOpenDreamGameTiming.cs create mode 100644 OpenDreamRuntime/Procs/OpenDreamGameTiming.cs diff --git a/Content.Tests/ContentUnitTest.cs b/Content.Tests/ContentUnitTest.cs index c102584fb66..647d58e07e6 100644 --- a/Content.Tests/ContentUnitTest.cs +++ b/Content.Tests/ContentUnitTest.cs @@ -3,8 +3,8 @@ using System.Reflection; using OpenDreamClient; using OpenDreamRuntime; +using OpenDreamRuntime.Procs; using OpenDreamRuntime.Rendering; -using OpenDreamShared; using OpenDreamShared.Rendering; using Robust.Shared.Analyzers; using Robust.Shared.IoC; @@ -23,11 +23,10 @@ public class ContentUnitTest : RobustUnitTest { protected override void OverrideIoC() { base.OverrideIoC(); - SharedOpenDreamIoC.Register(); - if (Project == UnitTestProject.Server) { ServerContentIoC.Register(unitTests: true); IoCManager.Register(); + IoCManager.Register(); } else if (Project == UnitTestProject.Client) { ClientContentIoC.Register(); } diff --git a/Content.Tests/DMTests.cs b/Content.Tests/DMTests.cs index 079b1188b14..13685ca838e 100644 --- a/Content.Tests/DMTests.cs +++ b/Content.Tests/DMTests.cs @@ -19,10 +19,14 @@ public sealed class DMTests : ContentUnitTest { private const string InitializeEnvironment = "./environment.dme"; private const string TestsDirectory = "Tests"; + [Dependency] IOpenDreamGameTiming _gameTiming = default!; [Dependency] private readonly DreamManager _dreamMan = default!; [Dependency] private readonly DreamObjectTree _objectTree = default!; [Dependency] private readonly ProcScheduler _procScheduler = default!; [Dependency] private readonly ITaskManager _taskManager = default!; + [Dependency] private readonly IGameTiming gameTiming = default!; + + DummyOpenDreamGameTiming GameTiming => (DummyOpenDreamGameTiming)_gameTiming; [Flags] public enum DMTestFlags { @@ -74,6 +78,7 @@ public void TestFiles(string sourceFile, DMTestFlags testFlags) { } _procScheduler.ClearState(); + GameTiming.CurTick = GameTick.Zero; Assert.That(compiledFile is not null && File.Exists(compiledFile), "Failed to compile DM source file"); Assert.That(_dreamMan.LoadJson(compiledFile), $"Failed to load {compiledFile}"); @@ -81,10 +86,13 @@ public void TestFiles(string sourceFile, DMTestFlags testFlags) { (bool successfulRun, DreamValue? returned, Exception? exception) = RunTest(); + int expectedThreads; if (testFlags.HasFlag(DMTestFlags.NoReturn)) { Assert.That(returned.HasValue, Is.False, "proc returned unexpectedly"); + expectedThreads = 1; } else { Assert.That(returned.HasValue, "proc did not return (did it hit an exception?)"); + expectedThreads = 0; } if (testFlags.HasFlag(DMTestFlags.RuntimeError)) { @@ -101,7 +109,7 @@ public void TestFiles(string sourceFile, DMTestFlags testFlags) { } var threads = _procScheduler.InspectThreads().ToList(); - Assert.That(threads.Count == 0 && !_procScheduler.HasProcsSleeping && !_procScheduler.HasProcsQueued, $"One or more threads did not finish!"); + Assert.That(threads.Count == expectedThreads && !_procScheduler.HasProcsSleeping && !_procScheduler.HasProcsQueued, $"One or more threads did not finish!"); Cleanup(compiledFile); TestContext.WriteLine($"--- PASS {sourceFile}"); @@ -136,6 +144,8 @@ public void TestFiles(string sourceFile, DMTestFlags testFlags) { _dreamMan.Update(); _taskManager.ProcessPendingTasks(); + GameTiming.CurTick = new GameTick(_gameTiming.CurTick.Value + 1); + if (watch.Elapsed.TotalSeconds > 5) { Assert.Fail("Test timed out"); } diff --git a/Content.Tests/DummyOpenDreamGameTiming.cs b/Content.Tests/DummyOpenDreamGameTiming.cs new file mode 100644 index 00000000000..8df783dbc50 --- /dev/null +++ b/Content.Tests/DummyOpenDreamGameTiming.cs @@ -0,0 +1,26 @@ +using OpenDreamRuntime.Procs; + +using Robust.Shared.IoC; +using Robust.Shared.Timing; + +using System; + +namespace Content.Tests { + sealed class DummyOpenDreamGameTiming : IOpenDreamGameTiming { + + [Dependency] IGameTiming gameTiming = null!; + + public GameTick CurTick { get; set; } + + public TimeSpan LastTick => gameTiming.LastTick; + + public TimeSpan RealTime => gameTiming.RealTime; + + public TimeSpan TickPeriod => gameTiming.TickPeriod; + + public byte TickRate { + get => gameTiming.TickRate; + set => gameTiming.TickRate = value; + } + } +} diff --git a/OpenDreamClient/Rendering/ClientImagesSystem.cs b/OpenDreamClient/Rendering/ClientImagesSystem.cs index 81d702ff9c8..323ff80b1c0 100644 --- a/OpenDreamClient/Rendering/ClientImagesSystem.cs +++ b/OpenDreamClient/Rendering/ClientImagesSystem.cs @@ -6,7 +6,6 @@ namespace OpenDreamClient.Rendering; internal sealed class ClientImagesSystem : SharedClientImagesSystem { [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly ClientAppearanceSystem _appearanceSystem = default!; private readonly Dictionary> _turfClientImages = new(); diff --git a/OpenDreamRuntime/DreamManager.cs b/OpenDreamRuntime/DreamManager.cs index 744eb192a30..0f474a7b8b5 100644 --- a/OpenDreamRuntime/DreamManager.cs +++ b/OpenDreamRuntime/DreamManager.cs @@ -27,7 +27,7 @@ public sealed partial class DreamManager { [Dependency] private readonly ProcScheduler _procScheduler = default!; [Dependency] private readonly DreamResourceManager _dreamResourceManager = default!; [Dependency] private readonly ITaskManager _taskManager = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IOpenDreamGameTiming _gameTiming = default!; [Dependency] private readonly DreamObjectTree _objectTree = default!; [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectWorld.cs b/OpenDreamRuntime/Objects/Types/DreamObjectWorld.cs index 0ac9914d473..f36e5551ca1 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectWorld.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectWorld.cs @@ -1,5 +1,7 @@ using System.Net; using System.Net.Sockets; + +using OpenDreamRuntime.Procs; using OpenDreamRuntime.Procs.Native; using OpenDreamRuntime.Resources; using OpenDreamShared; @@ -8,7 +10,6 @@ using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.Network; -using Robust.Shared.Timing; namespace OpenDreamRuntime.Objects.Types; @@ -16,7 +17,7 @@ public sealed class DreamObjectWorld : DreamObject { public override bool ShouldCallNew => false; // Gets called manually later [Dependency] private readonly IBaseServer _server = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IOpenDreamGameTiming _gameTiming = default!; [Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; diff --git a/OpenDreamRuntime/Procs/IOpenDreamGameTiming.cs b/OpenDreamRuntime/Procs/IOpenDreamGameTiming.cs new file mode 100644 index 00000000000..3a2fd94daed --- /dev/null +++ b/OpenDreamRuntime/Procs/IOpenDreamGameTiming.cs @@ -0,0 +1,15 @@ +using Robust.Shared.Timing; + +namespace OpenDreamRuntime.Procs { + public interface IOpenDreamGameTiming { + public GameTick CurTick { get; } + + public TimeSpan LastTick { get; } + + public TimeSpan RealTime { get; } + + public TimeSpan TickPeriod { get; } + + public byte TickRate { get; set; } + } +} diff --git a/OpenDreamRuntime/Procs/OpenDreamGameTiming.cs b/OpenDreamRuntime/Procs/OpenDreamGameTiming.cs new file mode 100644 index 00000000000..27f7778454e --- /dev/null +++ b/OpenDreamRuntime/Procs/OpenDreamGameTiming.cs @@ -0,0 +1,20 @@ +using Robust.Shared.Timing; + +namespace OpenDreamRuntime.Procs { + sealed class OpenDreamGameTiming : IOpenDreamGameTiming { + [Dependency] private readonly IGameTiming _gameTiming = default!; + + public GameTick CurTick => _gameTiming.CurTick; + + public TimeSpan LastTick => _gameTiming.LastTick; + + public TimeSpan RealTime => _gameTiming.RealTime; + + public TimeSpan TickPeriod => _gameTiming.TickPeriod; + + public byte TickRate { + get => _gameTiming.TickRate; + set => _gameTiming.TickRate = value; + } + } +} diff --git a/OpenDreamRuntime/Procs/ProcScheduler.Delays.cs b/OpenDreamRuntime/Procs/ProcScheduler.Delays.cs index de2382e8324..3abbda97185 100644 --- a/OpenDreamRuntime/Procs/ProcScheduler.Delays.cs +++ b/OpenDreamRuntime/Procs/ProcScheduler.Delays.cs @@ -6,7 +6,7 @@ namespace OpenDreamRuntime.Procs; // Handles delay processing for sleep() and spawn(). public sealed partial class ProcScheduler { - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IOpenDreamGameTiming _gameTiming = default!; private PriorityQueue _tickers = new(); diff --git a/OpenDreamRuntime/ServerContentIoC.cs b/OpenDreamRuntime/ServerContentIoC.cs index 77ec1706bff..65c95d26d8a 100644 --- a/OpenDreamRuntime/ServerContentIoC.cs +++ b/OpenDreamRuntime/ServerContentIoC.cs @@ -22,6 +22,7 @@ public static void Register(bool unitTests = false) { if (!unitTests) { // Unit tests use their own version IoCManager.Register(); + IoCManager.Register(); } } }