/// <summary> /// 把系统回滚到上一个状态并演绎 /// </summary> public static void SteadyBackward() { lock (typeof(RollbackManager)) { // 还有得回滚且不在动画时才滚 if (RollbackManager.forwardStack.Count > 0 && Director.RunMana.GameState(Director.RunMana.CallStack) != StackMachineState.WaitAnimation) { // 如果还未回滚过就要将自己先移除 if (RollbackManager.IsRollingBack == false && RollbackManager.forwardStack.Count > 1) { var selfStep = RollbackManager.forwardStack.Last(); RollbackManager.forwardStack.RemoveLast(); RollbackManager.backwardStack.AddLast(selfStep); RollbackManager.IsRollingBack = true; } // 取上一状态 if (RollbackManager.IsRollingBack && RollbackManager.forwardStack.Count > 0) { var lastStep = RollbackManager.forwardStack.Last(); RollbackManager.forwardStack.RemoveLast(); RollbackManager.backwardStack.AddLast(lastStep); // 重演绎 RollbackManager.GotoSteadyState(lastStep); ViewManager.MaskFrameRef.Opacity = 0; NotificationManager.SystemMessageNotify("正在回滚", 800); } } } }
/// <summary> /// 系统向前进一个状态 /// 她只有在对话推进和选择项出现时才被触发 /// </summary> public static void SteadyForward(bool fromWheel, SceneAction saPtr, MusicianDescriptor mdescriptor, BacklogHolder backlogHolder) { lock (typeof(RollbackManager)) { // 回滚后返回,移栈并演绎 if (fromWheel && RollbackManager.IsRollingBack) { // 取上一状态 var recentStep = RollbackManager.backwardStack.Last(); RollbackManager.backwardStack.RemoveLast(); RollbackManager.forwardStack.AddLast(recentStep); // 重演绎 RollbackManager.GotoSteadyState(recentStep); } // 非回滚状态时才重新构造 else if (fromWheel == false) { // 处理回顾 if (saPtr.Type == SActionType.act_dialog) { backlogHolder.AddLog(saPtr.Tag); } // 构造当前状态的拷贝 var vm = Director.RunMana.CallStack.Fork() as StackMachine; vm.SetMachineName(String.Format("Yuri!Forked?{0}?{1}", DateTime.Now.Ticks, rand.Next(0, int.MaxValue))); RollbackableSnapshot ssp = new RollbackableSnapshot() { TimeStamp = DateTime.Now, IsBranchingRefer = Director.GetInstance().GetMainRender().IsBranching, MusicRef = ForkableState.DeepCopyBySerialization(mdescriptor), BacklogRef = ForkableState.DeepCopyBySerialization(backlogHolder), ReactionRef = saPtr, VMRef = vm, globalDao = SymbolTable.GetInstance().GlobalCtxDao.Fork() as GlobalContextDAO, sceneDao = SymbolTable.GetInstance().SceneCtxDao.Fork() as SceneContextDAO, ScreenStateRef = ScreenManager.GetInstance().Fork() as ScreenManager, SemaphoreDict = ForkableState.DeepCopyBySerialization(Director.RunMana.SemaphoreBindings), EnableRClickRef = Director.RunMana.EnableRClick, PerformingChapterRef = Director.RunMana.PerformingChapter }; // 如果栈中容量溢出就剔掉最早进入的那个 if (RollbackManager.forwardStack.Count >= GlobalConfigContext.MaxRollbackStep) { RollbackManager.forwardStack.RemoveFirst(); } // 入栈 RollbackManager.forwardStack.AddLast(ssp); } } }
/// <summary> /// 取下一动作指令并暂存当前执行的动作 /// </summary> /// <param name="vsm">关于哪个调用堆栈做动作</param> /// <returns>动作实例</returns> public SceneAction MoveNext(StackMachine vsm) { SceneAction fetched = this.FetchNextInstruction(vsm); if (fetched != null && vsm.ESP.State == StackMachineState.Interpreting) { this.DashingPureSa = fetched.Clone(true); if (this.DashingPureSa.Type == SActionType.act_dialog || this.DashingPureSa.Type == SActionType.act_branch) { RollbackManager.SteadyForward(false, this.DashingPureSa, this.Musics, this.Backlogs); } } return(fetched); }
/// <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(); }