/// <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); } }
/// <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; } } }