public void Breakpoint(VMStackFrame frame) { if (IsCheck) { return; //can't breakpoint in check trees. } ThreadBreak = VMThreadBreakMode.Pause; BreakFrame = Stack.IndexOf(frame); Context.VM.BreakpointHit(Entity); }
public void Tick() { #if IDE_COMPAT if (ThreadBreak == VMThreadBreakMode.Pause) { return; } else if (ThreadBreak == VMThreadBreakMode.Reset) { Entity.Reset(Context); ThreadBreak = VMThreadBreakMode.Active; } else if (ThreadBreak == VMThreadBreakMode.Immediate) { Breakpoint(Stack.LastOrDefault(), "Paused."); return; } if (RoutineDirty) { foreach (var frame in Stack) { if (frame.Routine.Chunk.RuntimeVer != frame.Routine.RuntimeVer) { frame.Routine = Context.VM.Assemble(frame.Routine.Chunk); } } RoutineDirty = false; } #endif if (BlockingState != null) { BlockingState.WaitTime++; } if (DialogCooldown > 0) { DialogCooldown--; } #if !THROW_SIMANTICS try { #endif if (!Entity.Dead) { if (QueueDirty) { EvaluateQueuePriorities(); TryRunImmediately(); QueueDirty = false; } if (Stack.Count == 0) { if (IsCheck) { return; //running out of execution means check trees have ended. } Entity.ExecuteEntryPoint(1, Context, false); if (Stack.Count == 0) { return; } } if ((!Stack.LastOrDefault().ActionTree) || (!Queue[0].Callee.Dead)) //main or our target is not dead { #if IDE_COMPAT if (ThreadBreak == VMThreadBreakMode.ReturnTrue) { var bf = Stack[BreakFrame]; HandleResult(bf, bf.GetCurrentInstruction(), VMPrimitiveExitCode.RETURN_TRUE); Breakpoint(Stack.LastOrDefault(), "Returned True."); return; } if (ThreadBreak == VMThreadBreakMode.ReturnFalse) { var bf = Stack[BreakFrame]; HandleResult(bf, bf.GetCurrentInstruction(), VMPrimitiveExitCode.RETURN_TRUE); Breakpoint(Stack.LastOrDefault(), "Returned False."); return; } #endif ContinueExecution = true; while (ContinueExecution) { if (TicksThisFrame++ > MAX_LOOP_COUNT) { throw new Exception("Thread entered infinite loop! ( >" + MAX_LOOP_COUNT + " primitives)"); } ContinueExecution = false; NextInstruction(); } } else //interaction owner is dead, rip { Entity.Reset(Context); } } #if !THROW_SIMANTICS } catch (Exception e) { #if IDE_COMPAT if (!IsCheck && VM.SignalBreaks) { Breakpoint(Stack.LastOrDefault(), "!" + e.Message + " " + StackTraceSimplify(e.StackTrace.Split('\n').FirstOrDefault(x => x.Contains(".cs")) ?? "")); ContinueExecution = false; return; } #endif if (e is ThreadAbortException) { throw e; } if (Stack.Count == 0) { return; } var context = Stack[Stack.Count - 1]; bool Delete = ((Entity is VMGameObject) && (DialogCooldown > 30 * 20 - 10)); if (DialogCooldown == 0) { var simExcept = new VMSimanticsException(e.Message + StackTraceSimplify(e.StackTrace.Split('\n').FirstOrDefault(x => x.Contains(".cs")) ?? ""), context); string exceptionStr = "A SimAntics Exception has occurred, and has been suppressed: \r\n\r\n" + simExcept.ToString() + "\r\n\r\nThe object will be reset. Please report this!"; VMDialogInfo info = new VMDialogInfo { Caller = null, Icon = context.Callee, Operand = new VMDialogOperand { }, Message = exceptionStr, Title = "SimAntics Exception!" }; Context.VM.SignalDialog(info); DialogCooldown = 30 * 20; } if (!IsCheck) { context.Callee.Reset(context.VM.Context); context.Caller.Reset(context.VM.Context); if (Delete) { Entity.Delete(true, context.VM.Context); } } else { Stack.Clear(); } } #endif }
public void Breakpoint(VMStackFrame frame) { if (IsCheck) return; //can't breakpoint in check trees. ThreadBreak = VMThreadBreakMode.Pause; BreakFrame = Stack.IndexOf(frame); Context.VM.BreakpointHit(Entity); }