Пример #1
0
 /// <summary>
 /// 事件:键盘即将按下按钮
 /// </summary>
 private void window_PreviewKeyDown(object sender, KeyEventArgs e)
 {
     if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt)
     {
         MainWindow.altDown = true;
     }
     else if (e.SystemKey == Key.F4 && MainWindow.altDown)
     {
         this.world.GetMainRender().Shutdown();
     }
     else if (e.SystemKey == Key.Enter && MainWindow.altDown && this.IsKeyAltWindowSizeEnabled)
     {
         if (Director.IsFullScreen)
         {
             Director.IsFullScreen = !Director.IsFullScreen;
             this.WindowScreenTransform();
         }
         else
         {
             Director.IsFullScreen = !Director.IsFullScreen;
             this.FullScreenTransform();
         }
     }
     SemaphoreDispatcher.Activate($"System_Key_{e.Key}");
 }
Пример #2
0
 /// <summary>
 /// 事件:键盘即将松开按钮
 /// </summary>
 private void window_PreviewKeyUp(object sender, KeyEventArgs e)
 {
     if (e.SystemKey == Key.LeftAlt || e.SystemKey == Key.RightAlt)
     {
         MainWindow.altDown = false;
     }
     SemaphoreDispatcher.Deactivate($"System_Key_{e.Key}");
 }
Пример #3
0
        /// <summary>
        /// 初始化运行时环境,并指定脚本的入口
        /// </summary>
        private void InitRuntime()
        {
            var mainScene = this.resMana.GetScene(GlobalConfigContext.Script_Main);

            if (mainScene == null)
            {
                LogUtils.LogLine(String.Format("No Entry Point Scene: {0}, Program will exit.", GlobalConfigContext.Script_Main),
                                 "Director", LogLevel.Error);
                this.updateRender.Shutdown();
            }
            this.resMana.GetAllScene().ForEach(t => Director.RunMana.Symbols.AddSceneSymbolContext(t));
            Director.RunMana.CallScene(mainScene);
            SemaphoreDispatcher.InitSystemSemaphore();
        }
Пример #4
0
        /// <summary>
        /// 立即结束本次调用
        /// </summary>
        /// <param name="svm">要作用的调用堆栈</param>
        public void ExitCall(StackMachine svm)
        {
            // 弹调用堆栈
            var consumed = svm.Consume();

            // 弹出的是主堆栈上的场景
            if (svm == this.CallStack && consumed.State == StackMachineState.Interpreting)
            {
                // 恢复到上一个并行栈帧的状态
                this.BackTraceParallel();
                // 关闭当前的信号量订阅者
                SemaphoreDispatcher.UnregisterSemaphoreService();
            }
        }
Пример #5
0
 /// <summary>
 /// 提供精灵按钮鼠标离开时的处理函数
 /// </summary>
 /// <param name="sender">触发者</param>
 /// <param name="e">鼠标参数</param>
 public void MouseLeaveHandler(object sender, MouseEventArgs e)
 {
     if (this.Enable)
     {
         this.IsMouseOver = this.IsMouseOn = false;
         SemaphoreDispatcher.Deactivate($"System_Button_Over_{this.Id}");
         if (this.DisplayBinding != null && (this.ImageMouseOver != null || this.ImageMouseOn != null))
         {
             BitmapImage myBitmapImage = this.ImageNormal.SpriteBitmapImage;
             //this.ImageNormal.DisplayBinding = this.DisplayBinding;
             this.DisplayBinding.Width  = myBitmapImage.PixelWidth;
             this.DisplayBinding.Height = myBitmapImage.PixelHeight;
             this.DisplayBinding.Source = myBitmapImage;
         }
     }
 }
Пример #6
0
 /// <summary>
 /// 事件:窗体关闭
 /// </summary>
 private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 {
     if (!ViewPageManager.IsAtMainStage())
     {
         SplashPage.LoadingExitFlag = true;
         Director.CollapseWorld();
         return;
     }
     if (SemaphoreDispatcher.CountBinding("System_PreviewShutdown") > 0)
     {
         e.Cancel = true;
         SemaphoreDispatcher.Activate("System_PreviewShutdown");
     }
     else
     {
         Director.CollapseWorld();
     }
 }
Пример #7
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();
            }
        }
Пример #8
0
        /// <summary>
        /// 设置运行时环境管理器,用于读取保存的信息
        /// </summary>
        /// <param name="rm">反序列化后的RM实例</param>
        public static void ResumeFromSaveData(RuntimeManager rm)
        {
            // 停止消息循环
            Director.PauseUpdateContext();
            // 清空回滚器
            RollbackManager.Clear();
            // 清空画面
            ViewManager.GetInstance().RemoveView(ResourceType.Unknown);
            // 检查是否需要回滚当前的并行处理
            Director.RunMana.StopAllParallel();
            // 变更运行时环境
            Director.RunMana = rm;
            Director.RunMana.ParallelHandler = Director.GetInstance().ParallelUpdateContext;
            SymbolTable.ResetSynObject(Director.RunMana.Symbols);
            LogUtils.LogLine("RuntimeManager is replaced", "Director", LogLevel.Important);
            // 缓存指令指针
            var irname = rm.CallStack.ESP.IR;
            var isname = rm.CallStack.ESP.BindingSceneName;

            rm.CallStack.ESP.MircoStep(Director.GetInstance().resMana.GetScene(isname).YuriDict[irname]);
            // 变更屏幕管理器
            ScreenManager.ResetSynObject(Director.RunMana.Screen);
            LogUtils.LogLine("ScreenManager is replaced", "Director", LogLevel.Important);
            // 重绘整个画面
            ViewManager.GetInstance().ReDraw();
            // 重新绑定渲染器的作用堆栈
            UpdateRender render = Director.GetInstance().updateRender;

            render.VsmReference = Director.RunMana.CallStack;
            // 恢复背景音乐
            if (GlobalConfigContext.UseBassEngine)
            {
                MusicianBass.GetInstance().RePerform(Director.RunMana.Musics);
            }
            else
            {
                Musician.GetInstance().RePerform(Director.RunMana.Musics);
            }
            // 清空字符串缓冲
            render.dialogPreStr = String.Empty;
            render.pendingDialogQueue.Clear();
            // 关闭自动播放
            Director.RunMana.IsAutoplaying = false;
            // 弹空全部等待,复现保存最后一个动作
            Director.RunMana.ExitUserWait();
            Interrupt reactionNtr = new Interrupt()
            {
                Type              = InterruptType.LoadReaction,
                Detail            = "Reaction for load data",
                InterruptSA       = Director.RunMana.DashingPureSa,
                InterruptFuncSign = String.Empty,
                ReturnTarget      = null,
                PureInterrupt     = true
            };

            // 提交中断
            Director.RunMana.CallStack.Submit(reactionNtr);
            // 重启并行调度系统
            var sc = ResourceManager.GetInstance().GetScene(Director.RunMana.CallStack.EBP.BindingSceneName);

            Director.RunMana.ParallelExecutorStack = new Stack <List <ParallelExecutor> >();
            Director.RunMana.ConstructParallel(sc);
            Director.RunMana.RestartParallel();
            Director.RunMana.LastScenario = sc.Scenario;
            // 重启信号分发系统
            SemaphoreDispatcher.ReBinding(sc, Director.RunMana.SemaphoreBindings);
            // 重启主调用堆栈上的消息循环
            Director.ResumeUpdateContext();
        }
Пример #9
0
        /// <summary>
        /// 将系统跳转到指定的稳定状态
        /// </summary>
        /// <param name="ssp">要演绎的状态包装</param>
        public static void GotoSteadyState(RollbackableSnapshot ssp)
        {
            // 停止消息循环
            Director.PauseUpdateContext();
            // 结束全部动画
            SpriteAnimation.ClearAnimateWaitingDict();
            // 检查是否需要回滚当前的并行处理和信号绑定
            bool needRepara = false;

            if (ssp.VMRef.ESP.BindingSceneName != Director.RunMana.CallStack.SAVEP.BindingSceneName)
            {
                Director.RunMana.PauseParallel();
                needRepara = true;
            }
            // 退到SSP所描述的状态
            SymbolTable.GetInstance().SetDAO(ssp.sceneDao.Fork() as SceneContextDAO, ssp.globalDao.Fork() as GlobalContextDAO);
            ScreenManager.ResetSynObject(ssp.ScreenStateRef.Fork() as ScreenManager);
            Director.RunMana.ResetCallstackObject(ssp.VMRef.Fork() as StackMachine);
            Director.RunMana.Backlogs          = ForkableState.DeepCopyBySerialization(ssp.BacklogRef);
            Director.RunMana.Musics            = ForkableState.DeepCopyBySerialization(ssp.MusicRef);
            Director.RunMana.DashingPureSa     = ssp.ReactionRef.Clone(true);
            Director.RunMana.SemaphoreBindings = ForkableState.DeepCopyBySerialization(ssp.SemaphoreDict);
            Director.RunMana.EnableRClick      = ssp.EnableRClickRef;
            Director.RunMana.PerformingChapter = ssp.PerformingChapterRef;
            Director.ScrMana = ScreenManager.GetInstance();
            // 刷新主渲染器上的堆栈绑定
            Director.GetInstance().RefreshMainRenderVMReference();
            Director.GetInstance().GetMainRender().IsBranching = ssp.IsBranchingRefer;
            // 重绘整个画面
            ViewManager.GetInstance().ReDraw(true);
            // 恢复音效
            UpdateRender render = Director.GetInstance().GetMainRender();

            if (GlobalConfigContext.UseBassEngine)
            {
                MusicianBass.GetInstance().RePerform(Director.RunMana.Musics);
            }
            else
            {
                Musician.GetInstance().RePerform(Director.RunMana.Musics);
            }
            // 清空字符串缓冲
            render.dialogPreStr = String.Empty;
            render.pendingDialogQueue.Clear();
            // 关闭自动播放
            Director.RunMana.IsAutoplaying = false;
            // 弹空全部等待,复现保存最后一个动作
            Director.RunMana.ExitUserWait();
            Interrupt reactionNtr = new Interrupt()
            {
                Type              = InterruptType.LoadReaction,
                Detail            = "Reaction for rollback",
                InterruptSA       = ssp.ReactionRef,
                InterruptFuncSign = String.Empty,
                ReturnTarget      = null,
                PureInterrupt     = true
            };

            // 提交中断到主调用堆栈
            Director.RunMana.CallStack.Submit(reactionNtr);
            // 重启并行处理和信号系统
            if (needRepara)
            {
                var sc = ResourceManager.GetInstance().GetScene(ssp.VMRef.EBP.BindingSceneName);
                Director.RunMana.ConstructParallelForRollingBack(sc);
                Director.RunMana.BackTraceParallel();
                Director.RunMana.LastSceneName = sc.Scenario;
                SemaphoreDispatcher.ReBinding(sc, Director.RunMana.SemaphoreBindings);
            }
            // 重启消息循环
            Director.ResumeUpdateContext();
        }