public void ProcessNumberVariableConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); sc.Assign("a", 5); sc.Assign("b", 12); sc.Assign("na", -5); sc.Assign("nb", -12); var res = etor.Eval("$a $b +", sc); Assert.AreEqual(res, 17); res = etor.Eval("$a $nb +", sc); Assert.AreEqual(res, -7); res = etor.Eval("$b $na -", sc); Assert.AreEqual(res, 17); res = etor.Eval("$na $nb -", sc); Assert.AreEqual(res, 7); res = etor.Eval("2 $na 3 + -", sc); Assert.AreEqual(res, 4); }
/// <summary> /// 左值运算一个变量 /// </summary> /// <param name="varname">变量名</param> /// <param name="valuePolish">右值逆波兰式</param> /// <param name="vsm">关于哪个调用堆栈做动作</param> public void Assignment(string varname, string valuePolish, StackMachine vsm) { // 处理局部变量 if (varname.StartsWith("$")) { // 非函数调用 if (this.GameState(vsm) != StackMachineState.FunctionCalling) { this.Symbols.SceneCtxDao.Assign(vsm.EBP.ScriptName, varname.Replace("$", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm)); } // 函数调用 else { var functionFrame = vsm.ESP.BindingFunction; functionFrame.Symbols[varname.Replace("$", String.Empty)] = PolishEvaluator.Evaluate(valuePolish, vsm); } } // 处理全局变量 else if (varname.StartsWith("&")) { this.Symbols.GlobalCtxDao.GlobalAssign(varname.Replace("&", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm)); } // 处理持久化变量 else if (varname.StartsWith("%")) { PersistContextDAO.Assign(varname.Replace("%", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm)); } }
public void ProcessStringNumberConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); var res = etor.Eval("\"testnumber:\" 233 +", sc); Assert.AreEqual(res, "testnumber:233"); res = etor.Eval("\"testnumber:\" 233 1000 + +", sc); Assert.AreEqual(res, "testnumber:1233"); }
public void ProcessStringConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); var res = etor.Eval("\"he\" \"llo\" +", sc); Assert.AreEqual(res, "hello"); res = etor.Eval("\"hello\" \"~\" \"world\" + +", sc); Assert.AreEqual(res, "hello~world"); }
public void ProcessNumberConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); var res = etor.Eval("1 2 +", sc); Assert.AreEqual(res, 3); res = etor.Eval("5 8 -", sc); Assert.AreEqual(res, -3); res = etor.Eval("2.33 3.33 +", sc); Assert.AreEqual(res, 5.66); res = etor.Eval("2.33 3.33 -", sc); Assert.AreEqual(res, -1); }
public void ProcessStringVariableConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); sc.Assign("str1", "hello"); sc.Assign("str2", "world"); sc.Assign("spacer", " "); var res = etor.Eval("$str1 $str2 +", sc); Assert.AreEqual(res, "helloworld"); res = etor.Eval("$str1 $spacer $str2 + +", sc); Assert.AreEqual(res, "hello world"); res = etor.Eval("\"TEST\" $spacer $str2 + +", sc); Assert.AreEqual(res, "TEST world"); }
public void ProcessStringNumberVariableConstant() { SimpleContext sc = new SimpleContext(""); IEvaluator etor = new PolishEvaluator(); sc.Assign("str1", "hello"); sc.Assign("str2", "world"); sc.Assign("num1", 1000); sc.Assign("num2", 24); var res = etor.Eval("\"testnumber:\" $num1 $num2 + +", sc); Assert.AreEqual(res, "testnumber:1024"); res = etor.Eval("\"testnumber:\" $num1 501 - +", sc); Assert.AreEqual(res, "testnumber:499"); res = etor.Eval("$str1 $num1 $str2 $num2 + + +", sc); Assert.AreEqual(res, "hello1000world24"); }
/// <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(); } }
/// <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(); } }
/// <summary> /// 在指定的调用堆栈上做递归寻指 /// </summary> /// <param name="vsm">关于哪个调用堆栈做动作</param> /// <returns>动作实例</returns> private SceneAction FetchNextInstruction(StackMachine vsm) { // 调用栈已经为空时预备退出 if (vsm.Count() == 0) { return(null); } // 取出当前要执行的指令 if (vsm.ESP.State != StackMachineState.Interpreting && vsm.ESP.State != StackMachineState.FunctionCalling) { return(null); } SceneAction ret = vsm.ESP.IP; // 如果没有下一指令就弹栈 if (ret == null) { this.ExitCall(vsm); // 递归寻指 return(this.FetchNextInstruction(vsm)); } // 如果没有条件子句 if (ret.CondPolish == String.Empty) { // 处理控制流程 switch (ret.Type) { case SActionType.NOP: case SActionType.act_function: case SActionType.act_for: // 优先进入trueRouting if (ret.TrueRouting != null && ret.TrueRouting.Count > 0) { return(vsm.ESP.MircoStep(ret.TrueRouting[0])); } // falseRouting if (ret.FalseRouting != null && ret.FalseRouting.Count > 0) { return(vsm.ESP.MircoStep(ret.FalseRouting[0])); } // next return(vsm.ESP.MacroStep(ret)); case SActionType.act_endfor: // endfor直接跳过 return(vsm.ESP.MacroStep(ret)); } // 移动下一指令指针,为下次处理做准备 return(vsm.ESP.MacroStep(ret)); } // 条件子句不为空时 else { // 计算条件真值 bool condBoolean = PolishEvaluator.EvaluateBoolean(ret.CondPolish, vsm); // 处理控制流程 switch (ret.Type) { // IF语句 case SActionType.act_if: // 条件为真且有真分支 if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0) { // 移动下一指令指针,进入trueRouting ret = vsm.ESP.MircoStep(ret.TrueRouting[0]); } // 条件为假且有假分支 else if (condBoolean == false && ret.FalseRouting != null && ret.FalseRouting.Count > 0) { // 移动下一指令指针,进入falseRouting ret = vsm.ESP.MircoStep(ret.FalseRouting[0]); } // 没有执行的语句时,移动指令指针到next节点 else { // 跳过if语句 ret = vsm.ESP.MacroStep(ret); } // 返回当前要执行的指令实例 return(ret); // FOR语句 case SActionType.act_for: // 如果条件为真就进入真分支 if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0) { // 移动下一指令指针,进入trueRouting ret = vsm.ESP.MircoStep(ret.TrueRouting[0]); } // 如果条件为假直接跳过for语句 else { // 跳过if语句 ret = vsm.ESP.MacroStep(ret); } // 返回当前要执行的指令实例 return(ret); // 除此以外,带了cond的语句,为真才执行 default: if (condBoolean == false) { // 跳过当前语句 ret = vsm.ESP.MacroStep(ret); } // 返回当前要执行的指令实例 return(ret); } } }