From e7184729dfaae5fbae78dddf2ca161fa8102e407 Mon Sep 17 00:00:00 2001 From: Tony Bark Date: Tue, 18 Feb 2025 08:17:56 -0500 Subject: [PATCH] Slight refractor - Bumped unit tests to .NET 8 --- src/SimAI.Tests/SimAI.Tests.csproj | 27 ++- src/SimAI.Tests/VMClockTest.cs | 19 +- src/SimAI.Tests/VMTest.cs | 6 +- src/SimAI/Direction.cs | 18 +- src/SimAI/Engine/Entities/VMEntity.cs | 230 +++++++++--------- src/SimAI/Engine/VMMemory.cs | 8 +- src/SimAI/Engine/VMScheduler.cs | 24 +- src/SimAI/Engine/VMStackFrame.cs | 275 +++++++++++----------- src/SimAI/Engine/VMThread.cs | 48 ++-- src/SimAI/GlobalUsing.cs | 5 +- src/SimAI/IVM.cs | 12 +- src/SimAI/Interfaces/VMIMotiveDecay.cs | 4 +- src/SimAI/Interfaces/VMSerializable.cs | 2 +- src/SimAI/Marshals/VMMarshal.cs | 8 +- src/SimAI/Marshals/VMStackFrameMarshal.cs | 104 ++++---- src/SimAI/VM.cs | 230 +++++++++--------- src/SimAI/VMClock.cs | 58 ++--- src/SimAI/VMContext.cs | 6 +- src/SimAI/VMSimanticsException.cs | 147 ++++++------ 19 files changed, 617 insertions(+), 614 deletions(-) diff --git a/src/SimAI.Tests/SimAI.Tests.csproj b/src/SimAI.Tests/SimAI.Tests.csproj index 2332136..48a8ea7 100644 --- a/src/SimAI.Tests/SimAI.Tests.csproj +++ b/src/SimAI.Tests/SimAI.Tests.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable false @@ -9,18 +9,19 @@ SimAntics.Tests - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/src/SimAI.Tests/VMClockTest.cs b/src/SimAI.Tests/VMClockTest.cs index 9edeec9..5278c82 100644 --- a/src/SimAI.Tests/VMClockTest.cs +++ b/src/SimAI.Tests/VMClockTest.cs @@ -1,16 +1,17 @@ using System.Diagnostics; +using SimAI; using Xunit; -namespace SimAI.Tests; +namespace SimAntics.Tests; public class VMClockTest { - [Fact] - public void TickTest() - { - var clock = new VMClock(); - Debug.WriteLine(clock.Ticks); - clock.Tick(); - Debug.WriteLine(clock.Ticks); - } + [Fact] + public void TickTest() + { + var clock = new VMClock(); + Debug.WriteLine(clock.Ticks); + clock.Tick(); + Debug.WriteLine(clock.Ticks); + } } \ No newline at end of file diff --git a/src/SimAI.Tests/VMTest.cs b/src/SimAI.Tests/VMTest.cs index f5c35fa..92da1ad 100644 --- a/src/SimAI.Tests/VMTest.cs +++ b/src/SimAI.Tests/VMTest.cs @@ -5,7 +5,7 @@ namespace SimAI.Tests; public class VMTest { - public VMTest() - { - } + public VMTest() + { + } } diff --git a/src/SimAI/Direction.cs b/src/SimAI/Direction.cs index a77fdcd..ef120b2 100644 --- a/src/SimAI/Direction.cs +++ b/src/SimAI/Direction.cs @@ -1,16 +1,16 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI; +namespace SimAntics; public enum Direction { - NORTH, - NORTHEAST, - EAST, - SOUTHEAST, - SOUTH, - SOUTHWEST, - WEST, - NORTHWEST + NORTH, + NORTHEAST, + EAST, + SOUTHEAST, + SOUTH, + SOUTHWEST, + WEST, + NORTHWEST } diff --git a/src/SimAI/Engine/Entities/VMEntity.cs b/src/SimAI/Engine/Entities/VMEntity.cs index 6098628..a11f92f 100644 --- a/src/SimAI/Engine/Entities/VMEntity.cs +++ b/src/SimAI/Engine/Entities/VMEntity.cs @@ -1,132 +1,130 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -using SimAI; - namespace SimAntics.Engine.Entities; public class VMEntityRTTI { - public string[]? AttributeLabels; + public string[]? AttributeLabels; } public abstract class VMEntity { - public static bool UseWorld = true; - public VMEntityRTTI? RTTI; - public bool GhostImage; + public static bool UseWorld = true; + public VMEntityRTTI? RTTI; + public bool GhostImage; - public short ObjectID; - public uint PersistID; + public short ObjectID; + public uint PersistID; - public short[]? ObjectData; - public LinkedList MyList = new(); - // public List SoundThreads; + public short[]? ObjectData; + public LinkedList MyList = new(); + // public List SoundThreads; - // public VMRuntimeHeadline Headline; - /// - /// IS NOT serialized, but rather regenerated on deserialize. - /// - // public VMHeadlineRenderer HeadlineRenderer; + // public VMRuntimeHeadline Headline; + /// + /// IS NOT serialized, but rather regenerated on deserialize. + /// + // public VMHeadlineRenderer HeadlineRenderer; - // public GameObject Object; - public VMThread? Thread; - // public VMMultitileGroup MultitileGroup; + // public GameObject Object; + public VMThread? Thread; + // public VMMultitileGroup MultitileGroup; - public short MainParam; //parameters passed to main on creation. - public short MainStackOBJ; + public short MainParam; //parameters passed to main on creation. + public short MainStackOBJ; - public VMEntity[] Contained = new VMEntity[0]; - public VMEntity? Container; - public short ContainerSlot; - /// - /// set when the entity is removed, threads owned by this object or with this object as callee will be cancelled/have their stack emptied - /// - public bool Dead; + public VMEntity[] Contained = new VMEntity[0]; + public VMEntity? Container; + public short ContainerSlot; + /// + /// set when the entity is removed, threads owned by this object or with this object as callee will be cancelled/have their stack emptied + /// + public bool Dead; - /** Relationship variables **/ - public Dictionary>? MeToObject; - public Dictionary>? MeToPersist; - //a runtime cache for objects that have relationships to us. Used to get a quick reference to objects - //that may need to delete a relationship to us. - //note this can point to false positives, but the worst case is a slow deletion if somehow every object is added. - public HashSet MayHaveRelToMe = new(); + /** Relationship variables **/ + public Dictionary>? MeToObject; + public Dictionary>? MeToPersist; + //a runtime cache for objects that have relationships to us. Used to get a quick reference to objects + //that may need to delete a relationship to us. + //note this can point to false positives, but the worst case is a slow deletion if somehow every object is added. + public HashSet MayHaveRelToMe = new(); - //signals which relationships have changed since the last time this was reset - //used to partial update relationships when doing an avatar save to db - public HashSet ChangedRels = new(); + //signals which relationships have changed since the last time this was reset + //used to partial update relationships when doing an avatar save to db + public HashSet ChangedRels = new(); - public ulong DynamicSpriteFlags; /** Used to show/hide dynamic sprites **/ - public ulong DynamicSpriteFlags2; - //public VMObstacle Footprint; + public ulong DynamicSpriteFlags; /** Used to show/hide dynamic sprites **/ + public ulong DynamicSpriteFlags2; + //public VMObstacle Footprint; - //LotTilePos _Position = new LotTilePos(LotTilePos.OUT_OF_WORLD); - //public EntityComponent WorldUI; + //LotTilePos _Position = new LotTilePos(LotTilePos.OUT_OF_WORLD); + //public EntityComponent WorldUI; - public uint TimestampLockoutCount = 0; - //public Color LightColor = Color.White; + public uint TimestampLockoutCount = 0; + //public Color LightColor = Color.White; - //inferred properties (from object resource) - //public GameGlobalResource SemiGlobal; - //public TTAB TreeTable; - //public TTAs TreeTableStrings; - //public Dictionary TreeByName; - //public SLOT Slots; - //public OBJD MasterDefinition; //if this object is multitile, its master definition will be stored here. - //public OBJfFunctionEntry[] EntryPoints; /** Entry points for specific events, eg. init, main, clean... **/ - //public virtual bool MovesOften - //{ - // get - // { - // if (Container != null) return true; - // if (Slots == null) return false; - // if (!Slots.Slots.ContainsKey(3)) return false; - // var slots = Slots.Slots[3]; - // return (slots.Count > 7); - // } - //} + //inferred properties (from object resource) + //public GameGlobalResource SemiGlobal; + //public TTAB TreeTable; + //public TTAs TreeTableStrings; + //public Dictionary TreeByName; + //public SLOT Slots; + //public OBJD MasterDefinition; //if this object is multitile, its master definition will be stored here. + //public OBJfFunctionEntry[] EntryPoints; /** Entry points for specific events, eg. init, main, clean... **/ + //public virtual bool MovesOften + //{ + // get + // { + // if (Container != null) return true; + // if (Slots == null) return false; + // if (!Slots.Slots.ContainsKey(3)) return false; + // var slots = Slots.Slots[3]; + // return (slots.Count > 7); + // } + //} - //public string Name - //{ - // get - // { - // if (MultitileGroup.Name != "") return MultitileGroup.Name; - // else return this.ToString(); - // } - // set - // { - // MultitileGroup.Name = value; - // } - //} + //public string Name + //{ + // get + // { + // if (MultitileGroup.Name != "") return MultitileGroup.Name; + // else return this.ToString(); + // } + // set + // { + // MultitileGroup.Name = value; + // } + //} - //bool DynamicMultitile - //{ - // get - // { - // return EntryPoints[8].ActionFunction >= 256; - // } - //} + //bool DynamicMultitile + //{ + // get + // { + // return EntryPoints[8].ActionFunction >= 256; + // } + //} - //public override string ToString() - //{ - // if (MultitileGroup.Name != "") return MultitileGroup.Name; - // var strings = Object.Resource.Get(Object.OBJ.CatalogStringsID); - // if (strings != null) - // { - // return strings.GetString(0); - // } - // var label = Object.OBJ.ChunkLabel; - // if (label != null && label.Length > 0) - // { - // return label; - // } - // return Object.OBJ.GUID.ToString("X"); - //} + //public override string ToString() + //{ + // if (MultitileGroup.Name != "") return MultitileGroup.Name; + // var strings = Object.Resource.Get(Object.OBJ.CatalogStringsID); + // if (strings != null) + // { + // return strings.GetString(0); + // } + // var label = Object.OBJ.ChunkLabel; + // if (label != null && label.Length > 0) + // { + // return label; + // } + // return Object.OBJ.GUID.ToString("X"); + //} - //positioning properties + //positioning properties - protected static Direction[] DirectionNotches = new Direction[] - { + protected static Direction[] DirectionNotches = new Direction[] + { Direction.NORTH, Direction.NORTHEAST, Direction.EAST, @@ -135,23 +133,23 @@ public abstract class VMEntity Direction.SOUTHWEST, Direction.WEST, Direction.NORTHWEST - }; + }; - //public LotTilePos Position - //{ - // get { return _Position; } - // set - // { - // _Position = value; - // if (UseWorld) WorldUI.Level = Position.Level; - // if (this is VMAvatar) ((VMAvatar)this).VisualPositionStart = null; - // VisualPosition = new Vector3(_Position.x / 16.0f, _Position.y / 16.0f, (_Position.Level - 1) * 2.95f); - // } - // } + //public LotTilePos Position + //{ + // get { return _Position; } + // set + // { + // _Position = value; + // if (UseWorld) WorldUI.Level = Position.Level; + // if (this is VMAvatar) ((VMAvatar)this).VisualPositionStart = null; + // VisualPosition = new Vector3(_Position.x / 16.0f, _Position.y / 16.0f, (_Position.Level - 1) * 2.95f); + // } + // } - // public abstract Vector3 VisualPosition { get; set; } - public abstract Direction Direction { get; set; } - public abstract float RadianDirection { get; set; } + // public abstract Vector3 VisualPosition { get; set; } + public abstract Direction Direction { get; set; } + public abstract float RadianDirection { get; set; } } diff --git a/src/SimAI/Engine/VMMemory.cs b/src/SimAI/Engine/VMMemory.cs index bc27363..67c2c42 100644 --- a/src/SimAI/Engine/VMMemory.cs +++ b/src/SimAI/Engine/VMMemory.cs @@ -1,11 +1,11 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI.Engine; +namespace SimAntics.Engine; public class VMMemory { - public VMMemory() - { - } + public VMMemory() + { + } } diff --git a/src/SimAI/Engine/VMScheduler.cs b/src/SimAI/Engine/VMScheduler.cs index f0257ac..be373be 100644 --- a/src/SimAI/Engine/VMScheduler.cs +++ b/src/SimAI/Engine/VMScheduler.cs @@ -3,25 +3,25 @@ // http://mozilla.org/MPL/2.0/. using SimAntics.Engine.Entities; -namespace SimAI.Engine; +namespace SimAntics.Engine; public class VMScheduler { - VM VM { get; set; } + VM VM { get; set; } - Dictionary> _tickScheduler = new(); - List _tickThisFrame; + Dictionary> _tickScheduler = new(); + List _tickThisFrame; - public HashSet PendingDeletion { get; set; } = new HashSet(); - public uint CurrentTickID { get; set; } - public short CurrentObjectID { get; set; } - public bool RunningNow { get; set; } + public HashSet PendingDeletion { get; set; } = new HashSet(); + public uint CurrentTickID { get; set; } + public short CurrentObjectID { get; set; } + public bool RunningNow { get; set; } - public VMScheduler(VM vm) => VM = vm; + public VMScheduler(VM vm) => VM = vm; - public void ScheduleTickIn(VMEntity _ent, uint delay) - { + public void ScheduleTickIn(VMEntity _ent, uint delay) + { - } + } } diff --git a/src/SimAI/Engine/VMStackFrame.cs b/src/SimAI/Engine/VMStackFrame.cs index 0dfb8d6..aee0178 100644 --- a/src/SimAI/Engine/VMStackFrame.cs +++ b/src/SimAI/Engine/VMStackFrame.cs @@ -3,171 +3,172 @@ // http://mozilla.org/MPL/2.0/. using SimAntics.Engine.Entities; +using SimAntics.Marshals; -namespace SimAI.Engine; +namespace SimAntics.Engine; /// /// Holds information about the execution of a routine /// public class VMStackFrame - { - public VMStackFrame() { } +{ + public VMStackFrame() { } - /** Thread executing this routine **/ - public VMThread Thread; + /** Thread executing this routine **/ + public VMThread Thread; - /** Routine that this context relates to **/ - // public VMRoutine Routine; + /** Routine that this context relates to **/ + // public VMRoutine Routine; - /** Current instruction **/ - public ushort InstructionPointer; + /** Current instruction **/ + public ushort InstructionPointer; - /** The object who executed this behavior **/ - public VMEntity Caller; + /** The object who executed this behavior **/ + public VMEntity Caller; - /** The object the code is running on **/ - public VMEntity Callee; + /** The object the code is running on **/ + public VMEntity Callee; - /** An object selected by the code to perform operations on. **/ - public VMEntity StackObject - { - get { return _StackObject; } - set - { - _StackObject = value; - _StackObjectID = value?.ObjectID ?? 0; - } - } - public short StackObjectID - { - get { return _StackObjectID; } - set - { - _StackObjectID = value; - _StackObject = VM.GetObjectById(value); - } - } + /** An object selected by the code to perform operations on. **/ + public VMEntity StackObject + { + get { return _StackObject; } + set + { + _StackObject = value; + _StackObjectID = value?.ObjectID ?? 0; + } + } + public short StackObjectID + { + get { return _StackObjectID; } + set + { + _StackObjectID = value; + _StackObject = VM.GetObjectById(value); + } + } - VMEntity _StackObject; - public short _StackObjectID; + VMEntity _StackObject; + public short _StackObjectID; - /** If true, this stack frame is not a subroutine. Return with a continue. **/ - public bool DiscardResult; + /** If true, this stack frame is not a subroutine. Return with a continue. **/ + public bool DiscardResult; - /** Indicates that the current stack frame is part of an action tree. - ** Set by "idle for input, allow push", when an interaction is selected. - ** Used to stop recursive interactions, is only false when within "main". - **/ - public bool ActionTree; + /** Indicates that the current stack frame is part of an action tree. + ** Set by "idle for input, allow push", when an interaction is selected. + ** Used to stop recursive interactions, is only false when within "main". + **/ + public bool ActionTree; - /** Used to get strings and other resources (for primitives) from the code owner, as it may not be the callee but instead a semiglobal or global. **/ - //public GameIffResource ScopeResource - //{ - // get - // { - // return CodeOwner.Resource; - // } - //} + /** Used to get strings and other resources (for primitives) from the code owner, as it may not be the callee but instead a semiglobal or global. **/ + //public GameIffResource ScopeResource + //{ + // get + // { + // return CodeOwner.Resource; + // } + //} - //public GameObject CodeOwner; - /** - * Routine locals - */ - public short[] Locals; + //public GameObject CodeOwner; + /** + * Routine locals + */ + public short[] Locals; - /** - * Arguments - */ - public short[] Args; + /** + * Arguments + */ + public short[] Args; - //public GameObjectResource CallerPrivate - //{ - // get - // { - // return Caller.Object.Resource; - // } - //} + //public GameObjectResource CallerPrivate + //{ + // get + // { + // return Caller.Object.Resource; + // } + //} - //public GameObjectResource CalleePrivate - //{ - // get - // { - // return Callee.Object.Resource; - // } - //} + //public GameObjectResource CalleePrivate + //{ + // get + // { + // return Callee.Object.Resource; + // } + //} - //public GameObjectResource StackObjPrivate - //{ - // get - // { - // return StackObject.Object.Resource; - // } - //} + //public GameObjectResource StackObjPrivate + //{ + // get + // { + // return StackObject.Object.Resource; + // } + //} - //public GameGlobal Global - //{ - // get - // { - // return Thread.Context.Globals; - // } - //} + //public GameGlobal Global + //{ + // get + // { + // return Thread.Context.Globals; + // } + //} - public VM VM - { - get - { - return Thread.Context.VM; - } - } + public VM VM + { + get + { + return Thread.Context.VM; + } + } - /** Utilities **/ - //public VMInstruction GetCurrentInstruction() - //{ - // return Routine.Instructions[InstructionPointer]; - //} + /** Utilities **/ + //public VMInstruction GetCurrentInstruction() + //{ + // return Routine.Instructions[InstructionPointer]; + //} - //public T GetCurrentOperand() - //{ - // return (T)GetCurrentInstruction().Operand; - //} + //public T GetCurrentOperand() + //{ + // return (T)GetCurrentInstruction().Operand; + //} - #region VM Marshalling Functions - //public virtual VMStackFrameMarshal Save() - //{ - // return new VMStackFrameMarshal - // { - // RoutineID = Routine?.ID ?? 0, - // InstructionPointer = InstructionPointer, - // Caller = (Caller == null) ? (short)0 : Caller.ObjectID, - // Callee = (Callee == null) ? (short)0 : Callee.ObjectID, - // StackObject = StackObjectID, - // CodeOwnerGUID = CodeOwner.OBJ.GUID, - // Locals = (short[])Locals?.Clone(), - // Args = (short[])Args?.Clone(), - // DiscardResult = DiscardResult, - // ActionTree = ActionTree, - // }; - //} + #region VM Marshalling Functions + //public virtual VMStackFrameMarshal Save() + //{ + // return new VMStackFrameMarshal + // { + // RoutineID = Routine?.ID ?? 0, + // InstructionPointer = InstructionPointer, + // Caller = (Caller == null) ? (short)0 : Caller.ObjectID, + // Callee = (Callee == null) ? (short)0 : Callee.ObjectID, + // StackObject = StackObjectID, + // CodeOwnerGUID = CodeOwner.OBJ.GUID, + // Locals = (short[])Locals?.Clone(), + // Args = (short[])Args?.Clone(), + // DiscardResult = DiscardResult, + // ActionTree = ActionTree, + // }; + //} - public virtual void Load(VMStackFrameMarshal input, VMContext context) - { - // CodeOwner = GameContent.Get.WorldObjects.Get(input.CodeOwnerGUID); + public virtual void Load(VMStackFrameMarshal input, VMContext context) + { + // CodeOwner = GameContent.Get.WorldObjects.Get(input.CodeOwnerGUID); - // Routine = null; - //if (input.RoutineID >= 8192) Routine = (VMRoutine)ScopeResource.SemiGlobal.GetRoutine(input.RoutineID); - //else if (input.RoutineID >= 4096) Routine = (VMRoutine)ScopeResource.GetRoutine(input.RoutineID); - //else Routine = (VMRoutine)Global.Resource.GetRoutine(input.RoutineID); + // Routine = null; + //if (input.RoutineID >= 8192) Routine = (VMRoutine)ScopeResource.SemiGlobal.GetRoutine(input.RoutineID); + //else if (input.RoutineID >= 4096) Routine = (VMRoutine)ScopeResource.GetRoutine(input.RoutineID); + //else Routine = (VMRoutine)Global.Resource.GetRoutine(input.RoutineID); - InstructionPointer = input.InstructionPointer; - Caller = context.VM.GetObjectById(input.Caller); - Callee = context.VM.GetObjectById(input.Callee); - StackObjectID = input.StackObject; - Locals = input.Locals; - Args = input.Args; - DiscardResult = input.DiscardResult; - ActionTree = input.ActionTree; - } + InstructionPointer = input.InstructionPointer; + Caller = context.VM.GetObjectById(input.Caller); + Callee = context.VM.GetObjectById(input.Callee); + StackObjectID = input.StackObject; + Locals = input.Locals; + Args = input.Args; + DiscardResult = input.DiscardResult; + ActionTree = input.ActionTree; + } - public VMStackFrame(VMStackFrameMarshal input, VMContext context, VMThread thread) => Thread = thread;// Load(input, context); - #endregion + public VMStackFrame(VMStackFrameMarshal input, VMContext context, VMThread thread) => Thread = thread;// Load(input, context); + #endregion } diff --git a/src/SimAI/Engine/VMThread.cs b/src/SimAI/Engine/VMThread.cs index 1928109..8c3e59d 100644 --- a/src/SimAI/Engine/VMThread.cs +++ b/src/SimAI/Engine/VMThread.cs @@ -5,9 +5,7 @@ #define IDE_COMPAT #endif -using SimAntics.Engine.Entities; - -namespace SimAI.Engine; +namespace SimAntics.Engine; /// /// Compatibility class @@ -19,36 +17,36 @@ public class VMThread : VMInstruction { } /// public class VMInstruction { - public static int MAX_USER_ACTIONS = 20; + public static int MAX_USER_ACTIONS = 20; - public VMContext? Context; + public VMContext? Context; - //check tree only vars - public bool IsCheck; + //check tree only vars + public bool IsCheck; - VMEntity? Entity; + VMEntity? Entity; - public List? Stack; - bool ContinueExecution; + public List? Stack; + bool ContinueExecution; - public string? ThreadBreakString; - public int BreakFrame; //frame the last breakpoint was performed on - public bool RoutineDirty; + public string? ThreadBreakString; + public int BreakFrame; //frame the last breakpoint was performed on + public bool RoutineDirty; - public bool Interrupt; + public bool Interrupt; - ushort ActionUID; + ushort ActionUID; - // Exception handling variables - // Don't need to be serialized. - public int DialogCooldown = 0; - // the number of ticks that have executed so far this frame. If this exceeds the allowed max, - // the thread resets, and a SimAI Error pops up. - public int TicksThisFrame = 0; - // the maximum number of primitives a thread can execute in one frame. Tweak appropriately. + // Exception handling variables + // Don't need to be serialized. + public int DialogCooldown = 0; + // the number of ticks that have executed so far this frame. If this exceeds the allowed max, + // the thread resets, and a SimAI Error pops up. + public int TicksThisFrame = 0; + // the maximum number of primitives a thread can execute in one frame. Tweak appropriately. - // variables for internal scheduler - public uint ScheduleIdleStart; // keep track of tick when we started idling for an object. must be synced! - public uint ScheduleIdleEnd; + // variables for internal scheduler + public uint ScheduleIdleStart; // keep track of tick when we started idling for an object. must be synced! + public uint ScheduleIdleEnd; } \ No newline at end of file diff --git a/src/SimAI/GlobalUsing.cs b/src/SimAI/GlobalUsing.cs index 6908a59..b993f9e 100644 --- a/src/SimAI/GlobalUsing.cs +++ b/src/SimAI/GlobalUsing.cs @@ -1,2 +1,3 @@ -global using SimAI.Engine; -global using SimAI.Marshals; \ No newline at end of file +global using SimAntics.Engine; +global using SimAntics.Marshals; +global using SimAntics.Engine.Entities; \ No newline at end of file diff --git a/src/SimAI/IVM.cs b/src/SimAI/IVM.cs index c2a90eb..0bb53b3 100644 --- a/src/SimAI/IVM.cs +++ b/src/SimAI/IVM.cs @@ -1,13 +1,13 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI; +namespace SimAntics; public interface IVM { - void Init(); - void Reset(); - void Update(); - void Tick(); - void InternalTick(uint tickId); + void Init(); + void Reset(); + void Update(); + void Tick(); + void InternalTick(uint tickId); } diff --git a/src/SimAI/Interfaces/VMIMotiveDecay.cs b/src/SimAI/Interfaces/VMIMotiveDecay.cs index ee61456..90888d4 100644 --- a/src/SimAI/Interfaces/VMIMotiveDecay.cs +++ b/src/SimAI/Interfaces/VMIMotiveDecay.cs @@ -1,9 +1,9 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI.Interfaces; +namespace SimAntics.Interfaces; public interface VMIMotiveDecay : VMSerializable { - // void Tick(VMAvatar avatar, VMContext context); + // void Tick(VMAvatar avatar, VMContext context); } diff --git a/src/SimAI/Interfaces/VMSerializable.cs b/src/SimAI/Interfaces/VMSerializable.cs index e2a6100..b464c86 100644 --- a/src/SimAI/Interfaces/VMSerializable.cs +++ b/src/SimAI/Interfaces/VMSerializable.cs @@ -1,7 +1,7 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI.Interfaces; +namespace SimAntics.Interfaces; public interface VMSerializable { diff --git a/src/SimAI/Marshals/VMMarshal.cs b/src/SimAI/Marshals/VMMarshal.cs index da90a89..3a86914 100644 --- a/src/SimAI/Marshals/VMMarshal.cs +++ b/src/SimAI/Marshals/VMMarshal.cs @@ -1,11 +1,11 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI.Marshals; +namespace SimAntics.Marshals; public class VMMarshal { - public VMMarshal() - { - } + public VMMarshal() + { + } } diff --git a/src/SimAI/Marshals/VMStackFrameMarshal.cs b/src/SimAI/Marshals/VMStackFrameMarshal.cs index 91b229f..8e62da4 100644 --- a/src/SimAI/Marshals/VMStackFrameMarshal.cs +++ b/src/SimAI/Marshals/VMStackFrameMarshal.cs @@ -1,66 +1,66 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI.Marshals; +namespace SimAntics.Marshals; public class VMStackFrameMarshal { - public ushort RoutineID { get; set; } - public ushort InstructionPointer { get; set; } - public short Caller { get; set; } - public short Callee { get; set; } - public short StackObject { get; set; } - public uint CodeOwnerGUID { get; set; } - public short[] Locals { get; set; } - public short[] Args { get; set; } - public bool DiscardResult { get; set; } - public bool ActionTree { get; set; } + public ushort RoutineID { get; set; } + public ushort InstructionPointer { get; set; } + public short Caller { get; set; } + public short Callee { get; set; } + public short StackObject { get; set; } + public uint CodeOwnerGUID { get; set; } + public short[] Locals { get; set; } + public short[] Args { get; set; } + public bool DiscardResult { get; set; } + public bool ActionTree { get; set; } - public int Version { get; set; } + public int Version { get; set; } - public VMStackFrameMarshal() { } - public VMStackFrameMarshal(int version) => Version = version; + public VMStackFrameMarshal() { } + public VMStackFrameMarshal(int version) => Version = version; - public virtual void Deserialize(BinaryReader reader) - { - RoutineID = reader.ReadUInt16(); - InstructionPointer = reader.ReadUInt16(); - Caller = reader.ReadInt16(); - Callee = reader.ReadInt16(); - StackObject = reader.ReadInt16(); - CodeOwnerGUID = reader.ReadUInt32(); + public virtual void Deserialize(BinaryReader reader) + { + RoutineID = reader.ReadUInt16(); + InstructionPointer = reader.ReadUInt16(); + Caller = reader.ReadInt16(); + Callee = reader.ReadInt16(); + StackObject = reader.ReadInt16(); + CodeOwnerGUID = reader.ReadUInt32(); - var localN = reader.ReadInt32(); - if (localN > -1) - { - Locals = new short[localN]; - for (var i = 0; i < localN; i++) Locals[i] = reader.ReadInt16(); - } + var localN = reader.ReadInt32(); + if (localN > -1) + { + Locals = new short[localN]; + for (var i = 0; i < localN; i++) Locals[i] = reader.ReadInt16(); + } - var argsN = reader.ReadInt32(); - if (argsN > -1) - { - Args = new short[argsN]; - for (var i = 0; i < argsN; i++) Args[i] = reader.ReadInt16(); - } + var argsN = reader.ReadInt32(); + if (argsN > -1) + { + Args = new short[argsN]; + for (var i = 0; i < argsN; i++) Args[i] = reader.ReadInt16(); + } - if (Version > 3) DiscardResult = reader.ReadBoolean(); - ActionTree = reader.ReadBoolean(); - } + if (Version > 3) DiscardResult = reader.ReadBoolean(); + ActionTree = reader.ReadBoolean(); + } - public virtual void SerializeInto(BinaryWriter writer) - { - writer.Write(RoutineID); - writer.Write(InstructionPointer); - writer.Write(Caller); - writer.Write(Callee); - writer.Write(StackObject); - writer.Write(CodeOwnerGUID); - writer.Write((Locals == null) ? -1 : Locals.Length); - //if (Locals != null) writer.Write(VMSerializableUtils.ToByteArray(Locals)); - //writer.Write((Args == null) ? -1 : Args.Length); - //if (Args != null) writer.Write(VMSerializableUtils.ToByteArray(Args)); - writer.Write(DiscardResult); - writer.Write(ActionTree); - } + public virtual void SerializeInto(BinaryWriter writer) + { + writer.Write(RoutineID); + writer.Write(InstructionPointer); + writer.Write(Caller); + writer.Write(Callee); + writer.Write(StackObject); + writer.Write(CodeOwnerGUID); + writer.Write(Locals == null ? -1 : Locals.Length); + //if (Locals != null) writer.Write(VMSerializableUtils.ToByteArray(Locals)); + //writer.Write((Args == null) ? -1 : Args.Length); + //if (Args != null) writer.Write(VMSerializableUtils.ToByteArray(Args)); + writer.Write(DiscardResult); + writer.Write(ActionTree); + } } diff --git a/src/SimAI/VM.cs b/src/SimAI/VM.cs index 0f8dd2c..6538757 100644 --- a/src/SimAI/VM.cs +++ b/src/SimAI/VM.cs @@ -1,140 +1,142 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. +using SimAI; +using SimAntics.Engine; using SimAntics.Engine.Entities; -namespace SimAI; +namespace SimAntics; /// /// VM is an abstract class that contains the /// public abstract class VM : IVM { - public bool IsTS1 { get; set; } - public bool Ready { get; set; } - public bool BHAVDirty { get; set; } - public VMContext Context { get; internal set; } - public VMScheduler Scheduler { set; get; } + public bool IsTS1 { get; set; } + public bool Ready { get; set; } + public bool BHAVDirty { get; set; } + public VMContext Context { get; internal set; } + public VMScheduler Scheduler { set; get; } - public delegate void VMRefreshHandler(); - public delegate void VMLotSwitchHandler(uint lotId); + public delegate void VMRefreshHandler(); + public delegate void VMLotSwitchHandler(uint lotId); - Dictionary ObjectsById = new(); - short ObjectId = 1; + Dictionary ObjectsById = new(); + short ObjectId = 1; - public List Entities = new(); - public HashSet SoundEntities = new(); - public short[] GlobalState; + public List Entities = new(); + public HashSet SoundEntities = new(); + public short[] GlobalState; - int GameTickRate = 60; - int GameTickNum = 0; - public int SpeedMultiplier = 1; - public int LastSpeedMultiplier; - int LastFrameSpeed = 1; - float Fraction; - public VMEntity GlobalBlockingDialog; + int GameTickRate = 60; + int GameTickNum = 0; + public int SpeedMultiplier = 1; + public int LastSpeedMultiplier; + int LastFrameSpeed = 1; + float Fraction; + public VMEntity GlobalBlockingDialog; - /// - /// Gets an entity from this VM. - /// - /// The entity's ID. - /// A VMEntity instance associated with the ID. - public VMEntity? GetObjectById(short id) - { - return ObjectsById.ContainsKey(id) ? ObjectsById[id] : null; - } + /// + /// Gets an entity from this VM. + /// + /// The entity's ID. + /// A VMEntity instance associated with the ID. + public VMEntity? GetObjectById(short id) + { + return ObjectsById.ContainsKey(id) ? ObjectsById[id] : null; + } - /// - /// Constructs a new Virtual Machine instance. - /// - /// The VMContext instance to use. - public VM(VMContext context) - { - context.VM = this; - Context = context; - Scheduler = new VMScheduler(this); - } + /// + /// Constructs a new Virtual Machine instance. + /// + /// The VMContext instance to use. + public VM(VMContext context) + { + context.VM = this; + Context = context; + Scheduler = new VMScheduler(this); + } - public VMEntity GetObjectByPersist(uint id) - { - // return Entities.FirstOrDefault(x => x.PersistID == id); - throw new VMSimanticsException(); - } + public VMEntity GetObjectByPersist(uint id) + { + // return Entities.FirstOrDefault(x => x.PersistID == id); + throw new VMSimanticsException(); + } - public virtual void Init() - { - // PlatformState = (TS1)?(VMAbstractLotState)new VMTS1LotState():new VMTSOLotState(); - GlobalState = new short[38]; - GlobalState[20] = 255; //Game Edition. Basically, what "expansion packs" are running. Let's just say all of them. - GlobalState[25] = 4; //as seen in EA-Land edith's simulator globals, this needs to be set for people to do their idle interactions. - GlobalState[17] = 4; //Runtime Code Version, is this in EA-Land. - // if (Driver is VMServerDriver) EODHost = new VMEODHost(); - } + public virtual void Init() + { + // PlatformState = (TS1)?(VMAbstractLotState)new VMTS1LotState():new VMTSOLotState(); + GlobalState = new short[38]; + GlobalState[20] = 255; //Game Edition. Basically, what "expansion packs" are running. Let's just say all of them. + GlobalState[25] = 4; //as seen in EA-Land edith's simulator globals, this needs to be set for people to do their idle interactions. + GlobalState[17] = 4; //Runtime Code Version, is this in EA-Land. + // if (Driver is VMServerDriver) EODHost = new VMEODHost(); + } - public virtual void Reset() - { - throw new NotImplementedException(); - } - public virtual void Update() - { - throw new NotImplementedException(); - } + public virtual void Reset() + { + throw new NotImplementedException(); + } + public virtual void Update() + { + throw new NotImplementedException(); + } - public virtual void Tick() - { - throw new NotImplementedException(); - } + public virtual void Tick() + { + throw new NotImplementedException(); + } - public virtual void InternalTick(uint tickId) - { - throw new NotImplementedException(); - } + public virtual void InternalTick(uint tickId) + { + throw new NotImplementedException(); + } - /// - /// Adds an entity to this Virtual Machine. - /// - /// The entity to add. - public void AddEntity(VMEntity entity) - { - entity.ObjectID = ObjectId; - ObjectsById.Add(entity.ObjectID, entity); - // AddToObjList(this.Entities, entity); - // if (!entity.GhostImage) Context.ObjectQueries.NewObject(entity); - // ObjectId = NextObjID(); - } + /// + /// Adds an entity to this Virtual Machine. + /// + /// The entity to add. + public void AddEntity(VMEntity entity) + { + entity.ObjectID = ObjectId; + ObjectsById.Add(entity.ObjectID, entity); + // AddToObjList(this.Entities, entity); + // if (!entity.GhostImage) Context.ObjectQueries.NewObject(entity); + // ObjectId = NextObjID(); + } - public static void AddToObjList(List list, VMEntity entity) - { - if (list.Count == 0) { list.Add(entity); return; } - int id = entity.ObjectID; - var max = list.Count; - var min = 0; - while (max > min) - { - var mid = (max + min) / 2; - int nid = list[mid].ObjectID; - if (id < nid) max = mid; - else if (id == nid) return; //do not add dupes - else min = mid + 1; - } - list.Insert(min, entity); - // list.Insert((list[min].ObjectID>id)?min:((list[max].ObjectID > id)?max:max+1), entity); - } + public static void AddToObjList(List list, VMEntity entity) + { + if (list.Count == 0) { list.Add(entity); return; } + int id = entity.ObjectID; + var max = list.Count; + var min = 0; + while (max > min) + { + var mid = (max + min) / 2; + int nid = list[mid].ObjectID; + if (id < nid) max = mid; + else if (id == nid) return; //do not add dupes + else min = mid + 1; + } + list.Insert(min, entity); + // list.Insert((list[min].ObjectID>id)?min:((list[max].ObjectID > id)?max:max+1), entity); + } - /// - /// Removes an entity from this Virtual Machine. - /// - /// The entity to remove. - public void RemoveEntity(VMEntity entity) - { - if (Entities.Contains(entity)) - { - // Context.ObjectQueries.RemoveObject(entity); - this.Entities.Remove(entity); - ObjectsById.Remove(entity.ObjectID); - // Scheduler.DescheduleTick(entity); - if (entity.ObjectID < ObjectId) ObjectId = entity.ObjectID; //this id is now the smallest free object id. - } - entity.Dead = true; - } + /// + /// Removes an entity from this Virtual Machine. + /// + /// The entity to remove. + public void RemoveEntity(VMEntity entity) + { + if (Entities.Contains(entity)) + { + // Context.ObjectQueries.RemoveObject(entity); + Entities.Remove(entity); + ObjectsById.Remove(entity.ObjectID); + // Scheduler.DescheduleTick(entity); + if (entity.ObjectID < ObjectId) ObjectId = entity.ObjectID; //this id is now the smallest free object id. + } + entity.Dead = true; + } } \ No newline at end of file diff --git a/src/SimAI/VMClock.cs b/src/SimAI/VMClock.cs index d96bb0f..5c0ba2a 100644 --- a/src/SimAI/VMClock.cs +++ b/src/SimAI/VMClock.cs @@ -2,43 +2,43 @@ // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI; +namespace SimAntics; public class VMClock { - public long Ticks { get; set; } - public int MinuteFractions { get; set; } - public int TicksPerMinute { get; set; } - public int Minutes { get; set; } - public int Hours { get; set; } + public long Ticks { get; set; } + public int MinuteFractions { get; set; } + public int TicksPerMinute { get; set; } + public int Minutes { get; set; } + public int Hours { get; set; } - public int DayOfMonth = 1; - public int Month = 6; - public int Year = 1997; + public int DayOfMonth = 1; + public int Month = 6; + public int Year = 1997; - public int FirePercent { get; set; } - public long UTCStart = DateTime.UtcNow.Ticks; + public int FirePercent { get; set; } + public long UTCStart = DateTime.UtcNow.Ticks; - public int TimeOfDay => (Hours >= 6 && Hours < 18) ? 0 : 1; - public int Seconds => MinuteFractions * 60 / TicksPerMinute; + public int TimeOfDay => Hours >= 6 && Hours < 18 ? 0 : 1; + public int Seconds => MinuteFractions * 60 / TicksPerMinute; - public DateTime UTCNow => new DateTime(UTCStart).AddSeconds(Ticks / 30.0); + public DateTime UTCNow => new DateTime(UTCStart).AddSeconds(Ticks / 30.0); - public VMClock() { } + public VMClock() { } - public void Tick() - { - if (FirePercent < 2000) FirePercent++; - if (++MinuteFractions < TicksPerMinute) return; - MinuteFractions = 0; - if (++Minutes < 60) return; - Minutes = 0; - if (++DayOfMonth <= 30) return; - DayOfMonth = 1; - if (++Month <= 12) return; - Month = 1; - Year++; + public void Tick() + { + if (FirePercent < 2000) FirePercent++; + if (++MinuteFractions < TicksPerMinute) return; + MinuteFractions = 0; + if (++Minutes < 60) return; + Minutes = 0; + if (++DayOfMonth <= 30) return; + DayOfMonth = 1; + if (++Month <= 12) return; + Month = 1; + Year++; - Ticks++; - } + Ticks++; + } } \ No newline at end of file diff --git a/src/SimAI/VMContext.cs b/src/SimAI/VMContext.cs index 43e224e..38b4f08 100644 --- a/src/SimAI/VMContext.cs +++ b/src/SimAI/VMContext.cs @@ -1,10 +1,10 @@ // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. -namespace SimAI; +namespace SimAntics; public class VMContext { - public static bool useWorld = true; - public VM? VM { get; set; } + public static bool useWorld = true; + public VM? VM { get; set; } } \ No newline at end of file diff --git a/src/SimAI/VMSimanticsException.cs b/src/SimAI/VMSimanticsException.cs index 33fd731..cf03b94 100644 --- a/src/SimAI/VMSimanticsException.cs +++ b/src/SimAI/VMSimanticsException.cs @@ -2,93 +2,94 @@ // If a copy of the MPL was not distributed with this file, You can obtain one at // http://mozilla.org/MPL/2.0/. using System.Text; +using SimAntics.Engine; -namespace SimAI; +namespace SimAntics; public class VMSimanticsException : Exception { - readonly string _message; - VMStackFrame _context; + readonly string _message; + VMStackFrame _context; - public VMSimanticsException() { } + public VMSimanticsException() { } - public VMSimanticsException(string message, VMStackFrame context) : base(message) - { - _context = context; - _message = message; - } + public VMSimanticsException(string message, VMStackFrame context) : base(message) + { + _context = context; + _message = message; + } - public override string ToString() - { - var output = new StringBuilder(); - output.Append(_message); - output.AppendLine(); - output.AppendLine(); - output.Append(GetStackTrace()); - return output.ToString(); - } + public override string ToString() + { + var output = new StringBuilder(); + output.Append(_message); + output.AppendLine(); + output.AppendLine(); + output.Append(GetStackTrace()); + return output.ToString(); + } - public string GetStackTrace() - { - if (_context == null) return "No Stack Info."; + public string GetStackTrace() + { + if (_context == null) return "No Stack Info."; - var stack = _context.Thread.Stack; - return GetStackTrace(stack); - } + var stack = _context.Thread.Stack; + return GetStackTrace(stack); + } - public static string GetStackTrace(List stack) - { - var output = new StringBuilder(); - var prevEE = ""; - var prevER = ""; + public static string GetStackTrace(List stack) + { + var output = new StringBuilder(); + var prevEE = ""; + var prevER = ""; - for (var i = stack.Count - 1; i >= 0; i--) - { - if (i == 9 && i <= stack.Count - 8) - { - output.Append("..."); - output.AppendLine(); - } - if (i > 8 && i <= stack.Count - 8) continue; - var frame = stack[i]; - //run in tree:76 + for (var i = stack.Count - 1; i >= 0; i--) + { + if (i == 9 && i <= stack.Count - 8) + { + output.Append("..."); + output.AppendLine(); + } + if (i > 8 && i <= stack.Count - 8) continue; + var frame = stack[i]; + //run in tree:76 - var callerStr = frame.Caller.ToString(); - var calleeStr = frame.Callee?.ToString(); + var callerStr = frame.Caller.ToString(); + var calleeStr = frame.Callee?.ToString(); - if (callerStr != prevER || calleeStr != prevEE) - { - output.Append('('); - output.Append(callerStr); - output.Append(':'); - output.Append(calleeStr); - output.Append(") "); - output.AppendLine(); - prevEE = calleeStr; - prevER = callerStr; - } + if (callerStr != prevER || calleeStr != prevEE) + { + output.Append('('); + output.Append(callerStr); + output.Append(':'); + output.Append(calleeStr); + output.Append(") "); + output.AppendLine(); + prevEE = calleeStr; + prevER = callerStr; + } - output.Append(" > "); + output.Append(" > "); - /*if (frame is VMRoutingFrame) - { - output.Append("VMRoutingFrame with state: "); - output.Append(((VMRoutingFrame)frame).State.ToString()); - } - else - { - output.Append(frame.Routine.Rti.Name.TrimEnd('\0')); - output.Append(':'); - output.Append(frame.InstructionPointer); - output.Append(" ("); - var opcode = frame.GetCurrentInstruction().Opcode; - var primitive = (opcode > 255) ? null : VMContext.Primitives[opcode]; - output.Append((primitive == null) ? opcode.ToString() : primitive.Name); - output.Append(")"); - }*/ - output.AppendLine(); - } + /*if (frame is VMRoutingFrame) + { + output.Append("VMRoutingFrame with state: "); + output.Append(((VMRoutingFrame)frame).State.ToString()); + } + else + { + output.Append(frame.Routine.Rti.Name.TrimEnd('\0')); + output.Append(':'); + output.Append(frame.InstructionPointer); + output.Append(" ("); + var opcode = frame.GetCurrentInstruction().Opcode; + var primitive = (opcode > 255) ? null : VMContext.Primitives[opcode]; + output.Append((primitive == null) ? opcode.ToString() : primitive.Name); + output.Append(")"); + }*/ + output.AppendLine(); + } - return output.ToString(); - } + return output.ToString(); + } }