Esempio n. 1
0
        /// <summary>
        /// 处理并行调用和信号函数的消息循环
        /// </summary>
        private void ParallelUpdateContext(object sender, EventArgs e)
        {
            // 如果主消息循环暂停那么就直接迭代掉
            if (Director.IsContextUpdatePaused)
            {
                return;
            }
            // 获取绑定的调用堆栈
            var dispatcher = sender as DispatcherTimer;

            dispatcher.Stop();
            ParallelDispatcherArgsPackage pdap;

            try
            {
                pdap = dispatcher.Tag as ParallelDispatcherArgsPackage;
            }
            catch (Exception ex)
            {
                LogUtils.LogLine("Parallel Failed " + ex, "Director", LogLevel.Warning);
                dispatcher.Start();
                return;
            }
            if (pdap == null)
            {
                LogUtils.LogLine("Parallel Failed.", "Director", LogLevel.Warning);
                dispatcher.Start();
                return;
            }
            var paraVM = pdap.IsSemaphore ? pdap.SemaphoreStack : Director.RunMana.ParallelExecutorStack.Peek()[pdap.Index].Executor;

            bool resumeFlag = true;

            while (true)
            {
                // 取得调用堆栈顶部状态
                StackMachineState stackState    = Director.RunMana.GameState(paraVM);
                GameState         paraGameState = GameState.Exit;
                switch (stackState)
                {
                case StackMachineState.Interpreting:
                case StackMachineState.FunctionCalling:
                    resumeFlag    = false;
                    paraGameState = GameState.Performing;
                    break;

                case StackMachineState.WaitUser:
                    dispatcher.Start();
                    return;

                case StackMachineState.WaitAnimation:
                    // 并行器里不应该出现等待动画结束,立即结束本次迭代
                    return;

                case StackMachineState.Await:
                    paraGameState = GameState.Waiting;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Interrupt:
                    LogUtils.LogLine(
                        "There is a interrupt in parallel function, which may cause system pause",
                        "Director", LogLevel.Warning);
                    paraGameState = GameState.Interrupt;
                    resumeFlag    = false;
                    break;

                case StackMachineState.NOP:
                    paraGameState = GameState.Exit;
                    resumeFlag    = true;
                    break;
                }
                // 根据调用堆栈顶部更新系统
                switch (paraGameState)
                {
                // 等待状态
                case GameState.Waiting:
                    // 计算已经等待的时间
                    if (DateTime.Now - paraVM.ESP.TimeStamp > paraVM.ESP.Delay)
                    {
                        paraVM.Consume();
                    }
                    break;

                // 等待动画
                case GameState.WaitAni:
                    if (SpriteAnimation.IsAnyAnimation == false)
                    {
                        paraVM.Consume();
                    }
                    break;

                // 演绎脚本
                case GameState.Performing:
                    // 取下一动作
                    var nextInstruct = Director.RunMana.MoveNext(paraVM);
                    // 如果指令空了就立即迭代本次消息循环
                    if (nextInstruct == null)
                    {
                        dispatcher.Start();
                        return;
                    }
                    // 处理影响调用堆栈的动作
                    if (nextInstruct.Type == SActionType.act_wait)
                    {
                        double waitMs = nextInstruct.ArgsDict.ContainsKey("time")
                                ? (double)PolishEvaluator.Evaluate(nextInstruct.ArgsDict["time"], paraVM)
                                : 0;
                        paraVM.Submit("Parallel Time Waiting", DateTime.Now, TimeSpan.FromMilliseconds(waitMs));
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waitani)
                    {
                        // 并行器里不应该出现等待动画结束,立即结束本次迭代
                        LogUtils.LogLine(
                            "There is a animation wait in parallel function, which may cause system pause",
                            "Director", LogLevel.Warning);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waituser)
                    {
                        LogUtils.LogLine(
                            "There is a user wait in parallel function, which may cause system pause",
                            "Director", LogLevel.Warning);
                        paraVM.Submit("Director", nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_jump)
                    {
                        var jumpToScene  = nextInstruct.ArgsDict["filename"];
                        var jumpToTarget = nextInstruct.ArgsDict["target"];
                        // 场景内跳转
                        if (jumpToScene == String.Empty)
                        {
                            if (stackState == StackMachineState.Interpreting)
                            {
                                var currentScene = this.resMana.GetScene(paraVM.ESP.BindingSceneName);
                                if (!currentScene.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                paraVM.ESP.MircoStep(currentScene.LabelDictionary[jumpToTarget]);
                            }
                            else if (stackState == StackMachineState.FunctionCalling)
                            {
                                var currentFunc = paraVM.ESP.BindingFunction;
                                if (!currentFunc.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                paraVM.ESP.MircoStep(currentFunc.LabelDictionary[jumpToTarget]);
                            }
                        }
                        // 跨场景跳转
                        else
                        {
                            LogUtils.LogLine(
                                "There is a jump across scene in parallel function, it will be ignored",
                                "Director", LogLevel.Warning);
                        }
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_call)
                    {
                        var callFunc = nextInstruct.ArgsDict["name"];
                        var signFunc = nextInstruct.ArgsDict["sign"];
                        this.FunctionCalling(callFunc, signFunc, paraVM);
                        break;
                    }
                    // 处理常规动作
                    pdap.Render.Execute(nextInstruct);
                    break;

                // 系统中断
                case GameState.Interrupt:
                    var interruptSa        = paraVM.ESP.IP;
                    var interruptExitPoint = paraVM.ESP.Tag;
                    // 退出中断
                    var pureInt = paraVM.ESP.BindingInterrupt.PureInterrupt;
                    var interruptFuncCalling = paraVM.ESP.BindingInterrupt.InterruptFuncSign;
                    var needExitWait         = paraVM.ESP.BindingInterrupt.ExitWait;
                    Director.RunMana.ExitCall(paraVM);
                    // 处理中断优先动作
                    if (interruptSa != null)
                    {
                        if (interruptSa.Type == SActionType.act_waituser)
                        {
                            LogUtils.LogLine(
                                "There is a user wait in parallel function, which may cause system pause",
                                "Director", LogLevel.Warning);
                            paraVM.Submit("Director", interruptSa.NodeName);
                            break;
                        }
                        else
                        {
                            var iterSa = interruptSa;
                            while (iterSa != null)
                            {
                                pdap.Render.Execute(interruptSa);
                                iterSa = iterSa.Next;
                            }
                        }
                    }
                    // 判断中断是否需要处理后续动作
                    if (pureInt)
                    {
                        break;
                    }
                    // 跳出所有用户等待
                    if (needExitWait || interruptExitPoint != String.Empty)
                    {
                        while (paraVM.Count() > 0 && paraVM.ESP.State == StackMachineState.WaitUser)
                        {
                            Director.RunMana.ExitCall(paraVM);
                        }
                    }
                    // 处理跳转(与中断调用互斥)
                    if (interruptExitPoint != String.Empty)
                    {
                        RunnableYuriri curRunnable;
                        if (paraVM.EBP.BindingFunction == null)
                        {
                            curRunnable = this.resMana.GetScene(paraVM.EBP.BindingSceneName);
                        }
                        else
                        {
                            curRunnable = paraVM.EBP.BindingFunction;
                        }
                        if (!curRunnable.LabelDictionary.ContainsKey(interruptExitPoint))
                        {
                            LogUtils.LogLine(String.Format("Ignored parallel Interrupt jump Instruction (target not exist): {0}",
                                                           interruptExitPoint), "Director", LogLevel.Error);
                            break;
                        }
                        paraVM.EBP.MircoStep(curRunnable.LabelDictionary[interruptExitPoint]);
                    }
                    // 处理中断函数调用
                    else if (interruptFuncCalling != String.Empty)
                    {
                        var ifcItems    = interruptFuncCalling.Split('(');
                        var funPureName = ifcItems[0];
                        var funParas    = "(" + ifcItems[1];
                        this.FunctionCalling(funPureName, funParas, paraVM);
                    }
                    break;

                // 退出(其实就是执行完毕了一轮,应该重新开始)
                case GameState.Exit:
                    if (pdap.IsSemaphore == false)
                    {
                        paraVM.Submit(pdap.BindingSF, new List <object>());
                    }
                    else
                    {
                        switch (pdap.SemaphoreType)
                        {
                        case SemaphoreHandlerType.ScheduleOnce:
                            return;

                        case SemaphoreHandlerType.ScheduleForever:
                            paraVM.Submit(pdap.BindingSF, new List <object>());
                            break;

                        case SemaphoreHandlerType.ScheduleWhenActivated:
                            throw new NotImplementedException();
                        }
                    }
                    break;
                }
                if (resumeFlag)
                {
                    break;
                }
            }
            if (resumeFlag)
            {
                dispatcher.Start();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 处理消息循环
        /// </summary>
        private void UpdateContext(object sender, EventArgs e)
        {
            bool resumeFlag = true;

            this.timer.Stop();
            while (true)
            {
                // 取得调用堆栈顶部状态
                StackMachineState stackState = Director.RunMana.GameState(Director.RunMana.CallStack);
                switch (stackState)
                {
                case StackMachineState.Interpreting:
                case StackMachineState.FunctionCalling:
                    this.curState = GameState.Performing;
                    resumeFlag    = false;
                    break;

                case StackMachineState.WaitUser:
                    this.curState = GameState.WaitForUserInput;
                    resumeFlag    = true;
                    break;

                case StackMachineState.WaitAnimation:
                    this.curState = GameState.WaitAni;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Await:
                    this.curState = GameState.Waiting;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Interrupt:
                    this.curState = GameState.Interrupt;
                    resumeFlag    = false;
                    break;

                case StackMachineState.AutoWait:
                    this.curState = GameState.AutoPlay;
                    resumeFlag    = true;
                    break;

                case StackMachineState.NOP:
                    this.curState = GameState.Exit;
                    resumeFlag    = true;
                    break;
                }
                // 根据调用堆栈顶部更新系统
                switch (this.curState)
                {
                // 等待状态
                case GameState.Waiting:
                    // 计算已经等待的时间
                    if (DateTime.Now - Director.RunMana.CallStack.ESP.TimeStamp >
                        Director.RunMana.CallStack.ESP.Delay)
                    {
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 等待动画
                case GameState.WaitAni:
                    if (SpriteAnimation.IsAnyAnimation == false && SCamera2D.IsAnyAnimation == false &&
                        SCamera3D.IsAnyAnimation == false)
                    {
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 自动播放
                case GameState.AutoPlay:
                    // 等待动画和延时
                    if (DateTime.Now - Director.RunMana.CallStack.ESP.TimeStamp > Director.RunMana.CallStack.ESP.Delay &&
                        SpriteAnimation.IsAnyAnimation == false &&
                        SCamera2D.IsAnyAnimation == false &&
                        SCamera3D.IsAnyAnimation == false &&
                        Director.IsRClicking == false &&
                        Musician.IsVoicePlaying == false &&
                        SemaphoreDispatcher.GetSemaphoreState("System_PreviewShutdown") == false &&
                        ViewPageManager.IsAtMainStage() == true)
                    {
                        this.updateRender.IsShowingDialog = false;
                        this.updateRender.dialogPreStr    = String.Empty;
                        if (this.updateRender.IsContinousDialog == false)
                        {
                            ViewManager.GetInstance().GetMessageLayer(0).Visibility = Visibility.Hidden;
                            this.updateRender.HideMessageTria();
                        }
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 等待用户操作
                case GameState.WaitForUserInput:
                    break;

                // 中断
                case GameState.Interrupt:
                    var interruptSa        = Director.RunMana.CallStack.ESP.IP;
                    var interruptExitPoint = Director.RunMana.CallStack.ESP.Tag;
                    // 退出中断
                    var pureInt = Director.RunMana.CallStack.ESP.BindingInterrupt.PureInterrupt;
                    var interruptFuncCalling = Director.RunMana.CallStack.ESP.BindingInterrupt.InterruptFuncSign;
                    var needExitWait         = Director.RunMana.CallStack.ESP.BindingInterrupt.ExitWait;
                    Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    // 处理中断优先动作
                    if (interruptSa != null)
                    {
                        if (interruptSa.Type == SActionType.act_waituser)
                        {
                            Director.RunMana.UserWait("Director", interruptSa.NodeName);
                        }
                        else
                        {
                            var iterSa = interruptSa;
                            while (iterSa != null)
                            {
                                this.updateRender.Execute(interruptSa);
                                iterSa = iterSa.Next;
                            }
                        }
                    }
                    // 判断中断是否需要处理后续动作
                    if (pureInt)
                    {
                        break;
                    }
                    // 跳出所有用户等待
                    if (needExitWait || interruptExitPoint != String.Empty)
                    {
                        Director.RunMana.ExitUserWait();
                    }
                    // 处理跳转(与中断调用互斥)
                    if (interruptExitPoint != String.Empty)
                    {
                        RunnableYuriri curRunnable;
                        if (Director.RunMana.CallStack.EBP.BindingFunction == null)
                        {
                            curRunnable = this.resMana.GetScene(Director.RunMana.CallStack.EBP.BindingSceneName);
                        }
                        else
                        {
                            curRunnable = Director.RunMana.CallStack.EBP.BindingFunction;
                        }
                        if (!curRunnable.LabelDictionary.ContainsKey(interruptExitPoint))
                        {
                            LogUtils.LogLine(String.Format("Ignored Interrupt jump Instruction (target not exist): {0}",
                                                           interruptExitPoint), "Director", LogLevel.Error);
                            break;
                        }
                        Director.RunMana.CallStack.EBP.MircoStep(curRunnable.LabelDictionary[interruptExitPoint]);
                    }
                    // 处理中断函数调用
                    else if (interruptFuncCalling != String.Empty)
                    {
                        var ifcItems    = interruptFuncCalling.Split('(');
                        var funPureName = ifcItems[0];
                        var funParas    = "(" + ifcItems[1];
                        this.FunctionCalling(funPureName, funParas, Director.RunMana.CallStack);
                    }
                    break;

                // 演绎脚本
                case GameState.Performing:
                    // 取下一动作
                    var nextInstruct = Director.RunMana.MoveNext(Director.RunMana.CallStack);
                    // 如果指令空了就立即迭代本次消息循环
                    if (nextInstruct == null)
                    {
                        this.timer.Start();
                        return;
                    }
                    // 处理影响调用堆栈的动作
                    if (nextInstruct.Type == SActionType.act_wait)
                    {
                        double waitMs = nextInstruct.ArgsDict.ContainsKey("time")
                                ? (double)PolishEvaluator.Evaluate(nextInstruct.ArgsDict["time"], Director.RunMana.CallStack)
                                : 0;
                        Director.RunMana.Delay(nextInstruct.NodeName, DateTime.Now,
                                               TimeSpan.FromMilliseconds(waitMs));
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waitani)
                    {
                        Director.RunMana.AnimateWait(nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waituser)
                    {
                        Director.RunMana.UserWait("Director", nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_jump)
                    {
                        var jumpToScene  = nextInstruct.ArgsDict["filename"];
                        var jumpToTarget = nextInstruct.ArgsDict["target"];
                        // 场景内跳转
                        if (jumpToScene == String.Empty)
                        {
                            if (stackState == StackMachineState.Interpreting)
                            {
                                var currentScene = this.resMana.GetScene(Director.RunMana.CallStack.ESP.BindingSceneName);
                                if (!currentScene.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                Director.RunMana.CallStack.ESP.MircoStep(currentScene.LabelDictionary[jumpToTarget]);
                            }
                            else if (stackState == StackMachineState.FunctionCalling)
                            {
                                var currentFunc = Director.RunMana.CallStack.ESP.BindingFunction;
                                if (!currentFunc.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                Director.RunMana.CallStack.ESP.MircoStep(currentFunc.LabelDictionary[jumpToTarget]);
                            }
                        }
                        // 跨场景跳转
                        else
                        {
                            var jumpScene = this.resMana.GetScene(jumpToScene);
                            if (jumpScene == null)
                            {
                                LogUtils.LogLine(
                                    String.Format("Ignored Jump Instruction (scene not exist): {0}", jumpToScene),
                                    "Director", LogLevel.Error);
                                break;
                            }
                            if (jumpToTarget != String.Empty && !jumpScene.LabelDictionary.ContainsKey(jumpToTarget))
                            {
                                LogUtils.LogLine(
                                    String.Format("Ignored Jump Instruction (target not exist): {0} -> {1}",
                                                  jumpToScene, jumpToTarget),
                                    "Director", LogLevel.Error);
                                break;
                            }
                            Director.RunMana.ExitCall(Director.RunMana.CallStack);
                            Director.RunMana.CallScene(jumpScene,
                                                       jumpToTarget == String.Empty ? jumpScene.Ctor : jumpScene.LabelDictionary[jumpToTarget]);
                        }
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_call)
                    {
                        var callFunc = nextInstruct.ArgsDict["name"];
                        var signFunc = nextInstruct.ArgsDict["sign"];
                        this.FunctionCalling(callFunc, signFunc, Director.RunMana.CallStack);
                        break;
                    }
                    // 处理常规动作
                    this.updateRender.Execute(nextInstruct);
                    break;

                // 退出
                case GameState.Exit:
                    this.updateRender.Shutdown();
                    break;
                }
                // 处理IO
                this.updateRender.UpdateForMouseState();
                // 是否恢复消息循环
                if (resumeFlag)
                {
                    break;
                }
            }
            if (resumeFlag)
            {
                this.timer.Start();
            }
        }