public void Evaluate(StoryInstance instance, object iterator, object[] args) { StackElementInfo stackInfo = NewStackElementInfo(); //调用实参部分需要在栈建立之前运算,结果需要记录在栈上 for (int i = 0; i < m_LoadedArgs.Count; ++i) { stackInfo.m_Args.Add(m_LoadedArgs[i].Clone()); } for (int i = 0; i < stackInfo.m_Args.Count; i++) { stackInfo.m_Args[i].Evaluate(instance, iterator, args); } //实参处理完,进入函数体执行,创建新的栈 PushStack(instance, stackInfo); try { for (int i = 0; i < m_ArgNames.Count && i < stackInfo.m_Args.Count; ++i) { instance.SetVariable(m_ArgNames[i], stackInfo.m_Args[i].Value); } Prepare(stackInfo); stackInfo.m_HaveValue = true; for (int i = 0; i < stackInfo.m_Commands.Count; ++i) { //函数调用命令需要忽略其中的wait指令(从而不会出现“挂起-恢复”行为),所以这里传的delta值是一个很大的值,目的是为了让wait直接结束 stackInfo.m_Commands[i].Execute(instance, StoryValueHelper.c_MaxWaitCommandTime, iterator, args); } instance.TryGetVariable(m_ReturnName, out stackInfo.m_Value); } finally { PopStack(instance); } }
private void Prepare(StackElementInfo stackInfo) { if (null != m_InitialCommands && m_FirstStackCommands.Count <= 0) { for (int i = 0; i < m_InitialCommands.Count; ++i) { IStoryCommand cmd = m_InitialCommands[i].Clone(); m_FirstStackCommands.Add(cmd); } } if (m_Stack.Count <= 1) { for (int i = 0; i < m_FirstStackCommands.Count; ++i) { IStoryCommand cmd = m_FirstStackCommands[i]; if (null != cmd.LeadCommand) { stackInfo.m_CommandQueue.Enqueue(cmd.LeadCommand); } stackInfo.m_CommandQueue.Enqueue(cmd); } } else { for (int i = 0; i < m_InitialCommands.Count; ++i) { IStoryCommand cmd = m_InitialCommands[i].Clone(); if (null != cmd.LeadCommand) { stackInfo.m_CommandQueue.Enqueue(cmd.LeadCommand); } stackInfo.m_CommandQueue.Enqueue(cmd); } } }
private void PushStack(StoryInstance instance, StackElementInfo info) { if (m_Stack.Count <= 0) { m_TopStack = instance.StackVariables; } m_Stack.Push(info); instance.StackVariables = info.m_StackVariables; }
protected override void Evaluate(StoryInstance instance, object iterator, object[] args) { if (m_Stack.Count > 0) { StackElementInfo stackInfo = m_Stack.Peek(); for (int i = 0; i < m_ArgNames.Count && i < stackInfo.m_Args.Count; ++i) { instance.SetVariable(m_ArgNames[i], stackInfo.m_Args[i].Value); } } }
private void PopStack(StoryInstance instance) { if (m_Stack.Count > 0) { m_Stack.Pop(); if (m_Stack.Count > 0) { StackElementInfo info = m_Stack.Peek(); instance.StackVariables = info.m_StackVariables; } else { instance.StackVariables = m_TopStack; } } }
public void NewCall(StoryInstance instance, object iterator, object[] args) { //command的执行不像函数,它支持类似协程的机制,允许暂时挂起,稍后继续,这意味着并非每次调用ExecCommand都对应语义上的一次过程调用 //,因此栈的创建不能在ExecCommand里进行(事实上,在ExecCommand里无法区分本次执行是一次新的过程调用还是一次挂起后的继续执行)。 StackElementInfo stackInfo = NewStackElementInfo(); //调用实参部分需要在栈建立之前运算,结果需要记录在栈上 for (int i = 0; i < m_LoadedArgs.Count; ++i) { stackInfo.m_Args.Add(m_LoadedArgs[i].Clone()); } for (int i = 0; i < stackInfo.m_Args.Count; i++) { stackInfo.m_Args[i].Evaluate(instance, iterator, args); } //实参处理完,进入函数体执行,创建新的栈 PushStack(instance, stackInfo); }
private void PopStack(StoryInstance instance) { if (m_Stack.Count > 0) { StackElementInfo old = m_Stack.Peek(); bool haveVal = old.m_HaveValue; object val = old.m_Value; m_Stack.Pop(); if (m_Stack.Count > 0) { StackElementInfo info = m_Stack.Peek(); instance.StackVariables = info.m_StackVariables; } else { instance.StackVariables = m_TopStack; m_HaveValue = haveVal; m_Value = val; } } }
protected override bool ExecCommand(StoryInstance instance, long delta, object iterator, object[] args) { bool ret = false; if (m_Stack.Count > 0) { StackElementInfo stackInfo = m_Stack.Peek(); instance.StackVariables = stackInfo.m_StackVariables; if (stackInfo.m_CommandQueue.Count == 0 && !stackInfo.m_AlreadyExecute) { Evaluate(instance, iterator, args); Prepare(stackInfo); stackInfo.m_AlreadyExecute = true; } if (stackInfo.m_CommandQueue.Count > 0) { while (stackInfo.m_CommandQueue.Count > 0) { IStoryCommand cmd = stackInfo.m_CommandQueue.Peek(); if (cmd.Execute(instance, delta, iterator, args)) { ret = true; break; } else { cmd.Reset(); stackInfo.m_CommandQueue.Dequeue(); } } } if (!ret) { PopStack(instance); stackInfo.m_AlreadyExecute = false; } } return(ret); }
private void Prepare(StackElementInfo stackInfo) { if (null != m_InitialCommands && m_FirstStackCommands.Count <= 0) { for (int i = 0; i < m_InitialCommands.Count; ++i) { IStoryCommand cmd = m_InitialCommands[i].Clone(); m_FirstStackCommands.Add(cmd); } } if (m_Stack.Count <= 1) { for (int i = 0; i < m_FirstStackCommands.Count; ++i) { IStoryCommand cmd = m_FirstStackCommands[i]; if (null != cmd.LeadCommand) stackInfo.m_CommandQueue.Enqueue(cmd.LeadCommand); stackInfo.m_CommandQueue.Enqueue(cmd); } } else { for (int i = 0; i < m_InitialCommands.Count; ++i) { IStoryCommand cmd = m_InitialCommands[i].Clone(); if (null != cmd.LeadCommand) stackInfo.m_CommandQueue.Enqueue(cmd.LeadCommand); stackInfo.m_CommandQueue.Enqueue(cmd); } } }