Ejemplo n.º 1
0
        public void Tick()
        {
#if IDE_COMPAT
            if (ThreadBreak == VMThreadBreakMode.Pause)
            {
                return;
            }
            else if (ThreadBreak == VMThreadBreakMode.Immediate)
            {
                Breakpoint(Stack.LastOrDefault()); 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--;
            }

            try {
                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.Count > 0 && (Queue[0] != null && !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());
                            return;
                        }
                        if (ThreadBreak == VMThreadBreakMode.ReturnFalse)
                        {
                            var bf = Stack[BreakFrame];
                            HandleResult(bf, bf.GetCurrentInstruction(), VMPrimitiveExitCode.RETURN_TRUE);
                            Breakpoint(Stack.LastOrDefault());
                            return;
                        }
#endif
                        ContinueExecution = true;
                        while (ContinueExecution)
                        {
                            if (TicksThisFrame++ > MAX_LOOP_COUNT)
                            {
                                throw new Exception("Thread entered infinite loop! ( >" + MAX_LOOP_COUNT + " primitives)");
                            }

                            if (Entity.GetBadObjects())
                            {
                                Entity.Delete(true, Context);
                            }

                            ContinueExecution = false;
                            NextInstruction();
                        }
                    }
                    else //interaction owner is dead, rip
                    {
                        Entity.Reset(Context);
                        Entity.Reseted = true;
                    }
                }
            } catch (Exception 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, 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;
                }

                context.Callee.Reset(context.VM.Context);
                context.Caller.Reset(context.VM.Context);

                if (Delete)
                {
                    Entity.Delete(true, context.VM.Context);
                }
            }
        }