/// <summary> /// 恢复消息循环 /// </summary> public static void ResumeUpdateContext() { Director.GetInstance().timer.Start(); Director.IsContextUpdatePaused = false; LogUtils.LogLine("Context Update Dispatcher is resumed", "Director", LogLevel.Important); }
/// <summary> /// 暂停消息循环 /// </summary> public static void PauseUpdateContext() { Director.IsContextUpdatePaused = true; Director.GetInstance().timer.Stop(); LogUtils.LogLine("Context Update Dispatcher is stopped", "Director", LogLevel.Important); }
/// <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(); }
/// <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(); }
/// <summary> /// 从资源文件中获取声音资源并返回句柄 /// </summary> /// <param name="sourceName">资源名称</param> /// <param name="rtype">资源类型</param> /// <returns>一个键值对:该音频的内存托管句柄 - 内存长度</returns> private KeyValuePair <GCHandle?, long> GetMusicGCHandleLengthKVP(string sourceName, ResourceType rtype) { if (sourceName == String.Empty) { return(new KeyValuePair <GCHandle?, long>(null, 0)); } string DevURI = null, PackURI = null; // 处理路径 switch (rtype) { case ResourceType.BGM: DevURI = GlobalConfigContext.DevURI_SO_BGM; PackURI = GlobalConfigContext.PackURI_SO_BGM; break; case ResourceType.BGS: DevURI = GlobalConfigContext.DevURI_SO_BGS; PackURI = GlobalConfigContext.PackURI_SO_BGS; break; case ResourceType.SE: DevURI = GlobalConfigContext.DevURI_SO_SE; PackURI = GlobalConfigContext.PackURI_SO_SE; break; case ResourceType.VOCAL: DevURI = GlobalConfigContext.DevURI_SO_VOCAL; PackURI = GlobalConfigContext.PackURI_SO_VOCAL; break; default: throw new Exception("调用了音乐获取方法,但却不是获取音乐资源"); } // 总是先查看是否有为封包的数据 if (this.resourceTable.ContainsKey(DevURI) && this.resourceTable[DevURI].ContainsKey(sourceName)) { var slot = this.resourceTable[DevURI][sourceName]; var sourceLocation = new KeyValuePair <long, long>(slot.Position, slot.Length); GCHandle ptr = PackageUtils.GetObjectManagedHandle(IOUtils.ParseURItoURL(PackURI + GlobalConfigContext.PackPostfix), sourceName, sourceLocation.Key, sourceLocation.Value); return(new KeyValuePair <GCHandle?, long>(ptr, sourceLocation.Value)); } // 没有封包数据再搜索开发目录 else { string furi = IOUtils.JoinPath(GlobalConfigContext.DevURI_RT_SOUND, DevURI, sourceName); if (File.Exists(IOUtils.ParseURItoURL(furi))) { byte[] bytes = File.ReadAllBytes(IOUtils.ParseURItoURL(furi)); return(new KeyValuePair <GCHandle?, long>(GCHandle.Alloc(bytes, GCHandleType.Pinned), bytes.Length)); } else { MessageBox.Show("[错误] 资源文件不存在:" + sourceName); Director.GetInstance().GetMainRender().Shutdown(); throw new FileNotFoundException(); } } }
/// <summary> /// 从资源文件中获取图片资源并返回精灵对象 /// </summary> /// <param name="sourceName">资源名称</param> /// <param name="rtype">资源类型</param> /// <param name="cutRect">纹理切割矩</param> /// <returns>该资源的精灵</returns> private YuriSprite GetGraphicSprite(string sourceName, ResourceType rtype, Int32Rect?cutRect) { if (sourceName == String.Empty) { return(null); } YuriSprite sprite = new YuriSprite(); string DevURI, PackURI; // 处理路径 switch (rtype) { case ResourceType.Background: DevURI = GlobalConfigContext.DevURI_PA_BACKGROUND; PackURI = GlobalConfigContext.PackURI_PA_BACKGROUND; break; case ResourceType.Stand: DevURI = GlobalConfigContext.DevURI_PA_CHARASTAND; PackURI = GlobalConfigContext.PackURI_PA_CHARASTAND; break; case ResourceType.Pictures: DevURI = GlobalConfigContext.DevURI_PA_PICTURES; PackURI = GlobalConfigContext.PackURI_PA_PICTURES; break; default: return(null); } // 总是先查看是否有为封包的数据 if (this.resourceTable.ContainsKey(DevURI) && this.resourceTable[DevURI].ContainsKey(sourceName)) { // 检查缓冲 var ob = ResourceCachePool.Refer(rtype.ToString() + "->" + sourceName, ResourceCacheType.Eden); if (ob == null) { var sourceSlot = this.resourceTable[DevURI][sourceName]; ob = PackageUtils.GetObjectBytes(sourceSlot.BindingFile, sourceName, sourceSlot.Position, sourceSlot.Length); ResourceCachePool.Register(rtype.ToString() + "->" + sourceName, ob, ResourceCacheType.Eden); } MemoryStream ms = new MemoryStream(ob); sprite.Init(sourceName, rtype, ms, cutRect); } // 没有封包数据再搜索开发目录 else { // 检查缓冲 byte[] ob = ResourceCachePool.Refer(rtype.ToString() + "->" + sourceName, ResourceCacheType.Eden); if (ob == null) { string furi = IOUtils.JoinPath(GlobalConfigContext.DevURI_RT_PICTUREASSETS, DevURI, sourceName); if (File.Exists(IOUtils.ParseURItoURL(furi))) { Uri bg = new Uri(IOUtils.ParseURItoURL(furi), UriKind.RelativeOrAbsolute); ob = IOUtils.GetObjectBytes(bg); ResourceCachePool.Register(rtype.ToString() + "->" + sourceName, ob, ResourceCacheType.Eden); } else { MessageBox.Show("[错误] 资源文件不存在:" + sourceName); Director.GetInstance().GetMainRender().Shutdown(); return(null); } } MemoryStream ms = new MemoryStream(ob); sprite.Init(sourceName, rtype, ms, cutRect); } return(sprite); }