implement non blocking stack, return exitcodes from stack.

This commit is contained in:
Nahuel Rocchetti 2023-08-21 20:49:12 -03:00
parent a4d4dacf5c
commit 5f8513d320
3 changed files with 15 additions and 11 deletions

View file

@ -10,14 +10,14 @@ namespace OpenTS2.SimAntics
{ {
public enum ExitCode : byte public enum ExitCode : byte
{ {
GoToTrue, True,
GoToFalse, False,
Continue Continue
} }
public ExitCode Code; public ExitCode Code;
public Func<ExitCode> ContinueCallback = null; public Func<ExitCode> ContinueCallback = null;
public static VMReturnValue ReturnTrue = new VMReturnValue { Code = ExitCode.GoToTrue }; public static VMReturnValue ReturnTrue = new VMReturnValue { Code = ExitCode.True };
public static VMReturnValue ReturnFalse = new VMReturnValue { Code = ExitCode.GoToFalse }; public static VMReturnValue ReturnFalse = new VMReturnValue { Code = ExitCode.False };
// TODO: would probably be a good idea to implement a scheduler for this. // TODO: would probably be a good idea to implement a scheduler for this.
public static VMReturnValue Sleep(VM vm, uint ticks) public static VMReturnValue Sleep(VM vm, uint ticks)
{ {
@ -27,7 +27,7 @@ namespace OpenTS2.SimAntics
returnValue.ContinueCallback = () => { returnValue.ContinueCallback = () => {
{ {
if (vm.CurrentTick >= targetTick) if (vm.CurrentTick >= targetTick)
return ExitCode.GoToTrue; return ExitCode.True;
return ExitCode.Continue; return ExitCode.Continue;
} }
}; };

View file

@ -8,33 +8,37 @@ namespace OpenTS2.SimAntics
{ {
public class VMStack public class VMStack
{ {
public bool CanYield = true;
public VMEntity Entity; public VMEntity Entity;
public Stack<VMStackFrame> Frames = new Stack<VMStackFrame>(); public Stack<VMStackFrame> Frames = new Stack<VMStackFrame>();
public VMStack(VMEntity entity) public VMStack(VMEntity entity)
{ {
Entity = entity; Entity = entity;
} }
public void Tick() public VMReturnValue.ExitCode Tick()
{ {
if (Frames.Count == 0) if (Frames.Count == 0)
return; return VMReturnValue.ExitCode.False;
var currentFrame = Frames.Peek(); var currentFrame = Frames.Peek();
var returnValue = currentFrame.Tick(); var returnValue = currentFrame.Tick();
if (returnValue.Code == VMReturnValue.ExitCode.Continue && !CanYield)
throw new Exception("Attempted to yield in a non-yielding VMStack.");
while (returnValue.Code != VMReturnValue.ExitCode.Continue) while (returnValue.Code != VMReturnValue.ExitCode.Continue)
{ {
Frames.Pop(); Frames.Pop();
if (Frames.Count == 0) if (Frames.Count == 0)
return; return returnValue.Code;
currentFrame = Frames.Peek(); currentFrame = Frames.Peek();
var currentNode = currentFrame.GetCurrentNode(); var currentNode = currentFrame.GetCurrentNode();
if (returnValue.Code == VMReturnValue.ExitCode.GoToTrue) if (returnValue.Code == VMReturnValue.ExitCode.True)
currentFrame.CurrentNode = currentNode.TrueTarget; currentFrame.CurrentNode = currentNode.TrueTarget;
else else
currentFrame.CurrentNode = currentNode.FalseTarget; currentFrame.CurrentNode = currentNode.FalseTarget;
returnValue = currentFrame.Tick(); returnValue = currentFrame.Tick();
} }
return returnValue.Code;
} }
} }
} }

View file

@ -42,7 +42,7 @@ namespace OpenTS2.SimAntics
{ {
var currentNode = GetCurrentNode(); var currentNode = GetCurrentNode();
ushort returnTarget = 0; ushort returnTarget = 0;
if (returnValue.Code == VMReturnValue.ExitCode.GoToTrue) if (returnValue.Code == VMReturnValue.ExitCode.True)
returnTarget = currentNode.TrueTarget; returnTarget = currentNode.TrueTarget;
else else
returnTarget = currentNode.FalseTarget; returnTarget = currentNode.FalseTarget;
@ -88,7 +88,7 @@ namespace OpenTS2.SimAntics
{ {
CurrentContinueCallback = null; CurrentContinueCallback = null;
ushort returnTarget = 0; ushort returnTarget = 0;
if (primReturn.Code == VMReturnValue.ExitCode.GoToTrue) if (primReturn.Code == VMReturnValue.ExitCode.True)
returnTarget = currentNode.TrueTarget; returnTarget = currentNode.TrueTarget;
else else
returnTarget = currentNode.FalseTarget; returnTarget = currentNode.FalseTarget;