Пример #1
0
        public async System.Threading.Tasks.Task <DynValue> ExecuteAsync(params object[] args)
        {
            if (IsCoroutine)
            {
                var co = Coroutine.Coroutine;
                if (co.State == CoroutineState.Dead || !CheckYieldStatus()) //Doesn't run check yield if coroutine is dead
                {
                    return(DynValue.Nil);
                }
                DynValue ret;

                if (co.State == CoroutineState.NotStarted)
                {
                    ret = await co.ResumeAsync(args);
                }
                else
                {
                    ret = await co.ResumeAsync();
                }

                switch (co.State)
                {
                case CoroutineState.Suspended:
                    if (ret.IsNotNil())
                    {
                        try
                        {
                            CurYielder = ret.ToObject <Yielder>();
                        }
                        catch
                        {
                            //TODO: throw error?
                        }
                    }
                    break;

                case CoroutineState.Dead:
                    CurYielder = null;
                    if (AutoResetCoroutine)
                    {
                        //Create new coroutine, assign it to our dynvalue
                        Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
                    }
                    break;

                default:
                    break;
                }
                return(ret);
            }
            else
            {
                //Not coroutine, just call the function
                var ret = await ScriptRef.CallAsync(LuaFunc, args);

                return(ret);
            }
        }
Пример #2
0
 public virtual void ResetCoroutine()
 {
     if (IsCoroutine)
     {
         CurYielder = null;
         //It is expensive to create coroutines, also DynVal.Assign() function is more expensive than just assigning in C#
         if (CoroutineState != CoroutineState.NotStarted)
         {
             Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
         }
     }
 }
Пример #3
0
 /// <summary>
 /// Clone the other scripthook. Also creates a new coroutine with the same settings as the original
 /// </summary>
 /// <param name="other"></param>
 public ScriptFunction(ScriptFunction other)
 {
     this.ScriptRef     = other.ScriptRef;
     LuaFunc            = other.LuaFunc;
     IsCoroutine        = other.IsCoroutine;
     AutoResetCoroutine = other.AutoResetCoroutine;
     Coroutine          = IsCoroutine ? ScriptRef.CreateCoroutine(LuaFunc) : null;
     if (IsCoroutine)
     {
         Coroutine.Coroutine.AutoYieldCounter = other.Coroutine.Coroutine.AutoYieldCounter;
     }
     FuncType = other.FuncType;
 }
Пример #4
0
        /// <summary>
        /// Executes this function with a callback. The callback will be called when the coroutine dies, or every time if it is a normal function
        /// </summary>
        /// <param name="callback"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public DynValue ExecuteWithCallback(Action callback, params object[] args)
        {
            if (IsCoroutine)
            {
                if (Coroutine.Coroutine.State == CoroutineState.Dead || !CheckYieldStatus()) //Doesn't run check yield if coroutine is dead
                {
                    return(null);
                }
                DynValue ret = Coroutine.Coroutine.Resume(args);
                switch (Coroutine.Coroutine.State)
                {
                case CoroutineState.Suspended:

                    if (ret.IsNotNil())
                    {
                        CurYielder = ret.ToObject <Yielder>();
                    }
                    else
                    {
                        CurYielder = null;
                    }
                    break;

                case CoroutineState.Dead:
                    CurYielder = null;
                    callback?.Invoke();
                    if (AutoResetCoroutine)
                    {
                        Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
                    }
                    break;

                default:
                    break;
                }
                return(ret);
            }
            else
            {
                var ret = ScriptRef.Call(LuaFunc, args);
                callback?.Invoke();
                return(ret);
            }
        }
        public OptimizedUnityCoroutine(ScriptRunnerBase runner, string functionBody, params string[] parameters)
        {
            UnityCoroutineState = $"{ID}_UNITY_COROUTINE_STATE";
            this.ScriptRef      = runner.Lua;
            ScriptRef.Globals[UnityCoroutineState] = true;
            string        nxtV = $"{ID}_NextVals";
            StringBuilder sb   = new StringBuilder();

            //1 based lua indices, ugh
            for (int i = 1; i < parameters.Length + 1; i++)
            {
                sb.Append($"{parameters[i - 1]} = {nxtV}[{i}] ");
            }
            string NextParamsStr = sb.ToString();
            string funcString    = $"function({string.Join(",", parameters)}) while (true) do{Environment.NewLine}{functionBody}{Environment.NewLine}{UnityCoroutineState} = false " +
                                   $"local {nxtV} = coroutine.yield() " +
                                   $"{NextParamsStr} " +
                                   $"end end";

            LuaFunc   = ScriptRef.LoadFunction(funcString);
            Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
        }
 public void ForceFullReset()
 {
     Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
     started   = false;
     ScriptRef.Globals[$"{ID}_UNITY_COROUTINE_STATE"] = true;
 }
Пример #7
0
        /// <summary>
        /// Executes this function whether it is a normal function or a coroutine. Dead coroutines do not run and return DynValue.Nil
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public DynValue Execute(params object[] args)
        {
            try
            {
                if (IsCoroutine)
                {
                    var co = Coroutine.Coroutine;
                    if (co.State == CoroutineState.Dead || !CheckYieldStatus()) //Doesn't run check yield if coroutine is dead
                    {
                        return(DynValue.Nil);
                    }
                    DynValue ret = co.Resume(args);
                    //if (co.State == CoroutineState.NotStarted)
                    //{
                    //    ret = co.Resume(args);
                    //}
                    //else
                    //{
                    //    ret = co.Resume();
                    //}

                    switch (co.State)
                    {
                    case CoroutineState.Suspended:
                        if (ret.IsNotNil())
                        {
                            try
                            {
                                CurYielder = ret.ToObject <Yielder>();
                            }
                            catch     //Todo: catch specific exception
                            {
                                //Moonsharp does not have a good way of checking the userdata type
                                //The way to check just throws an error anyways, so this is more efficient
                            }
                        }
                        break;

                    case CoroutineState.Dead:
                        CurYielder = null;
                        if (AutoResetCoroutine)
                        {
                            //Create new coroutine, assign it to our dynvalue
                            Coroutine = ScriptRef.CreateCoroutine(LuaFunc);
                        }
                        break;

                    default:
                        break;
                    }
                    return(ret);
                }
                else
                {
                    //Not coroutine, just call the function
                    var ret = ScriptRef.Call(LuaFunc, args);
                    return(ret);
                }
            }
            catch (Exception ex)
            {
                if (ex is InterpreterException ex2)
                {
                    //For unity
                    throw new Exception(ex2.DecoratedMessage, ex);
                }
                else
                {
                    throw ex;
                }
            }
        }