mirror of
https://github.com/LazyDuchess/OpenTS2.git
synced 2025-01-22 16:21:47 -05:00
VMStack -> VMThread
This commit is contained in:
parent
0229014e46
commit
a0acde0273
9 changed files with 35 additions and 34 deletions
|
@ -12,7 +12,7 @@ namespace OpenTS2.SimAntics.Primitives
|
|||
{
|
||||
var stackObj = ctx.StackObjectEntity;
|
||||
if (stackObj != null)
|
||||
ctx.VM.Scheduler.ScheduleInterrupt(stackObj.Stack);
|
||||
ctx.VM.Scheduler.ScheduleInterrupt(stackObj.MainThread);
|
||||
return VMReturnValue.ReturnTrue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace OpenTS2.SimAntics.Primitives
|
|||
{
|
||||
var argumentIndex = ctx.Node.GetUInt16Operand(0);
|
||||
var sleepTicks = (uint)Math.Max(0,(int)ctx.StackFrame.Arguments[argumentIndex]);
|
||||
return new VMReturnValue(new ContinueHandler(ctx.Stack, sleepTicks));
|
||||
return new VMReturnValue(new ContinueHandler(ctx.Thread, sleepTicks));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -24,24 +24,24 @@ namespace OpenTS2.SimAntics.Primitives
|
|||
public class ContinueHandler : VMContinueHandler
|
||||
{
|
||||
public uint TargetTick = 0;
|
||||
VMStack _stack;
|
||||
VMThread _thread;
|
||||
|
||||
public ContinueHandler(VMStack stack, uint ticks)
|
||||
public ContinueHandler(VMThread thread, uint ticks)
|
||||
{
|
||||
_stack = stack;
|
||||
var vm = _stack.Entity.VM;
|
||||
_thread = thread;
|
||||
var vm = _thread.Entity.VM;
|
||||
TargetTick = vm.CurrentTick + ticks;
|
||||
}
|
||||
|
||||
public override VMExitCode Tick()
|
||||
{
|
||||
if (_stack.Interrupt)
|
||||
if (_thread.Interrupt)
|
||||
{
|
||||
// Handled!
|
||||
_stack.Interrupt = false;
|
||||
_thread.Interrupt = false;
|
||||
return VMExitCode.True;
|
||||
}
|
||||
if (_stack.Entity.VM.CurrentTick >= TargetTick)
|
||||
if (_thread.Entity.VM.CurrentTick >= TargetTick)
|
||||
return VMExitCode.True;
|
||||
return VMExitCode.Continue;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace OpenTS2.SimAntics
|
|||
{
|
||||
public VMStackFrame StackFrame;
|
||||
public BHAVAsset.Node Node;
|
||||
public VMStack Stack => StackFrame.Stack;
|
||||
public VMEntity Entity => StackFrame.Stack.Entity;
|
||||
public VMThread Thread => StackFrame.Thread;
|
||||
public VMEntity Entity => StackFrame.Thread.Entity;
|
||||
public VMEntity StackObjectEntity => VM.GetEntityByID(StackFrame.StackObjectID);
|
||||
public VM VM => Entity.VM;
|
||||
|
||||
|
|
|
@ -8,14 +8,15 @@ using System.Threading.Tasks;
|
|||
namespace OpenTS2.SimAntics
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a process or thread running in the SimAntics virtual machine, with its own stack and temp variables.
|
||||
/// This is a process running in the SimAntics virtual machine.
|
||||
/// </summary>
|
||||
public class VMEntity
|
||||
{
|
||||
public bool PendingDeletion = false;
|
||||
public short ID = 1;
|
||||
public short[] Temps = new short[20];
|
||||
public VMStack Stack;
|
||||
// Main thread the VM will tick.
|
||||
public VMThread MainThread;
|
||||
public VM VM;
|
||||
public ObjectDefinitionAsset ObjectDefinition;
|
||||
public uint PrivateGroupID => ObjectDefinition.GlobalTGI.GroupID;
|
||||
|
@ -32,7 +33,7 @@ namespace OpenTS2.SimAntics
|
|||
|
||||
protected VMEntity()
|
||||
{
|
||||
Stack = new VMStack(this);
|
||||
MainThread = new VMThread(this);
|
||||
}
|
||||
|
||||
public VMEntity(ObjectDefinitionAsset objectDefinition) : this()
|
||||
|
@ -42,7 +43,7 @@ namespace OpenTS2.SimAntics
|
|||
|
||||
public void Tick()
|
||||
{
|
||||
Stack.Tick();
|
||||
MainThread.Tick();
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
|
|
|
@ -44,11 +44,11 @@ namespace OpenTS2.SimAntics
|
|||
}
|
||||
|
||||
// TODO - Right now the way this works is that once an entity has been notified out of idle/interrupted, the first idle that gets executed on the next tick (or that continues to run if there is one already running) won't actually sleep. If no idles are ran then the interrupt is just discarded. Verify this is okay!
|
||||
public void ScheduleInterrupt(VMStack stack)
|
||||
public void ScheduleInterrupt(VMThread thread)
|
||||
{
|
||||
ScheduleWhenPossible(() =>
|
||||
{
|
||||
stack.Interrupt = true;
|
||||
thread.Interrupt = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace OpenTS2.SimAntics
|
|||
/// </summary>
|
||||
public class VMStackFrame
|
||||
{
|
||||
public VMStack Stack;
|
||||
public VMThread Thread;
|
||||
public BHAVAsset BHAV;
|
||||
public short StackObjectID = 0;
|
||||
public int CurrentNode = 0;
|
||||
|
@ -25,10 +25,10 @@ namespace OpenTS2.SimAntics
|
|||
public short[] Arguments;
|
||||
private static int MaxIterations = 500000;
|
||||
|
||||
public VMStackFrame(BHAVAsset bhav, VMStack stack)
|
||||
public VMStackFrame(BHAVAsset bhav, VMThread thread)
|
||||
{
|
||||
BHAV = bhav;
|
||||
Stack = stack;
|
||||
Thread = thread;
|
||||
Locals = new short[BHAV.LocalCount];
|
||||
Arguments = new short[BHAV.ArgumentCount];
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ namespace OpenTS2.SimAntics
|
|||
var newStackFrame = CreateStackFrameForNode(context);
|
||||
if (newStackFrame != null)
|
||||
{
|
||||
Stack.Frames.Push(newStackFrame);
|
||||
Thread.Frames.Push(newStackFrame);
|
||||
return newStackFrame.Tick();
|
||||
}
|
||||
else
|
||||
|
@ -145,7 +145,7 @@ namespace OpenTS2.SimAntics
|
|||
if (bhav == null)
|
||||
return null;
|
||||
|
||||
var newStackFrame = new VMStackFrame(bhav, Stack);
|
||||
var newStackFrame = new VMStackFrame(bhav, Thread);
|
||||
newStackFrame.StackObjectID = ctx.StackFrame.StackObjectID;
|
||||
|
||||
GoSubFormat format = GoSubFormat.PassTemps;
|
||||
|
@ -173,10 +173,10 @@ namespace OpenTS2.SimAntics
|
|||
switch(format)
|
||||
{
|
||||
case GoSubFormat.PassTemps:
|
||||
argAmount = Math.Min(newStackFrame.Arguments.Length, Stack.Entity.Temps.Length);
|
||||
argAmount = Math.Min(newStackFrame.Arguments.Length, Thread.Entity.Temps.Length);
|
||||
for (var i=0;i<argAmount;i++)
|
||||
{
|
||||
newStackFrame.TrySetArgument(i, Stack.Entity.Temps[i]);
|
||||
newStackFrame.TrySetArgument(i, Thread.Entity.Temps[i]);
|
||||
}
|
||||
break;
|
||||
case GoSubFormat.TS1:
|
||||
|
@ -225,12 +225,12 @@ namespace OpenTS2.SimAntics
|
|||
BHAVAsset GetBHAVForOpCode(ushort opCode)
|
||||
{
|
||||
// 0x0XXX is global scope, 0x1XXX is private scope and 0x2XXX is semiglobal scope.
|
||||
var groupid = Stack.Entity.SemiGlobalGroupID;
|
||||
var groupid = Thread.Entity.SemiGlobalGroupID;
|
||||
|
||||
if (opCode < 0x1000)
|
||||
groupid = GroupIDs.Global;
|
||||
else if (opCode < 0x2000)
|
||||
groupid = Stack.Entity.PrivateGroupID;
|
||||
groupid = Thread.Entity.PrivateGroupID;
|
||||
|
||||
return VM.GetBHAV(opCode, groupid);
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ using System.Threading.Tasks;
|
|||
namespace OpenTS2.SimAntics
|
||||
{
|
||||
/// <summary>
|
||||
/// Stack of scripts to run on a SimAntics entity/thread.
|
||||
/// Thread running in a VM Entity.
|
||||
/// </summary>
|
||||
public class VMStack
|
||||
public class VMThread
|
||||
{
|
||||
public bool Interrupt = false;
|
||||
// For check trees and other things that should execute and return immediately we should set this to false.
|
||||
public bool CanYield = true;
|
||||
public VMEntity Entity;
|
||||
public Stack<VMStackFrame> Frames = new Stack<VMStackFrame>();
|
||||
public VMStack(VMEntity entity)
|
||||
public VMThread(VMEntity entity)
|
||||
{
|
||||
Entity = entity;
|
||||
}
|
|
@ -45,8 +45,8 @@ public class SimAnticsTest
|
|||
var entity = new VMEntity(testObjectDefinition);
|
||||
vm.AddEntity(entity);
|
||||
|
||||
var stackFrame = new VMStackFrame(bhav, entity.Stack);
|
||||
entity.Stack.Frames.Push(stackFrame);
|
||||
var stackFrame = new VMStackFrame(bhav, entity.MainThread);
|
||||
entity.MainThread.Frames.Push(stackFrame);
|
||||
|
||||
// Test BHAV:
|
||||
// Multiplies Param0 by 2, stores it in Temp0
|
||||
|
@ -61,7 +61,7 @@ public class SimAnticsTest
|
|||
vm.Tick();
|
||||
Assert.That(entity.Temps[0], Is.EqualTo(1200));
|
||||
// Interrupt idle here, so that it doesn't sleep for 20000 ticks.
|
||||
vm.Scheduler.ScheduleInterrupt(entity.Stack);
|
||||
vm.Scheduler.ScheduleInterrupt(entity.MainThread);
|
||||
vm.Tick();
|
||||
Assert.That(entity.Temps[0], Is.EqualTo(0));
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ public class SimAnticsTest
|
|||
var entity = new VMEntity(testObjectDefinition);
|
||||
vm.AddEntity(entity);
|
||||
|
||||
var stackFrame = new VMStackFrame(bhav, entity.Stack);
|
||||
entity.Stack.Frames.Push(stackFrame);
|
||||
var stackFrame = new VMStackFrame(bhav, entity.MainThread);
|
||||
entity.MainThread.Frames.Push(stackFrame);
|
||||
|
||||
Assert.Throws<SimAnticsException>(() =>
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue