diff --git a/OpenDreamRuntime/AtomManager.cs b/OpenDreamRuntime/AtomManager.cs index 699dc4fbc86..56d299a415e 100644 --- a/OpenDreamRuntime/AtomManager.cs +++ b/OpenDreamRuntime/AtomManager.cs @@ -173,7 +173,7 @@ public IconAppearance CreateAppearanceFromDefinition(DreamObjectDefinition def) } } - internal interface IAtomManager { + public interface IAtomManager { public Dictionary OverlaysListToAtom { get; } public Dictionary UnderlaysListToAtom { get; } diff --git a/OpenDreamRuntime/DreamManager.cs b/OpenDreamRuntime/DreamManager.cs index bdb38476253..96c12d44005 100644 --- a/OpenDreamRuntime/DreamManager.cs +++ b/OpenDreamRuntime/DreamManager.cs @@ -4,6 +4,7 @@ using OpenDreamRuntime.Objects; using OpenDreamRuntime.Objects.MetaObjects; using OpenDreamRuntime.Procs; +using OpenDreamRuntime.Procs.DebugAdapter; using OpenDreamRuntime.Procs.Native; using OpenDreamRuntime.Resources; using OpenDreamShared; @@ -20,9 +21,12 @@ partial class DreamManager : IDreamManager { [Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IDreamMapManager _dreamMapManager = default!; + [Dependency] private readonly IDreamDebugManager _dreamDebugManager = default!; [Dependency] private readonly IProcScheduler _procScheduler = default!; [Dependency] private readonly DreamResourceManager _dreamResourceManager = default!; [Dependency] private readonly IDreamObjectTree _objectTree = default!; + [Dependency] private readonly ITaskManager _taskManager = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; public DreamObject WorldInstance { get; private set; } public Exception? LastDMException { get; set; } @@ -48,18 +52,21 @@ public void PreInitialize(string jsonPath) { _dreamResourceManager.Initialize(); if (!LoadJson(jsonPath)) { - IoCManager.Resolve().RunOnMainThread(() => { IoCManager.Resolve().Shutdown("Error while loading the compiled json. The opendream.json_path CVar may be empty, or points to a file that doesn't exist"); }); + _taskManager.RunOnMainThread(() => { IoCManager.Resolve().Shutdown("Error while loading the compiled json. The opendream.json_path CVar may be empty, or points to a file that doesn't exist"); }); } } public void StartWorld() { // It is now OK to call user code, like /New procs. Initialized = true; - InitializedTick = IoCManager.Resolve().CurTick; + InitializedTick = _gameTiming.CurTick; // Call global with waitfor=FALSE if (_compiledJson.GlobalInitProc is ProcDefinitionJson initProcDef) { - var globalInitProc = new DMProc(DreamPath.Root, "(global init)", null, null, null, initProcDef.Bytecode, initProcDef.MaxStackSize, initProcDef.Attributes, initProcDef.VerbName, initProcDef.VerbCategory, initProcDef.VerbDesc, initProcDef.Invisibility, _objectTree, _dreamResourceManager); + var globalInitProc = new DMProc(DreamPath.Root, "(global init)", null, null, null, initProcDef.Bytecode, + initProcDef.MaxStackSize, initProcDef.Attributes, initProcDef.VerbName, initProcDef.VerbCategory, + initProcDef.VerbDesc, initProcDef.Invisibility, this, _objectTree, _dreamMapManager, _dreamDebugManager, + _dreamResourceManager); globalInitProc.Spawn(WorldInstance, new DreamProcArguments()); } diff --git a/OpenDreamRuntime/DreamThread.cs b/OpenDreamRuntime/DreamThread.cs index e18b6229297..74e4ae9eb1e 100644 --- a/OpenDreamRuntime/DreamThread.cs +++ b/OpenDreamRuntime/DreamThread.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using OpenDreamRuntime.Objects; using OpenDreamRuntime.Procs; +using OpenDreamRuntime.Procs.DebugAdapter; +using OpenDreamRuntime.Resources; using OpenDreamShared.Dream; using OpenDreamShared.Dream.Procs; @@ -31,6 +33,11 @@ public abstract class DreamProc { public string? VerbDesc { get; } public sbyte? Invisibility { get; } + internal abstract IDreamManager DreamManager { get; } + internal abstract IDreamMapManager DreamMapManager { get; } + internal abstract IDreamDebugManager DreamDebugManager { get; } + internal abstract DreamResourceManager DreamResourceManager { get; } + protected DreamProc(DreamPath owningType, string name, DreamProc superProc, ProcAttributes attributes, List? argumentNames, List? argumentTypes, string? verbName, string? verbCategory, string? verbDesc, sbyte? invisibility) { OwningType = owningType; Name = name; diff --git a/OpenDreamRuntime/Objects/DreamIcon.cs b/OpenDreamRuntime/Objects/DreamIcon.cs index a19747a7a75..d747895460b 100644 --- a/OpenDreamRuntime/Objects/DreamIcon.cs +++ b/OpenDreamRuntime/Objects/DreamIcon.cs @@ -358,7 +358,7 @@ public sealed class DreamIconOperationBlendImage : DreamIconOperationBlend { public DreamIconOperationBlendImage(BlendType type, int xOffset, int yOffset, DreamValue blending) : base(type, xOffset, yOffset) { var objectTree = IoCManager.Resolve(); - var resourceManager = IoCManager.Resolve(); + var resourceManager = IoCManager.Resolve(); //TODO: Find a way to get rid of this! (var blendingResource, _blendingDescription) = DreamMetaObjectIcon.GetIconResourceAndDescription(objectTree, resourceManager, blending); _blending = resourceManager.LoadImage(blendingResource); } diff --git a/OpenDreamRuntime/Objects/DreamObjectTree.cs b/OpenDreamRuntime/Objects/DreamObjectTree.cs index bccaf0c0d28..ede396aa8f4 100644 --- a/OpenDreamRuntime/Objects/DreamObjectTree.cs +++ b/OpenDreamRuntime/Objects/DreamObjectTree.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using OpenDreamRuntime.Objects.MetaObjects; using OpenDreamRuntime.Procs; +using OpenDreamRuntime.Procs.DebugAdapter; using OpenDreamRuntime.Resources; using OpenDreamShared.Dream; using OpenDreamShared.Dream.Procs; @@ -39,6 +40,10 @@ public sealed class DreamObjectTree : IDreamObjectTree { private Dictionary _globalProcIds; [Dependency] private readonly DreamResourceManager _resourceManager = default!; + [Dependency] private readonly IDreamManager DreamManager = default!; + [Dependency] private readonly IDreamMapManager DreamMapManager = default!; + [Dependency] private readonly IDreamDebugManager DreamDebugManager = default!; + [Dependency] private readonly DreamResourceManager DreamResourceManager = default!; public void LoadJson(DreamCompiledJson json) { Strings = json.Strings; @@ -298,7 +303,10 @@ public DreamProc LoadProcJson(DreamTypeJson[] types, ProcDefinitionJson procDefi } DreamPath owningType = new DreamPath(types[procDefinition.OwningTypeId].Path); - var proc = new DMProc(owningType, procDefinition.Name, null, argumentNames, argumentTypes, bytecode, procDefinition.MaxStackSize, procDefinition.Attributes, procDefinition.VerbName, procDefinition.VerbCategory, procDefinition.VerbDesc, procDefinition.Invisibility, this, _resourceManager); + var proc = new DMProc(owningType, procDefinition.Name, null, argumentNames, argumentTypes, bytecode, + procDefinition.MaxStackSize, procDefinition.Attributes, procDefinition.VerbName, + procDefinition.VerbCategory, procDefinition.VerbDesc, procDefinition.Invisibility, DreamManager, + this, DreamMapManager, DreamDebugManager, DreamResourceManager); proc.Source = procDefinition.Source; proc.Line = procDefinition.Line; return proc; diff --git a/OpenDreamRuntime/Objects/MetaObjects/DreamMetaObjectAtom.cs b/OpenDreamRuntime/Objects/MetaObjects/DreamMetaObjectAtom.cs index 6cabf6d0012..fd0c5a50c92 100644 --- a/OpenDreamRuntime/Objects/MetaObjects/DreamMetaObjectAtom.cs +++ b/OpenDreamRuntime/Objects/MetaObjects/DreamMetaObjectAtom.cs @@ -2,6 +2,7 @@ using OpenDreamRuntime.Rendering; using OpenDreamRuntime.Resources; using OpenDreamShared.Dream; +using Robust.Shared.Serialization.Manager; namespace OpenDreamRuntime.Objects.MetaObjects { sealed class DreamMetaObjectAtom : IDreamMetaObject { diff --git a/OpenDreamRuntime/Procs/AsyncNativeProc.cs b/OpenDreamRuntime/Procs/AsyncNativeProc.cs index fde5fa117fa..4e6ce204f38 100644 --- a/OpenDreamRuntime/Procs/AsyncNativeProc.cs +++ b/OpenDreamRuntime/Procs/AsyncNativeProc.cs @@ -1,6 +1,8 @@ using System.Text; using System.Threading.Tasks; using OpenDreamRuntime.Objects; +using OpenDreamRuntime.Procs.DebugAdapter; +using OpenDreamRuntime.Resources; using OpenDreamShared.Dream; using OpenDreamShared.Dream.Procs; @@ -151,15 +153,22 @@ public override void AppendStackFrame(StringBuilder builder) private Dictionary _defaultArgumentValues; private Func> _taskFunc; - private AsyncNativeProc() - : base(DreamPath.Root, "", null, ProcAttributes.DisableWaitfor, null, null, null, null, null, null) - {} + [Dependency] private readonly IDreamManager _dreamManager; + internal override IDreamManager DreamManager => _dreamManager; + [Dependency] private readonly IDreamMapManager _dreamMapManager; + internal override IDreamMapManager DreamMapManager => _dreamMapManager; + [Dependency] private readonly IDreamDebugManager _dreamDebugManager; + internal override IDreamDebugManager DreamDebugManager => _dreamDebugManager; + [Dependency] private readonly DreamResourceManager _dreamResourceManager; + internal override DreamResourceManager DreamResourceManager => _dreamResourceManager; public AsyncNativeProc(DreamPath owningType, string name, DreamProc superProc, List argumentNames, List argumentTypes, Dictionary defaultArgumentValues, Func> taskFunc, string? verbName, string? verbCategory, string? verbDesc, sbyte? invisibility) : base(owningType, name, superProc, ProcAttributes.None, argumentNames, argumentTypes, verbName, verbCategory, verbDesc, invisibility) { + IoCManager.InjectDependencies(this); // i gave up on passing in the iocs as args here due to access related issues, IDreamDebugManager is internal. _defaultArgumentValues = defaultArgumentValues; _taskFunc = taskFunc; + } public override ProcState CreateState(DreamThread thread, DreamObject src, DreamObject usr, DreamProcArguments arguments) diff --git a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs index 914110e4111..435c1311410 100644 --- a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs +++ b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs @@ -152,8 +152,7 @@ private static DreamValue[] GetEnumerableContents(IDreamObjectTree objectTree, D if (!loc.TryGetValueAsDreamObjectOfType(state.Proc.ObjectTree.Turf, out var turf)) throw new Exception($"Invalid turf loc {loc}"); - IDreamMapManager dreamMapManager = IoCManager.Resolve(); - dreamMapManager.SetTurf(turf, objectDef, arguments); + state.Proc.DreamMapManager.SetTurf(turf, objectDef, arguments); state.Push(loc); return null; @@ -545,7 +544,7 @@ private static void HandleSuffixPronoun(ref StringBuilder formattedString, ReadO public static ProcStatus? PushResource(DMProcState state) { string resourcePath = state.ReadString(); - state.Push(new DreamValue(IoCManager.Resolve().LoadResource(resourcePath))); + state.Push(new DreamValue(state.Proc.DreamResourceManager.LoadResource(resourcePath))); return null; } @@ -1338,7 +1337,7 @@ private static void HandleSuffixPronoun(ref StringBuilder formattedString, ReadO throw new Exception($"{popProc} is not a valid proc name"); } // DLL Invoke - var entryPoint = DllHelper.ResolveDllTarget(IoCManager.Resolve(), dllName, procName); + var entryPoint = DllHelper.ResolveDllTarget(state.Proc.DreamResourceManager, dllName, procName); Span argV = stackalloc nint[arguments.ArgumentCount]; argV.Fill(0); @@ -1749,7 +1748,7 @@ private static void PerformOutput(DreamValue a, DreamValue b) { if (x.TryGetValueAsInteger(out var xInt) && y.TryGetValueAsInteger(out var yInt) && z.TryGetValueAsInteger(out var zInt)) { - IoCManager.Resolve().TryGetTurfAt((xInt, yInt), zInt, out var turf); + state.Proc.DreamMapManager.TryGetTurfAt((xInt, yInt), zInt, out var turf); state.Push(new DreamValue(turf)); } else diff --git a/OpenDreamRuntime/Procs/DMProc.cs b/OpenDreamRuntime/Procs/DMProc.cs index 0260ed861d6..f6e9f381f65 100644 --- a/OpenDreamRuntime/Procs/DMProc.cs +++ b/OpenDreamRuntime/Procs/DMProc.cs @@ -9,8 +9,6 @@ namespace OpenDreamRuntime.Procs { sealed class DMProc : DreamProc { - public readonly IDreamObjectTree ObjectTree; - public readonly DreamResourceManager ResourceManager; public byte[] Bytecode { get; } private readonly int _maxStackSize; @@ -18,10 +16,20 @@ sealed class DMProc : DreamProc { public string? Source { get; set; } public int Line { get; set; } - public DMProc(DreamPath owningType, string name, DreamProc superProc, List argumentNames, List argumentTypes, byte[] bytecode, int maxStackSize, ProcAttributes attributes, string? verbName, string? verbCategory, string? verbDesc, sbyte? invisibility, IDreamObjectTree objectTree, DreamResourceManager resourceManager) + public readonly IDreamManager DreamManager; + public readonly IDreamObjectTree ObjectTree; + public readonly IDreamMapManager DreamMapManager; + public readonly IDreamDebugManager DreamDebugManager; + public readonly DreamResourceManager ResourceManager; + + public DMProc(DreamPath owningType, string name, DreamProc superProc, List argumentNames, List argumentTypes, byte[] bytecode, int maxStackSize, ProcAttributes attributes, string? verbName, string? verbCategory, string? verbDesc, sbyte? invisibility, IDreamManager dreamManager, IDreamObjectTree objectTree, IDreamMapManager dreamMapManager, IDreamDebugManager dreamDebugManager, DreamResourceManager dreamResourceManager) : base(owningType, name, superProc, attributes, argumentNames, argumentTypes, verbName, verbCategory, verbDesc, invisibility) { + + DreamManager = dreamManager; ObjectTree = objectTree; - ResourceManager = resourceManager; + DreamMapManager = dreamMapManager; + DreamDebugManager = dreamDebugManager; + ResourceManager = dreamResourceManager; Bytecode = bytecode; _maxStackSize = maxStackSize; } @@ -143,8 +151,8 @@ sealed class DMProcState : ProcState }; #endregion - public readonly IDreamManager DreamManager = IoCManager.Resolve(); - public readonly IDreamDebugManager DebugManager = IoCManager.Resolve(); + public IDreamManager DreamManager => _proc.DreamManager; + public IDreamDebugManager DebugManager => _proc.DreamDebugManager; /// This stores our 'src' value. May be null! public DreamObject? Instance; diff --git a/OpenDreamRuntime/Procs/DebugAdapter/DreamDebugManager.cs b/OpenDreamRuntime/Procs/DebugAdapter/DreamDebugManager.cs index 5431661809e..1e7962713df 100644 --- a/OpenDreamRuntime/Procs/DebugAdapter/DreamDebugManager.cs +++ b/OpenDreamRuntime/Procs/DebugAdapter/DreamDebugManager.cs @@ -434,7 +434,7 @@ private void HandleRequestVariables(DebugAdapterClient client, RequestVariables } } -interface IDreamDebugManager { +internal interface IDreamDebugManager { bool Stopped { get; } public void Initialize(int port); diff --git a/OpenDreamRuntime/Procs/NativeProc.cs b/OpenDreamRuntime/Procs/NativeProc.cs index b19e53fda10..7e772578d90 100644 --- a/OpenDreamRuntime/Procs/NativeProc.cs +++ b/OpenDreamRuntime/Procs/NativeProc.cs @@ -1,6 +1,8 @@ using System.Reflection; using System.Text; using OpenDreamRuntime.Objects; +using OpenDreamRuntime.Procs.DebugAdapter; +using OpenDreamRuntime.Resources; using OpenDreamShared.Dream; using OpenDreamShared.Dream.Procs; @@ -69,9 +71,20 @@ public override void AppendStackFrame(StringBuilder builder) private Dictionary _defaultArgumentValues; public HandlerFn Handler { get; } + [Dependency] private readonly IDreamManager _dreamManager; + internal override IDreamManager DreamManager => _dreamManager; + [Dependency] private readonly IDreamMapManager _dreamMapManager; + internal override IDreamMapManager DreamMapManager => _dreamMapManager; + [Dependency] private readonly IDreamDebugManager _dreamDebugManager; + internal override IDreamDebugManager DreamDebugManager => _dreamDebugManager; + [Dependency] private readonly DreamResourceManager _dreamResourceManager; + internal override DreamResourceManager DreamResourceManager => _dreamResourceManager; + + public NativeProc(DreamPath owningType, string name, DreamProc superProc, List argumentNames, List argumentTypes, Dictionary defaultArgumentValues, HandlerFn handler, string? verbName, string? verbCategory, string? verbDesc, sbyte? invisibility) : base(owningType, name, superProc, ProcAttributes.None, argumentNames, argumentTypes, verbName, verbCategory, verbDesc, invisibility) { + IoCManager.InjectDependencies(this); // i gave up on passing in the iocs as args here due to access related issues, IDreamDebugManager is internal. _defaultArgumentValues = defaultArgumentValues; Handler = handler; }