mirror of
https://github.com/simtactics/SimAINet.git
synced 2025-03-15 08:41:21 +00:00
Target .NET 6
- Cleaned up code with Global and Implicit Usings - Nullable is now enabled - New .NET workflow
This commit is contained in:
parent
c042b47b4a
commit
4210e21c65
26 changed files with 776 additions and 794 deletions
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
|
@ -1,23 +0,0 @@
|
|||
name: build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
dotnet: [ '3.1.200', '3.1.201' ]
|
||||
build_mode: [ 'Release', 'Debug' ]
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet }}
|
||||
- name: Build
|
||||
run: dotnet build src -c ${{ matrix.build_mode }}
|
||||
- name: Run tests
|
||||
run: dotnet test src -c ${{ matrix.build_mode }}
|
26
.github/workflows/dotnet.yml
vendored
Normal file
26
.github/workflows/dotnet.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: .NET
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master, "releases/**"]
|
||||
pull_request:
|
||||
branches: [main, master, "releases/**"]
|
||||
jobs:
|
||||
build:
|
||||
timeout-minutes: 15
|
||||
continue-on-error: true
|
||||
runs-on: ${{ matrix.platforms }}
|
||||
strategy:
|
||||
matrix:
|
||||
dotnet: ["6.0.x"]
|
||||
platforms: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet }}
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release --no-restore
|
1
src/GlobalUsing.cs
Normal file
1
src/GlobalUsing.cs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,26 +1,28 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<RootNamespace>SimAntics.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<RootNamespace>SimAntics.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.1"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SimAI\SimAI.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SimAI\SimAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Xunit;
|
||||
|
||||
namespace SimAI.Tests
|
||||
{
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
var clock = new VMClock();
|
||||
Console.WriteLine(clock.Ticks);
|
||||
clock.Tick();
|
||||
Console.WriteLine(clock.Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace SimAI.Tests;
|
||||
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
var clock = new VMClock();
|
||||
Console.WriteLine(clock.Ticks);
|
||||
clock.Tick();
|
||||
Console.WriteLine(clock.Ticks);
|
||||
}
|
||||
}
|
|
@ -1,12 +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.Tests
|
||||
{
|
||||
public class VMTest
|
||||
{
|
||||
public VMTest()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace SimAI.Tests;
|
||||
|
||||
public class VMTest
|
||||
{
|
||||
public VMTest()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimAI", "SimAI\SimAI.csproj", "{6B758449-9D5A-456A-A733-31B7841E538A}"
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimAI", "SimAI\SimAI.csproj", "{6B758449-9D5A-456A-A733-31B7841E538A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimAI.Tests", "SimAI.Tests\SimAI.Tests.csproj", "{4B7461A4-982A-4D89-92E3-E4D4A3EC85FB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimAI.Tests", "SimAI.Tests\SimAI.Tests.csproj", "{4B7461A4-982A-4D89-92E3-E4D4A3EC85FB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4FF3BCA6-25C6-4E59-9036-2B416C836B7D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -20,6 +24,12 @@ Global
|
|||
{4B7461A4-982A-4D89-92E3-E4D4A3EC85FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B7461A4-982A-4D89-92E3-E4D4A3EC85FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0CAB232D-BCC7-412F-9D4F-715753F4DFF5}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.StandardHeader = $1
|
||||
|
|
|
@ -1,18 +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 SimAI
|
||||
public enum Direction
|
||||
{
|
||||
public enum Direction
|
||||
{
|
||||
NORTH,
|
||||
NORTHEAST,
|
||||
EAST,
|
||||
SOUTHEAST,
|
||||
SOUTH,
|
||||
SOUTHWEST,
|
||||
WEST,
|
||||
NORTHWEST
|
||||
}
|
||||
NORTH,
|
||||
NORTHEAST,
|
||||
EAST,
|
||||
SOUTHEAST,
|
||||
SOUTH,
|
||||
SOUTHWEST,
|
||||
WEST,
|
||||
NORTHWEST
|
||||
}
|
||||
|
|
157
src/SimAI/Engine/Entities/VMEntity.cs
Normal file
157
src/SimAI/Engine/Entities/VMEntity.cs
Normal file
|
@ -0,0 +1,157 @@
|
|||
// 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 abstract class VMEntity
|
||||
{
|
||||
public static bool UseWorld = true;
|
||||
public VMEntityRTTI? RTTI;
|
||||
public bool GhostImage;
|
||||
|
||||
public short ObjectID;
|
||||
public uint PersistID;
|
||||
|
||||
public short[]? ObjectData;
|
||||
public LinkedList<short> MyList = new();
|
||||
// public List<VMSoundEntry> SoundThreads;
|
||||
|
||||
// public VMRuntimeHeadline Headline;
|
||||
/// <summary>
|
||||
/// IS NOT serialized, but rather regenerated on deserialize.
|
||||
/// </summary>
|
||||
// public VMHeadlineRenderer HeadlineRenderer;
|
||||
|
||||
// public GameObject Object;
|
||||
public VMThread? Thread;
|
||||
// public VMMultitileGroup MultitileGroup;
|
||||
|
||||
public short MainParam; //parameters passed to main on creation.
|
||||
public short MainStackOBJ;
|
||||
|
||||
public VMEntity[] Contained = new VMEntity[0];
|
||||
public VMEntity? Container;
|
||||
public short ContainerSlot;
|
||||
/// <summary>
|
||||
/// set when the entity is removed, threads owned by this object or with this object as callee will be cancelled/have their stack emptied
|
||||
/// </summary>
|
||||
public bool Dead;
|
||||
|
||||
/** Relationship variables **/
|
||||
public Dictionary<ushort, List<short>>? MeToObject;
|
||||
public Dictionary<uint, List<short>>? 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<ushort> 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<uint> ChangedRels = new();
|
||||
|
||||
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;
|
||||
|
||||
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<string, VMTreeByNameTableEntry> 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;
|
||||
// }
|
||||
//}
|
||||
|
||||
//bool DynamicMultitile
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return EntryPoints[8].ActionFunction >= 256;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public override string ToString()
|
||||
//{
|
||||
// if (MultitileGroup.Name != "") return MultitileGroup.Name;
|
||||
// var strings = Object.Resource.Get<CTSS>(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
|
||||
|
||||
protected static Direction[] DirectionNotches = new Direction[]
|
||||
{
|
||||
Direction.NORTH,
|
||||
Direction.NORTHEAST,
|
||||
Direction.EAST,
|
||||
Direction.SOUTHEAST,
|
||||
Direction.SOUTH,
|
||||
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 abstract Vector3 VisualPosition { get; set; }
|
||||
public abstract Direction Direction { get; set; }
|
||||
public abstract float RadianDirection { get; set; }
|
||||
|
||||
|
||||
}
|
|
@ -1,12 +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 SimAI.Engine;
|
||||
|
||||
public class VMMemory
|
||||
{
|
||||
public class VMMemory
|
||||
{
|
||||
public VMMemory()
|
||||
{
|
||||
}
|
||||
}
|
||||
public VMMemory()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
// 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 System.Collections.Generic;
|
||||
using SimAI.Engine.Entities;
|
||||
using SimAntics.Engine.Entities;
|
||||
|
||||
namespace SimAI.Engine
|
||||
namespace SimAI.Engine;
|
||||
|
||||
public class VMScheduler
|
||||
{
|
||||
public class VMScheduler
|
||||
{
|
||||
VM VM { get; set; }
|
||||
VM VM { get; set; }
|
||||
|
||||
Dictionary<uint, List<VMEntity>> _tickScheduler = new Dictionary<uint, List<VMEntity>>();
|
||||
List<VMEntity> _tickThisFrame;
|
||||
Dictionary<uint, List<VMEntity>> _tickScheduler = new();
|
||||
List<VMEntity> _tickThisFrame;
|
||||
|
||||
public HashSet<VMEntity> PendingDeletion { get; set; } = new HashSet<VMEntity>();
|
||||
public uint CurrentTickID { get; set; }
|
||||
public short CurrentObjectID { get; set; }
|
||||
public bool RunningNow { get; set; }
|
||||
public HashSet<VMEntity> PendingDeletion { get; set; } = new HashSet<VMEntity>();
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,178 +2,176 @@
|
|||
// 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.Engine.Entities;
|
||||
using SimAI.Marshals;
|
||||
using SimAntics.Engine.Entities;
|
||||
|
||||
namespace SimAI.Engine
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about the execution of a routine
|
||||
/// </summary>
|
||||
public class VMStackFrame
|
||||
{
|
||||
public VMStackFrame() { }
|
||||
namespace SimAI.Engine;
|
||||
|
||||
/** Thread executing this routine **/
|
||||
public VMThread Thread;
|
||||
/// <summary>
|
||||
/// Holds information about the execution of a routine
|
||||
/// </summary>
|
||||
public class VMStackFrame
|
||||
{
|
||||
public VMStackFrame() { }
|
||||
|
||||
/** Routine that this context relates to **/
|
||||
// public VMRoutine Routine;
|
||||
/** Thread executing this routine **/
|
||||
public VMThread Thread;
|
||||
|
||||
/** Current instruction **/
|
||||
public ushort InstructionPointer;
|
||||
/** Routine that this context relates to **/
|
||||
// public VMRoutine Routine;
|
||||
|
||||
/** The object who executed this behavior **/
|
||||
public VMEntity Caller;
|
||||
/** Current instruction **/
|
||||
public ushort InstructionPointer;
|
||||
|
||||
/** The object the code is running on **/
|
||||
public VMEntity Callee;
|
||||
/** The object who executed this behavior **/
|
||||
public VMEntity Caller;
|
||||
|
||||
/** 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);
|
||||
}
|
||||
}
|
||||
/** The object the code is running on **/
|
||||
public VMEntity Callee;
|
||||
|
||||
VMEntity _StackObject;
|
||||
public short _StackObjectID;
|
||||
/** 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);
|
||||
}
|
||||
}
|
||||
|
||||
/** If true, this stack frame is not a subroutine. Return with a continue. **/
|
||||
public bool DiscardResult;
|
||||
VMEntity _StackObject;
|
||||
public short _StackObjectID;
|
||||
|
||||
/** 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;
|
||||
/** If true, this stack frame is not a subroutine. Return with a continue. **/
|
||||
public bool DiscardResult;
|
||||
|
||||
/** 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;
|
||||
// }
|
||||
//}
|
||||
/** 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;
|
||||
|
||||
//public GameObject CodeOwner;
|
||||
/**
|
||||
* Routine locals
|
||||
*/
|
||||
public short[] Locals;
|
||||
/** 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;
|
||||
// }
|
||||
//}
|
||||
|
||||
/**
|
||||
* Arguments
|
||||
*/
|
||||
public short[] Args;
|
||||
//public GameObject CodeOwner;
|
||||
/**
|
||||
* Routine locals
|
||||
*/
|
||||
public short[] Locals;
|
||||
|
||||
//public GameObjectResource CallerPrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Caller.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
/**
|
||||
* Arguments
|
||||
*/
|
||||
public short[] Args;
|
||||
|
||||
//public GameObjectResource CalleePrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Callee.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
//public GameObjectResource CallerPrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Caller.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public GameObjectResource StackObjPrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return StackObject.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
//public GameObjectResource CalleePrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Callee.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public GameGlobal Global
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Thread.Context.Globals;
|
||||
// }
|
||||
//}
|
||||
//public GameObjectResource StackObjPrivate
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return StackObject.Object.Resource;
|
||||
// }
|
||||
//}
|
||||
|
||||
public VM VM
|
||||
{
|
||||
get
|
||||
{
|
||||
return Thread.Context.VM;
|
||||
}
|
||||
}
|
||||
//public GameGlobal Global
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Thread.Context.Globals;
|
||||
// }
|
||||
//}
|
||||
|
||||
/** Utilities **/
|
||||
//public VMInstruction GetCurrentInstruction()
|
||||
//{
|
||||
// return Routine.Instructions[InstructionPointer];
|
||||
//}
|
||||
public VM VM
|
||||
{
|
||||
get
|
||||
{
|
||||
return Thread.Context.VM;
|
||||
}
|
||||
}
|
||||
|
||||
//public T GetCurrentOperand<T>()
|
||||
//{
|
||||
// return (T)GetCurrentInstruction().Operand;
|
||||
//}
|
||||
/** Utilities **/
|
||||
//public VMInstruction GetCurrentInstruction()
|
||||
//{
|
||||
// return Routine.Instructions[InstructionPointer];
|
||||
//}
|
||||
|
||||
#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 T GetCurrentOperand<T>()
|
||||
//{
|
||||
// return (T)GetCurrentInstruction().Operand;
|
||||
//}
|
||||
|
||||
public virtual void Load(VMStackFrameMarshal input, VMContext context)
|
||||
{
|
||||
// CodeOwner = GameContent.Get.WorldObjects.Get(input.CodeOwnerGUID);
|
||||
#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,
|
||||
// };
|
||||
//}
|
||||
|
||||
// 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);
|
||||
public virtual void Load(VMStackFrameMarshal input, VMContext context)
|
||||
{
|
||||
// CodeOwner = GameContent.Get.WorldObjects.Get(input.CodeOwnerGUID);
|
||||
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
|
||||
public VMStackFrame(VMStackFrameMarshal input, VMContext context, VMThread thread)
|
||||
{
|
||||
Thread = thread;
|
||||
// Load(input, context);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -5,52 +5,50 @@
|
|||
#define IDE_COMPAT
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using SimAI.Engine.Entities;
|
||||
using SimAntics.Engine.Entities;
|
||||
|
||||
namespace SimAI.Engine
|
||||
namespace SimAI.Engine;
|
||||
|
||||
/// <summary>
|
||||
/// Compatibility class
|
||||
/// </summary>
|
||||
public class VMThread : VMInstruction { }
|
||||
|
||||
/// <summary>
|
||||
/// Handles instruction sets
|
||||
/// </summary>
|
||||
public class VMInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Compatibility class
|
||||
/// </summary>
|
||||
public class VMThread : VMInstruction { }
|
||||
|
||||
/// <summary>
|
||||
/// Handles instruction sets
|
||||
/// </summary>
|
||||
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<VMStackFrame> Stack;
|
||||
bool ContinueExecution;
|
||||
public List<VMStackFrame>? 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;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
// 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 System.Collections.Generic;
|
||||
|
||||
namespace SimAI.Engine.Entities
|
||||
{
|
||||
public class VMEntityRTTI
|
||||
{
|
||||
public string[] AttributeLabels;
|
||||
}
|
||||
|
||||
public abstract class VMEntity
|
||||
{
|
||||
public static bool UseWorld = true;
|
||||
public VMEntityRTTI RTTI;
|
||||
public bool GhostImage;
|
||||
|
||||
public short ObjectID;
|
||||
public uint PersistID;
|
||||
|
||||
public short[] ObjectData;
|
||||
public LinkedList<short> MyList = new LinkedList<short>();
|
||||
// public List<VMSoundEntry> SoundThreads;
|
||||
|
||||
// public VMRuntimeHeadline Headline;
|
||||
/// <summary>
|
||||
/// IS NOT serialized, but rather regenerated on deserialize.
|
||||
/// </summary>
|
||||
// public VMHeadlineRenderer HeadlineRenderer;
|
||||
|
||||
// public GameObject Object;
|
||||
public VMThread Thread;
|
||||
// public VMMultitileGroup MultitileGroup;
|
||||
|
||||
public short MainParam; //parameters passed to main on creation.
|
||||
public short MainStackOBJ;
|
||||
|
||||
public VMEntity[] Contained = new VMEntity[0];
|
||||
public VMEntity Container;
|
||||
public short ContainerSlot;
|
||||
/// <summary>
|
||||
/// set when the entity is removed, threads owned by this object or with this object as callee will be cancelled/have their stack emptied
|
||||
/// </summary>
|
||||
public bool Dead;
|
||||
|
||||
/** Relationship variables **/
|
||||
public Dictionary<ushort, List<short>> MeToObject;
|
||||
public Dictionary<uint, List<short>> 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<ushort> MayHaveRelToMe = new HashSet<ushort>();
|
||||
|
||||
//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<uint> ChangedRels = new HashSet<uint>();
|
||||
|
||||
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;
|
||||
|
||||
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<string, VMTreeByNameTableEntry> 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;
|
||||
// }
|
||||
//}
|
||||
|
||||
//bool DynamicMultitile
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return EntryPoints[8].ActionFunction >= 256;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public override string ToString()
|
||||
//{
|
||||
// if (MultitileGroup.Name != "") return MultitileGroup.Name;
|
||||
// var strings = Object.Resource.Get<CTSS>(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
|
||||
|
||||
protected static Direction[] DirectionNotches = new Direction[]
|
||||
{
|
||||
Direction.NORTH,
|
||||
Direction.NORTHEAST,
|
||||
Direction.EAST,
|
||||
Direction.SOUTHEAST,
|
||||
Direction.SOUTH,
|
||||
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 abstract Vector3 VisualPosition { get; set; }
|
||||
public abstract Direction Direction { get; set; }
|
||||
public abstract float RadianDirection { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
2
src/SimAI/GlobalUsing.cs
Normal file
2
src/SimAI/GlobalUsing.cs
Normal file
|
@ -0,0 +1,2 @@
|
|||
global using SimAI.Engine;
|
||||
global using SimAI.Marshals;
|
|
@ -1,15 +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 SimAI
|
||||
public interface IVM
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,10 +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 SimAI.Interfaces;
|
||||
|
||||
public interface VMIMotiveDecay : VMSerializable
|
||||
{
|
||||
public interface VMIMotiveDecay : VMSerializable
|
||||
{
|
||||
// void Tick(VMAvatar avatar, VMContext context);
|
||||
}
|
||||
// void Tick(VMAvatar avatar, VMContext context);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// 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 SimAI.Interfaces;
|
||||
|
||||
public interface VMSerializable
|
||||
{
|
||||
public interface VMSerializable
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,13 +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/.
|
||||
using System;
|
||||
namespace SimAI.Marshals
|
||||
namespace SimAI.Marshals;
|
||||
|
||||
public class VMMarshal
|
||||
{
|
||||
public class VMMarshal
|
||||
{
|
||||
public VMMarshal()
|
||||
{
|
||||
}
|
||||
}
|
||||
public VMMarshal()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,70 +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/.
|
||||
using System;
|
||||
using System.IO;
|
||||
namespace SimAI.Marshals;
|
||||
|
||||
namespace SimAI.Marshals
|
||||
public class VMStackFrameMarshal
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<RootNamespace>SimAntics</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>SimAntics</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Authors>Tony Bark</Authors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Entities\" />
|
||||
<Folder Include="Interfaces\" />
|
||||
<Folder Include="Marshals\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Engine\Entities\" />
|
||||
<Folder Include="Interfaces\" />
|
||||
<Folder Include="Marshals\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
250
src/SimAI/VM.cs
250
src/SimAI/VM.cs
|
@ -1,144 +1,140 @@
|
|||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using SimAI.Engine;
|
||||
using SimAI.Engine.Entities;
|
||||
using SimAntics.Engine.Entities;
|
||||
|
||||
namespace SimAI
|
||||
namespace SimAI;
|
||||
|
||||
/// <summary>
|
||||
/// VM is an abstract class that contains the
|
||||
/// </summary>
|
||||
public abstract class VM : IVM
|
||||
{
|
||||
/// <summary>
|
||||
/// VM is an abstract class that contains the
|
||||
/// </summary>
|
||||
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<short, VMEntity> ObjectsById = new Dictionary<short, VMEntity>();
|
||||
short ObjectId = 1;
|
||||
Dictionary<short, VMEntity> ObjectsById = new();
|
||||
short ObjectId = 1;
|
||||
|
||||
public List<VMEntity> Entities = new List<VMEntity>();
|
||||
public HashSet<VMEntity> SoundEntities = new HashSet<VMEntity>();
|
||||
public short[] GlobalState;
|
||||
|
||||
int GameTickRate = 60;
|
||||
int GameTickNum = 0;
|
||||
public int SpeedMultiplier = 1;
|
||||
public int LastSpeedMultiplier;
|
||||
int LastFrameSpeed = 1;
|
||||
float Fraction;
|
||||
public VMEntity GlobalBlockingDialog;
|
||||
public List<VMEntity> Entities = new();
|
||||
public HashSet<VMEntity> SoundEntities = new();
|
||||
public short[] GlobalState;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an entity from this VM.
|
||||
/// </summary>
|
||||
/// <param name="id">The entity's ID.</param>
|
||||
/// <returns>A VMEntity instance associated with the ID.</returns>
|
||||
public VMEntity GetObjectById(short id)
|
||||
{
|
||||
return ObjectsById.ContainsKey(id) ? ObjectsById[id] : null;
|
||||
}
|
||||
int GameTickRate = 60;
|
||||
int GameTickNum = 0;
|
||||
public int SpeedMultiplier = 1;
|
||||
public int LastSpeedMultiplier;
|
||||
int LastFrameSpeed = 1;
|
||||
float Fraction;
|
||||
public VMEntity GlobalBlockingDialog;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Virtual Machine instance.
|
||||
/// </summary>
|
||||
/// <param name="context">The VMContext instance to use.</param>
|
||||
public VM(VMContext context)
|
||||
{
|
||||
context.VM = this;
|
||||
Context = context;
|
||||
Scheduler = new VMScheduler(this);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets an entity from this VM.
|
||||
/// </summary>
|
||||
/// <param name="id">The entity's ID.</param>
|
||||
/// <returns>A VMEntity instance associated with the ID.</returns>
|
||||
public VMEntity? GetObjectById(short id)
|
||||
{
|
||||
return ObjectsById.ContainsKey(id) ? ObjectsById[id] : null;
|
||||
}
|
||||
|
||||
public VMEntity GetObjectByPersist(uint id)
|
||||
{
|
||||
// return Entities.FirstOrDefault(x => x.PersistID == id);
|
||||
throw new VMSimanticsException();
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructs a new Virtual Machine instance.
|
||||
/// </summary>
|
||||
/// <param name="context">The VMContext instance to use.</param>
|
||||
public VM(VMContext context)
|
||||
{
|
||||
context.VM = this;
|
||||
Context = context;
|
||||
Scheduler = new VMScheduler(this);
|
||||
}
|
||||
|
||||
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 VMEntity GetObjectByPersist(uint id)
|
||||
{
|
||||
// return Entities.FirstOrDefault(x => x.PersistID == id);
|
||||
throw new VMSimanticsException();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public virtual void Update()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
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 Tick()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public virtual void Reset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public virtual void Update()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void InternalTick(uint tickId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an entity to this Virtual Machine.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add.</param>
|
||||
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<VMEntity> 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 virtual void Tick()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an entity from this Virtual Machine.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove.</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
public virtual void InternalTick(uint tickId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an entity to this Virtual Machine.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to add.</param>
|
||||
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<VMEntity> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an entity from this Virtual Machine.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove.</param>
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,46 +1,44 @@
|
|||
// 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 System;
|
||||
|
||||
namespace SimAI
|
||||
namespace SimAI;
|
||||
|
||||
public class VMClock
|
||||
{
|
||||
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 VMClock() {}
|
||||
public DateTime UTCNow => new DateTime(UTCStart).AddSeconds(Ticks / 30.0);
|
||||
|
||||
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 VMClock() { }
|
||||
|
||||
Ticks++;
|
||||
}
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
|
@ -1,11 +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 SimAI;
|
||||
|
||||
public class VMContext
|
||||
{
|
||||
public class VMContext
|
||||
{
|
||||
public static bool useWorld = true;
|
||||
public VM VM { get; set; }
|
||||
}
|
||||
public static bool useWorld = true;
|
||||
public VM? VM { get; set; }
|
||||
}
|
|
@ -1,98 +1,94 @@
|
|||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SimAI.Engine;
|
||||
|
||||
namespace SimAI
|
||||
namespace SimAI;
|
||||
|
||||
public class VMSimanticsException : Exception
|
||||
{
|
||||
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<VMStackFrame> stack)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
var prevEE = "";
|
||||
var prevER = "";
|
||||
public static string GetStackTrace(List<VMStackFrame> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "3.1.201"
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue