Esempio n. 1
0
        public void Evaluate(StoryInstance instance, StoryMessageHandler handler, BoxedValue iterator, BoxedValueList args)
        {
            var stackInfo = StoryLocalInfo.New();
            var runtime   = StoryRuntime.New();

            //调用实参部分需要在栈建立之前运算,结果需要记录在栈上
            for (int i = 0; i < m_LoadedArgs.Count; ++i)
            {
                stackInfo.Args.Add(m_LoadedArgs[i].Clone());
            }
            foreach (var pair in m_LoadedOptArgs)
            {
                stackInfo.OptArgs.Add(pair.Key, pair.Value.Clone());
            }
            runtime.Arguments          = instance.NewBoxedValueList();
            runtime.Arguments.Capacity = stackInfo.Args.Count;
            for (int i = 0; i < stackInfo.Args.Count; i++)
            {
                stackInfo.Args[i].Evaluate(instance, handler, iterator, args);
                runtime.Arguments.Add(stackInfo.Args[i].Value);
            }
            runtime.Iterator = stackInfo.Args.Count;
            foreach (var pair in stackInfo.OptArgs)
            {
                pair.Value.Evaluate(instance, handler, iterator, args);
            }
            //实参处理完,进入函数体执行,创建新的栈
            PushStack(instance, handler, stackInfo, runtime);
            try {
                for (int i = 0; i < m_ArgNames.Count; ++i)
                {
                    if (i < stackInfo.Args.Count)
                    {
                        instance.SetVariable(m_ArgNames[i], stackInfo.Args[i].Value);
                    }
                    else
                    {
                        instance.SetVariable(m_ArgNames[i], BoxedValue.NullObject);
                    }
                }
                foreach (var pair in stackInfo.OptArgs)
                {
                    instance.SetVariable(pair.Key, pair.Value.Value);
                }
                Prepare(runtime);
                stackInfo.HaveValue = true;
                runtime.Tick(instance, handler, long.MaxValue);
                BoxedValue val;
                instance.TryGetVariable(m_ReturnName, out val);
                stackInfo.Value = val;
            } finally {
                instance.RecycleBoxedValueList(runtime.Arguments);
                PopStack(instance, handler);
            }
        }
Esempio n. 2
0
        protected override bool ExecCommand(StoryInstance instance, StoryMessageHandler handler, long delta, BoxedValue iterator, BoxedValueList args)
        {
            var runtime = handler.PeekRuntime();

            if (runtime.CompositeReentry)
            {
                return(false);
            }
            bool ret       = false;
            var  stackInfo = handler.PeekLocalInfo();

            for (int i = 0; i < m_ArgNames.Count; ++i)
            {
                if (i < stackInfo.Args.Count)
                {
                    instance.SetVariable(m_ArgNames[i], stackInfo.Args[i].Value);
                }
                else
                {
                    instance.SetVariable(m_ArgNames[i], BoxedValue.NullObject);
                }
            }
            foreach (var pair in stackInfo.OptArgs)
            {
                instance.SetVariable(pair.Key, pair.Value.Value);
            }
            Prepare(handler);
            runtime                    = handler.PeekRuntime();
            runtime.Arguments          = instance.NewBoxedValueList();
            runtime.Arguments.Capacity = stackInfo.Args.Count;
            for (int i = 0; i < stackInfo.Args.Count; i++)
            {
                runtime.Arguments.Add(stackInfo.Args[i].Value);
            }
            runtime.Iterator = stackInfo.Args.Count;
            //没有wait之类命令直接执行
            runtime.Tick(instance, handler, delta);
            instance.RecycleBoxedValueList(runtime.Arguments);
            if (runtime.CommandQueue.Count == 0)
            {
                handler.PopRuntime(instance);
            }
            else
            {
                //遇到wait命令,跳出执行,之后直接在StoryMessageHandler里执行栈顶的命令队列(降低开销)
                ret = true;
            }
            return(ret);
        }