123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 |
- #if UNITY_IPHONE
- #define __NOGEN__
- #endif
- namespace LuaInterface
- {
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Reflection;
- using System.Security;
- using System.Runtime.InteropServices;
- using System.Threading;
- using System.Text;
- public class LuaState : IDisposable
- {
- public IntPtr L;
- internal LuaCSFunction tracebackFunction;
- internal ObjectTranslator translator;
- internal LuaCSFunction panicCallback;
- public LuaState()
- {
- // Create State
- L = LuaDLL.luaL_newstate();
- // Create LuaInterface library
- LuaDLL.luaL_openlibs(L);
- LuaDLL.lua_pushstring(L, "LUAINTERFACE LOADED");
- LuaDLL.lua_pushboolean(L, true);
- LuaDLL.lua_settable(L, (int) LuaIndexes.LUA_REGISTRYINDEX);
- LuaDLL.lua_newtable(L);
- LuaDLL.lua_setglobal(L, "luanet");
- LuaDLL.lua_pushvalue(L, (int)LuaIndexes.LUA_GLOBALSINDEX);
- LuaDLL.lua_getglobal(L, "luanet");
- LuaDLL.lua_pushstring(L, "getmetatable");
- LuaDLL.lua_getglobal(L, "getmetatable");
- LuaDLL.lua_settable(L, -3);
- // Set luanet as global for object translator
- LuaDLL.lua_replace(L, (int)LuaIndexes.LUA_GLOBALSINDEX);
- translator = new ObjectTranslator(this,L);
- LuaDLL.lua_replace(L, (int)LuaIndexes.LUA_GLOBALSINDEX);
- GCHandle handle = GCHandle.Alloc(translator, GCHandleType.Pinned);
- IntPtr thisptr = GCHandle.ToIntPtr(handle);
- LuaDLL.lua_pushlightuserdata(L, thisptr);
- LuaDLL.lua_setglobal(L, "_translator");
- }
- public void Close()
- {
- if (L != IntPtr.Zero)
- {
- LuaDLL.lua_close(L);
- }
- }
- /// <summary>
- /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
- /// </summary>
- /// <exception cref="LuaScriptException">Thrown if the script caused an exception</exception>
- public void ThrowExceptionFromError(int oldTop)
- {
- object err = translator.getObject(L, -1);
- LuaDLL.lua_settop(L, oldTop);
- // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved)
- LuaScriptException luaEx = err as LuaScriptException;
- if (luaEx != null) throw luaEx;
- // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it
- if (err == null) err = "Unknown Lua Error";
- throw new LuaScriptException(err.ToString(), "");
- }
- /// <summary>
- /// Convert C# exceptions into Lua errors
- /// </summary>
- /// <returns>num of things on stack</returns>
- /// <param name="e">null for no pending exception</param>
- internal int SetPendingException(Exception e)
- {
- Exception caughtExcept = e;
- if (caughtExcept != null)
- {
- translator.throwError(L, caughtExcept);
- LuaDLL.lua_pushnil(L);
- return 1;
- }
- else
- return 0;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="chunk"></param>
- /// <param name="name"></param>
- /// <returns></returns>
- public LuaFunction LoadString(string chunk, string name, LuaTable env)
- {
- int oldTop = LuaDLL.lua_gettop(L);
- if (LuaDLL.luaL_loadbuffer(L, chunk, Encoding.UTF8.GetByteCount(chunk), name) != 0)
- ThrowExceptionFromError(oldTop);
- if (env != null)
- {
- env.push(L);
- LuaDLL.lua_setfenv(L, -2);
- }
- LuaFunction result = translator.getFunction(L, -1);
- translator.popValues(L, oldTop);
- return result;
- }
- public LuaFunction LoadString(string chunk, string name)
- {
- return LoadString(chunk, name, null);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fileName"></param>
- /// <returns></returns>
- protected LuaFunction LoadFile(string fileName)
- {
- int oldTop = LuaDLL.lua_gettop(L);
- if (LuaDLL.luaL_loadfile(L, fileName) != 0)
- ThrowExceptionFromError(oldTop);
- LuaFunction result = translator.getFunction(L, -1);
- translator.popValues(L, oldTop);
- return result;
- }
- /*
- * Excutes a Lua chunk and returns all the chunk's return
- * values in an array
- */
- public object[] DoString(string chunk)
- {
- return DoString(chunk,"chunk", null);
- }
- /// <summary>
- /// Executes a Lua chnk and returns all the chunk's return values in an array.
- /// </summary>
- /// <param name="chunk">Chunk to execute</param>
- /// <param name="chunkName">Name to associate with the chunk</param>
- /// <returns></returns>
- public object[] DoString(string chunk, string chunkName, LuaTable env)
- {
- int oldTop = LuaDLL.lua_gettop(L);
- if (LuaDLL.luaL_loadbuffer(L, chunk, Encoding.UTF8.GetByteCount(chunk), chunkName) == 0)
- {
- if (env != null)
- {
- env.push(L);
- //LuaDLL.lua_setfenv(L, -1);
- LuaDLL.lua_setfenv(L, -2);
- }
- if (LuaDLL.lua_pcall(L, 0, -1, 0) == 0)
- return translator.popValues(L, oldTop);
- else
- ThrowExceptionFromError(oldTop);
- }
- else
- ThrowExceptionFromError(oldTop);
- return null; // Never reached - keeps compiler happy
- }
- public object[] DoFile(string fileName)
- {
- return DoFile(fileName, null);
- }
- /*
- * Excutes a Lua file and returns all the chunk's return
- * values in an array
- */
- protected object[] DoFile(string fileName, LuaTable env)
- {
- LuaDLL.lua_pushstdcallcfunction(L,tracebackFunction);
- int oldTop = LuaDLL.lua_gettop(L);
- if (LuaDLL.luaL_loadfile(L, fileName) == 0)
- {
- try
- {
- if (LuaDLL.lua_pcall(L, 0, -1, -2) == 0)
- return translator.popValues(L, oldTop);
- else
- ThrowExceptionFromError(oldTop);
- }
- finally {}
- }
- else
- ThrowExceptionFromError(oldTop);
- return null; // Never reached - keeps compiler happy
- }
- /*
- * Indexer for global variables from the LuaInterpreter
- * Supports navigation of tables by using . operator
- */
- public object this[string fullPath]
- {
- get
- {
- object returnValue=null;
- int oldTop=LuaDLL.lua_gettop(L);
- string[] path=fullPath.Split(new char[] { '.' });
- LuaDLL.lua_getglobal(L,path[0]);
- returnValue=translator.getObject(L,-1);
- if(path.Length>1)
- {
- string[] remainingPath=new string[path.Length-1];
- Array.Copy(path,1,remainingPath,0,path.Length-1);
- returnValue=getObject(remainingPath);
- }
- LuaDLL.lua_settop(L,oldTop);
- return returnValue;
- }
- set
- {
- int oldTop=LuaDLL.lua_gettop(L);
- string[] path=fullPath.Split(new char[] { '.' });
- if(path.Length==1)
- {
- translator.push(L,value);
- LuaDLL.lua_setglobal(L,fullPath);
- }
- else
- {
- LuaDLL.lua_getglobal(L,path[0]);
- string[] remainingPath=new string[path.Length-1];
- Array.Copy(path,1,remainingPath,0,path.Length-1);
- setObject(remainingPath,value);
- }
- LuaDLL.lua_settop(L,oldTop);
- // Globals auto-complete
- if (value == null)
- {
- // Remove now obsolete entries
- globals.Remove(fullPath);
- }
- else
- {
- // Add new entries
- if (!globals.Contains(fullPath))
- registerGlobal(fullPath, value.GetType(), 0);
- }
- }
- }
- #region Globals auto-complete
- private readonly List<string> globals = new List<string>();
- private bool globalsSorted;
- /// <summary>
- /// An alphabetically sorted list of all globals (objects, methods, etc.) externally added to this Lua instance
- /// </summary>
- /// <remarks>Members of globals are also listed. The formatting is optimized for text input auto-completion.</remarks>
- public IEnumerable<string> Globals
- {
- get
- {
- // Only sort list when necessary
- if (!globalsSorted)
- {
- globals.Sort();
- globalsSorted = true;
- }
- return globals;
- }
- }
- /// <summary>
- /// Adds an entry to <see cref="globals"/> (recursivley handles 2 levels of members)
- /// </summary>
- /// <param name="path">The index accessor path ot the entry</param>
- /// <param name="type">The type of the entry</param>
- /// <param name="recursionCounter">How deep have we gone with recursion?</param>
- private void registerGlobal(string path, Type type, int recursionCounter)
- {
- // If the type is a global method, list it directly
- if (type == typeof(LuaCSFunction))
- {
- // Format for easy method invocation
- globals.Add(path + "(");
- }
- // If the type is a class or an interface and recursion hasn't been running too long, list the members
- else if ((type.IsClass || type.IsInterface) && type != typeof(string) && recursionCounter < 2)
- {
- #region Methods
- foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance))
- {
- if (
- // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
- (method.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
- (method.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) &&
- // Exclude some generic .NET methods that wouldn't be very usefull in Lua
- method.Name != "GetType" && method.Name != "GetHashCode" && method.Name != "Equals" &&
- method.Name != "ToString" && method.Name != "Clone" && method.Name != "Dispose" &&
- method.Name != "GetEnumerator" && method.Name != "CopyTo" &&
- !method.Name.StartsWith("get_", StringComparison.Ordinal) &&
- !method.Name.StartsWith("set_", StringComparison.Ordinal) &&
- !method.Name.StartsWith("add_", StringComparison.Ordinal) &&
- !method.Name.StartsWith("remove_", StringComparison.Ordinal))
- {
- // Format for easy method invocation
- string command = path + ":" + method.Name + "(";
- if (method.GetParameters().Length == 0) command += ")";
- globals.Add(command);
- }
- }
- #endregion
- #region Fields
- foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance))
- {
- if (
- // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
- (field.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
- (field.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0))
- {
- // Go into recursion for members
- registerGlobal(path + "." + field.Name, field.FieldType, recursionCounter + 1);
- }
- }
- #endregion
- #region Properties
- foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
- {
- if (
- // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
- (property.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
- (property.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0)
- // Exclude some generic .NET properties that wouldn't be very usefull in Lua
- && property.Name != "Item")
- {
- // Go into recursion for members
- registerGlobal(path + "." + property.Name, property.PropertyType, recursionCounter + 1);
- }
- }
- #endregion
- }
- // Otherwise simply add the element to the list
- else globals.Add(path);
- // List will need to be sorted on next access
- globalsSorted = false;
- }
- #endregion
- /*
- * Navigates a table in the top of the stack, returning
- * the value of the specified field
- */
- internal object getObject(string[] remainingPath)
- {
- object returnValue=null;
- for(int i=0;i<remainingPath.Length;i++)
- {
- LuaDLL.lua_pushstring(L,remainingPath[i]);
- LuaDLL.lua_gettable(L,-2);
- returnValue=translator.getObject(L,-1);
- if(returnValue==null) break;
- }
- return returnValue;
- }
- /*
- * Gets a numeric global variable
- */
- public double GetNumber(string fullPath)
- {
- return (double)this[fullPath];
- }
- /*
- * Gets a string global variable
- */
- public string GetString(string fullPath)
- {
- return (string)this[fullPath];
- }
- /*
- * Gets a table global variable
- */
- public LuaTable GetTable(string fullPath)
- {
- return (LuaTable)this[fullPath];
- }
- #if ! __NOGEN__
- /*
- * Gets a table global variable as an object implementing
- * the interfaceType interface
- */
- public object GetTable(Type interfaceType, string fullPath)
- {
- translator.throwError(L,"Tables as interfaces not implemnented");
- return CodeGeneration.Instance.GetClassInstance(interfaceType,GetTable(fullPath));
- }
- #endif
- /*
- * Gets a function global variable
- */
- public LuaFunction GetFunction(string fullPath)
- {
- object obj=this[fullPath];
- return (obj is LuaCSFunction ? new LuaFunction((LuaCSFunction)obj,this) : (LuaFunction)obj);
- }
- /*
- * Gets a function global variable as a delegate of
- * type delegateType
- */
- public Delegate GetFunction(Type delegateType,string fullPath)
- {
- #if __NOGEN__
- translator.throwError(L,"function delegates not implemnented");
- return null;
- #else
- return CodeGeneration.Instance.GetDelegate(delegateType,GetFunction(fullPath));
- #endif
- }
- /*
- * Calls the object as a function with the provided arguments,
- * returning the function's returned values inside an array
- */
- internal object[] callFunction(object function,object[] args)
- {
- return callFunction(function, args, null);
- }
- /*
- * Calls the object as a function with the provided arguments and
- * casting returned values to the types in returnTypes before returning
- * them in an array
- */
- internal object[] callFunction(object function,object[] args,Type[] returnTypes)
- {
- int nArgs=0;
- int oldTop=LuaDLL.lua_gettop(L);
- if(!LuaDLL.lua_checkstack(L,args.Length+6))
- throw new LuaException("Lua stack overflow");
- translator.push(L,function);
- if(args!=null)
- {
- nArgs=args.Length;
- for(int i=0;i<args.Length;i++)
- {
- translator.push(L,args[i]);
- }
- }
- int error = LuaDLL.lua_pcall(L, nArgs, -1, 0);
- if (error != 0)
- ThrowExceptionFromError(oldTop);
- if(returnTypes != null)
- return translator.popValues(L,oldTop,returnTypes);
- else
- return translator.popValues(L, oldTop);
- }
- /*
- * Navigates a table to set the value of one of its fields
- */
- internal void setObject(string[] remainingPath, object val)
- {
- for(int i=0; i<remainingPath.Length-1;i++)
- {
- LuaDLL.lua_pushstring(L,remainingPath[i]);
- LuaDLL.lua_gettable(L,-2);
- }
- LuaDLL.lua_pushstring(L,remainingPath[remainingPath.Length-1]);
- translator.push(L,val);
- LuaDLL.lua_settable(L,-3);
- }
- /*
- * Creates a new table as a global variable or as a field
- * inside an existing table
- */
- public void NewTable(string fullPath)
- {
- string[] path=fullPath.Split(new char[] { '.' });
- int oldTop=LuaDLL.lua_gettop(L);
- if(path.Length==1)
- {
- LuaDLL.lua_newtable(L);
- LuaDLL.lua_setglobal(L,fullPath);
- }
- else
- {
- LuaDLL.lua_getglobal(L,path[0]);
- for(int i=1; i<path.Length-1;i++)
- {
- LuaDLL.lua_pushstring(L,path[i]);
- LuaDLL.lua_gettable(L,-2);
- }
- LuaDLL.lua_pushstring(L,path[path.Length-1]);
- LuaDLL.lua_newtable(L);
- LuaDLL.lua_settable(L,-3);
- }
- LuaDLL.lua_settop(L,oldTop);
- }
-
- public LuaTable NewTable()
- {
- int oldTop=LuaDLL.lua_gettop(L);
-
- LuaDLL.lua_newtable(L);
- LuaTable returnVal = (LuaTable)translator.getObject(L,-1);
-
- LuaDLL.lua_settop(L,oldTop);
- return returnVal;
- }
- public ListDictionary GetTableDict(LuaTable table)
- {
- ListDictionary dict = new ListDictionary();
- int oldTop = LuaDLL.lua_gettop(L);
- translator.push(L, table);
- LuaDLL.lua_pushnil(L);
- while (LuaDLL.lua_next(L, -2) != 0)
- {
- dict[translator.getObject(L, -2)] = translator.getObject(L, -1);
- LuaDLL.lua_settop(L, -2);
- }
- LuaDLL.lua_settop(L, oldTop);
- return dict;
- }
- /*
- * Lets go of a previously allocated reference to a table, function
- * or userdata
- */
- internal void dispose(int reference)
- {
- if (L != IntPtr.Zero) //Fix submitted by Qingrui Li
- LuaDLL.lua_unref(L,reference);
- }
- /*
- * Gets a field of the table corresponding to the provided reference
- * using rawget (do not use metatables)
- */
- internal object rawGetObject(int reference,string field)
- {
- int oldTop=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,reference);
- LuaDLL.lua_pushstring(L,field);
- LuaDLL.lua_rawget(L,-2);
- object obj=translator.getObject(L,-1);
- LuaDLL.lua_settop(L,oldTop);
- return obj;
- }
- /*
- * Gets a field of the table or userdata corresponding to the provided reference
- */
- internal object getObject(int reference,string field)
- {
- int oldTop=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,reference);
- object returnValue=getObject(field.Split(new char[] {'.'}));
- LuaDLL.lua_settop(L,oldTop);
- return returnValue;
- }
- /*
- * Gets a numeric field of the table or userdata corresponding the the provided reference
- */
- internal object getObject(int reference,object field)
- {
- int oldTop=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,reference);
- translator.push(L,field);
- LuaDLL.lua_gettable(L,-2);
- object returnValue=translator.getObject(L,-1);
- LuaDLL.lua_settop(L,oldTop);
- return returnValue;
- }
- /*
- * Sets a field of the table or userdata corresponding the the provided reference
- * to the provided value
- */
- internal void setObject(int reference, string field, object val)
- {
- int oldTop=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,reference);
- setObject(field.Split(new char[] {'.'}),val);
- LuaDLL.lua_settop(L,oldTop);
- }
- /*
- * Sets a numeric field of the table or userdata corresponding the the provided reference
- * to the provided value
- */
- internal void setObject(int reference, object field, object val)
- {
- int oldTop=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,reference);
- translator.push(L,field);
- translator.push(L,val);
- LuaDLL.lua_settable(L,-3);
- LuaDLL.lua_settop(L,oldTop);
- }
- /*
- * Registers an object's method as a Lua function (global or table field)
- * The method may have any signature
- */
- public LuaFunction RegisterFunction(string path, object target, MethodBase function /*MethodInfo function*/) //CP: Fix for struct constructor by Alexander Kappner (link: http://luaforge.net/forum/forum.php?thread_id=2859&forum_id=145)
- {
- // We leave nothing on the stack when we are done
- int oldTop = LuaDLL.lua_gettop(L);
- LuaMethodWrapper wrapper=new LuaMethodWrapper(translator,target,function.DeclaringType,function);
- translator.push(L,new LuaCSFunction(wrapper.call));
- this[path]=translator.getObject(L,-1);
- LuaFunction f = GetFunction(path);
- LuaDLL.lua_settop(L, oldTop);
- return f;
- }
-
- public LuaFunction CreateFunction(object target, MethodBase function /*MethodInfo function*/) //CP: Fix for struct constructor by Alexander Kappner (link: http://luaforge.net/forum/forum.php?thread_id=2859&forum_id=145)
- {
- // We leave nothing on the stack when we are done
- int oldTop = LuaDLL.lua_gettop(L);
- LuaMethodWrapper wrapper=new LuaMethodWrapper(translator,target,function.DeclaringType,function);
- translator.push(L,new LuaCSFunction(wrapper.call));
-
- object obj = translator.getObject(L,-1);
- LuaFunction f = (obj is LuaCSFunction ? new LuaFunction((LuaCSFunction)obj,this) : (LuaFunction)obj);
- LuaDLL.lua_settop(L, oldTop);
- return f;
- }
- /*
- * Compares the two values referenced by ref1 and ref2 for equality
- */
- internal bool compareRef(int ref1, int ref2)
- {
- int top=LuaDLL.lua_gettop(L);
- LuaDLL.lua_getref(L,ref1);
- LuaDLL.lua_getref(L,ref2);
- int equal=LuaDLL.lua_equal(L,-1,-2);
- LuaDLL.lua_settop(L,top);
- return (equal!=0);
- }
- internal void pushCSFunction(LuaCSFunction function)
- {
- translator.pushFunction(L,function);
- }
- #region IDisposable Members
- public void Dispose()
- {
- Dispose(true);
- System.GC.Collect();
- System.GC.WaitForPendingFinalizers();
- }
-
- public virtual void Dispose(bool dispose)
- {
- if( dispose )
- {
- if (translator != null)
- {
- translator.pendingEvents.Dispose();
- translator = null;
- }
- }
- }
- #endregion
- }
- public class LuaThread : LuaState
- {
- // Tracks if thread is running or not
- private bool start = false;
- // Keeps reference of thread in registry to prevent GC
- private int threadRef;
- // Hold on to parent for later
- private LuaState parent;
- // Func running on
- private LuaFunction func;
- public LuaThread( LuaState parentState, LuaFunction threadFunc )
- {
- // Copy from parent
- this.tracebackFunction = parentState.tracebackFunction;
- this.translator = parentState.translator;
- this.translator.interpreter = this;
-
- this.panicCallback = parentState.panicCallback;
- //this.printFunction = parentState.printFunction;
- //this.loadfileFunction = parentState.loadfileFunction;
- //this.loaderFunction = parentState.loaderFunction;
- //this.dofileFunction = parentState.dofileFunction;
-
- // Assign to store
- func = threadFunc;
- parent = parentState;
- // Create Thread
- L = LuaDLL.lua_newthread( parent.L );
- // Store thread in registry
- threadRef = LuaDLL.luaL_ref( parent.L, LuaIndexes.LUA_REGISTRYINDEX );
- }
- #region IDisposable Members
- public override void Dispose(bool dispose)
- {
- if( dispose )
- {
- LuaDLL.luaL_unref( parent.L, LuaIndexes.LUA_REGISTRYINDEX, threadRef );
- }
- }
- #endregion
- public void Start()
- {
- if(IsInactive() && !start)
- {
- start = true;
- }
- }
-
- public int Resume()
- {
- return Resume(null, null);
- }
- public int Resume(object[] args, LuaTable env)
- {
- int result = 0;
- int oldTop = LuaDLL.lua_gettop(L);
- // If thread isn't started, it needs to be restarted
- if( start )
- {
- start = false;
- func.push( L );
-
- if (env != null)
- {
- env.push(L);
- LuaDLL.lua_setfenv(L, -2);
- }
-
- result = resume(args, oldTop);
- }
- // If thread is suspended, resume it
- else if( IsSuspended() )
- {
- result = resume(args, oldTop);
- }
- return result;
- }
- private int resume(object[] args, int oldTop)
- {
- int nArgs=0;
-
- // Push args
- if(args!=null)
- {
- nArgs=args.Length;
- for(int i=0;i<args.Length;i++)
- {
- translator.push(L,args[i]);
- }
- }
-
- // Call func
- int r = 0;
- r = LuaDLL.lua_resume( L, nArgs );
-
- if( r > (int)LuaThreadStatus.LUA_YIELD )
- {
- // Error
- int top = LuaDLL.lua_gettop(L);
- ThrowExceptionFromError(top);
- }
- return r;
- }
- public bool IsStarted()
- {
- return start;
- }
- public bool IsSuspended()
- {
- int status = LuaDLL.lua_status( L );
-
- return (status == (int)LuaThreadStatus.LUA_YIELD);
- }
-
- public bool IsDead()
- {
- int status = LuaDLL.lua_status( L );
-
- return (status > (int)LuaThreadStatus.LUA_YIELD);
- }
-
- public bool IsInactive()
- {
- int status = LuaDLL.lua_status( L );
-
- return (status == 0);
- }
- }
- }
|