Commit f2af5ebb authored by Megax's avatar Megax
Browse files

* KopiLua integralva lett a magba nem nem mukodik valamiert normalisan.

parent 153cecd9
......@@ -5,7 +5,7 @@ using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace Mono.LuaInterface
namespace LuaInterface
{
/*
* Structure to store a type and the return types of
......@@ -44,7 +44,7 @@ namespace Mono.LuaInterface
this.translator=translator;
this.delegateType=delegateType;
}
public object extractGenerated(IntPtr luaState,int stackPos)
public object extractGenerated(KopiLua.Lua.lua_State luaState,int stackPos)
{
return CodeGeneration.Instance.GetDelegate(delegateType,translator.getFunction(luaState,stackPos));
}
......@@ -67,7 +67,7 @@ namespace Mono.LuaInterface
this.translator=translator;
this.klass=klass;
}
public object extractGenerated(IntPtr luaState,int stackPos)
public object extractGenerated(KopiLua.Lua.lua_State luaState,int stackPos)
{
return CodeGeneration.Instance.GetClassInstance(klass,translator.getTable(luaState,stackPos));
}
......@@ -105,11 +105,10 @@ namespace Mono.LuaInterface
private CodeGeneration()
{
// Create an assembly name
assemblyName=new AssemblyName( );
assemblyName=new AssemblyName();
assemblyName.Name="LuaInterface_generatedcode";
// Create a new assembly with one module.
newAssembly=Thread.GetDomain().DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.Run);
newAssembly=Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
newModule=newAssembly.DefineDynamicModule("LuaInterface_generatedcode");
}
......@@ -149,7 +148,7 @@ namespace Mono.LuaInterface
// Emits the IL for the method. It loads the arguments
// and calls the handleEvent method of the base class
ILGenerator generator=handleMethod.GetILGenerator( );
ILGenerator generator=handleMethod.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldarg_2);
......@@ -202,7 +201,7 @@ namespace Mono.LuaInterface
returnType,paramTypes);
// Generates the IL for the method
ILGenerator generator=delegateMethod.GetILGenerator( );
ILGenerator generator=delegateMethod.GetILGenerator();
generator.DeclareLocal(typeof(object[])); // original arguments
generator.DeclareLocal(typeof(object[])); // with out-only arguments removed
......@@ -452,7 +451,7 @@ namespace Mono.LuaInterface
if(myType.BaseType.Equals(typeof(object)))
myType.DefineMethodOverride(methodImpl,method);
ILGenerator generator=methodImpl.GetILGenerator( );
ILGenerator generator=methodImpl.GetILGenerator();
generator.DeclareLocal(typeof(object[])); // original arguments
generator.DeclareLocal(typeof(object[])); // with out-only arguments removed
......
namespace Mono.LuaInterface
namespace LuaInterface
{
using System;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Threading;
using LuaWrap;
using System.Threading;
using LuaWrap;
/*
* Main class of LuaInterface
......@@ -23,7 +22,6 @@ namespace Mono.LuaInterface
* */
public class Lua : IDisposable
{
static string init_luanet =
"local metatable = {} \n"+
"local import_type = luanet.import_type \n"+
......@@ -64,153 +62,153 @@ namespace Mono.LuaInterface
"-- Preload the mscorlib assembly \n"+
"luanet.load_assembly(\"mscorlib\") \n";
readonly IntPtr luaState;
readonly KopiLua.Lua.lua_State luaState;
ObjectTranslator translator;
CallbackFunction panicCallback, lockCallback, unlockCallback;
KopiLua.Lua.lua_CFunction panicCallback/*, lockCallback, unlockCallback*/;
/// <summary>
/// Used to ensure multiple .net threads all get serialized by this single lock for access to the lua stack/objects
/// </summary>
object luaLock = new object();
/// <summary>
/// Used to ensure multiple .net threads all get serialized by this single lock for access to the lua stack/objects
/// </summary>
object luaLock = new object();
public Lua()
{
luaState = LuaLib.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone)
//LuaLib.luaopen_base(luaState); // steffenj: luaopen_* no longer used
LuaLib.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here)
LuaLib.lua_pushstring(luaState, "LUAINTERFACE LOADED");
LuaLib.lua_pushboolean(luaState, true);
LuaLib.lua_settable(luaState, (int) PseudoIndex.Registry);
LuaLib.lua_newtable(luaState);
LuaLib.lua_setglobal(luaState, "luanet");
LuaLib.lua_pushvalue(luaState, (int)PseudoIndex.Globals);
LuaLib.lua_getglobal(luaState, "luanet");
LuaLib.lua_pushstring(luaState, "getmetatable");
LuaLib.lua_getglobal(luaState, "getmetatable");
LuaLib.lua_settable(luaState, -3);
LuaLib.lua_replace(luaState, (int)PseudoIndex.Globals);
luaState = KopiLua.Lua.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone)
//KopiLua.Lua.luaopen_base(luaState); // steffenj: luaopen_* no longer used
KopiLua.Lua.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here)
KopiLua.Lua.lua_pushstring(luaState, "LUAINTERFACE LOADED");
KopiLua.Lua.lua_pushboolean(luaState, 1);
KopiLua.Lua.lua_settable(luaState, (int) PseudoIndex.Registry);
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_setglobal(luaState, "luanet");
KopiLua.Lua.lua_pushvalue(luaState, (int)PseudoIndex.Globals);
KopiLua.Lua.lua_getglobal(luaState, "luanet");
KopiLua.Lua.lua_pushstring(luaState, "getmetatable");
KopiLua.Lua.lua_getglobal(luaState, "getmetatable");
KopiLua.Lua.lua_settable(luaState, -3);
KopiLua.Lua.lua_replace(luaState, (int)PseudoIndex.Globals);
translator=new ObjectTranslator(this,luaState);
LuaLib.lua_replace(luaState, (int)PseudoIndex.Globals);
KopiLua.Lua.lua_replace(luaState, (int)PseudoIndex.Globals);
LuaLib.luaL_dostring(luaState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
// We need to keep this in a managed reference so the delegate doesn't get garbage collected
panicCallback = new CallbackFunction(PanicCallback);
LuaLib.lua_atpanic(luaState, panicCallback);
// LuaLib.lua_atlock(luaState, lockCallback = new CallbackFunction(LockCallback));
// LuaLib.lua_atunlock(luaState, unlockCallback = new CallbackFunction(UnlockCallback));
}
/*
* CAUTION: LuaInterface.Lua instances can't share the same lua state!
*/
public Lua(Int64 luaState)
{
IntPtr lState = new IntPtr(luaState);
LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
LuaLib.lua_gettable(lState, (int)PseudoIndex.Registry);
if(LuaLib.lua_toboolean(lState,-1)) {
LuaLib.lua_settop(lState,-2);
throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
} else {
LuaLib.lua_settop(lState,-2);
LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
LuaLib.lua_pushboolean(lState, true);
LuaLib.lua_settable(lState, (int)PseudoIndex.Registry);
this.luaState=lState;
LuaLib.lua_pushvalue(lState, (int)PseudoIndex.Globals);
LuaLib.lua_getglobal(lState, "luanet");
LuaLib.lua_pushstring(lState, "getmetatable");
LuaLib.lua_getglobal(lState, "getmetatable");
LuaLib.lua_settable(lState, -3);
LuaLib.lua_replace(lState, (int)PseudoIndex.Globals);
// We need to keep this in a managed reference so the delegate doesn't get garbage collected
panicCallback = new KopiLua.Lua.lua_CFunction(PanicCallback);
KopiLua.Lua.lua_atpanic(luaState, panicCallback);
// KopiLua.Lua.lua_atlock(luaState, lockCallback = new CallbackFunction(LockCallback));
// KopiLua.Lua.lua_atunlock(luaState, unlockCallback = new CallbackFunction(UnlockCallback));
}
/*
* CAUTION: LuaInterface.Lua instances can't share the same lua state!
*/
public Lua(KopiLua.Lua.lua_State luaState)
{
//IntPtr lState = new IntPtr(luaState);
KopiLua.Lua.lua_pushstring(luaState, "LUAINTERFACE LOADED");
KopiLua.Lua.lua_gettable(luaState, (int)PseudoIndex.Registry);
if(KopiLua.Lua.lua_toboolean(luaState,-1).ToBoolean()) {
KopiLua.Lua.lua_settop(luaState,-2);
throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
} else {
KopiLua.Lua.lua_settop(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState, "LUAINTERFACE LOADED");
KopiLua.Lua.lua_pushboolean(luaState, 1);
KopiLua.Lua.lua_settable(luaState, (int)PseudoIndex.Registry);
this.luaState=luaState;
KopiLua.Lua.lua_pushvalue(luaState, (int)PseudoIndex.Globals);
KopiLua.Lua.lua_getglobal(luaState, "luanet");
KopiLua.Lua.lua_pushstring(luaState, "getmetatable");
KopiLua.Lua.lua_getglobal(luaState, "getmetatable");
KopiLua.Lua.lua_settable(luaState, -3);
KopiLua.Lua.lua_replace(luaState, (int)PseudoIndex.Globals);
translator=new ObjectTranslator(this, this.luaState);
LuaLib.lua_replace(lState, (int)PseudoIndex.Globals);
LuaLib.luaL_dostring(lState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
}
}
KopiLua.Lua.lua_replace(luaState, (int)PseudoIndex.Globals);
LuaLib.luaL_dostring(luaState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
}
}
/// <summary>
/// Called for each lua_lock call
/// </summary>
/// <param name="luaState"></param>
/// Not yet used
int LockCallback(IntPtr luaState)
{
// Monitor.Enter(luaLock);
/// <summary>
/// Called for each lua_lock call
/// </summary>
/// <param name="luaState"></param>
/// Not yet used
int LockCallback(KopiLua.Lua.lua_State luaState)
{
// Monitor.Enter(luaLock);
return 0;
}
return 0;
}
/// <summary>
/// Called for each lua_unlock call
/// </summary>
/// <param name="luaState"></param>
/// Not yet used
int UnlockCallback(IntPtr luaState)
{
// Monitor.Exit(luaLock);
/// <summary>
/// Called for each lua_unlock call
/// </summary>
/// <param name="luaState"></param>
/// Not yet used
int UnlockCallback(KopiLua.Lua.lua_State luaState)
{
// Monitor.Exit(luaLock);
return 0;
}
return 0;
}
static int PanicCallback(IntPtr luaState)
{
// string desc = LuaLib.lua_tostring(luaState, 1);
string reason = String.Format("unprotected error in call to Lua API ({0})", LuaLib.lua_tostring(luaState, -1));
static int PanicCallback(KopiLua.Lua.lua_State luaState)
{
// string desc = KopiLua.Lua.lua_tostring(luaState, 1);
string reason = String.Format("unprotected error in call to Lua API ({0})", KopiLua.Lua.lua_tostring(luaState, -1));
// lua_tostring(L, -1);
// lua_tostring(L, -1);
throw new LuaException(reason);
}
throw new LuaException(reason);
}
/// <summary>
/// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
/// </summary>
void ThrowExceptionFromError(int oldTop)
{
object err = translator.getObject(luaState, -1);
LuaLib.lua_settop(luaState, oldTop);
/// <summary>
/// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
/// </summary>
void ThrowExceptionFromError(int oldTop)
{
object err = translator.getObject(luaState, -1);
KopiLua.Lua.lua_settop(luaState, oldTop);
// If the 'error' on the stack is an actual C# exception, just rethrow it. Otherwise the value must have started
// as a true Lua error and is best interpreted as a string - wrap it in a LuaException and rethrow.
Exception thrown = err as Exception;
// If the 'error' on the stack is an actual C# exception, just rethrow it. Otherwise the value must have started
// as a true Lua error and is best interpreted as a string - wrap it in a LuaException and rethrow.
Exception thrown = err as Exception;
if (thrown == null)
{
if (err == null)
err = "Unknown Lua Error";
if (thrown == null)
{
if (err == null)
err = "Unknown Lua Error";
thrown = new LuaException(err.ToString());
}
thrown = new LuaException(err.ToString());
}
throw thrown;
}
throw thrown;
}
/// <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;
/// <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(luaState, caughtExcept);
LuaLib.lua_pushnil(luaState);
if (caughtExcept != null)
{
translator.throwError(luaState, caughtExcept);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
else
return 0;
}
return 1;
}
else
return 0;
}
/*
......@@ -219,18 +217,18 @@ namespace Mono.LuaInterface
*/
public object[] DoString(string chunk)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
if(LuaLib.luaL_loadbuffer(luaState,chunk,"chunk")== LuaEnum.Ok)
{
if (LuaLib.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
if (KopiLua.Lua.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
else
ThrowExceptionFromError(oldTop);
ThrowExceptionFromError(oldTop);
return null; // Never reached - keeps compiler happy
return null; // Never reached - keeps compiler happy
}
/*
* Excutes a Lua file and returns all the chunk's return
......@@ -238,18 +236,21 @@ namespace Mono.LuaInterface
*/
public object[] DoFile(string fileName)
{
int oldTop=LuaLib.lua_gettop(luaState);
if(LuaLib.luaL_loadfile(luaState,fileName)==0)
int oldTop=KopiLua.Lua.lua_gettop(luaState);
//Console.WriteLine("aaa: {0}",oldTop);
if(KopiLua.Lua.luaL_loadfile(luaState,fileName)==0)
{
if (LuaLib.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
//Console.WriteLine("aaa2: {0}",KopiLua.Lua.lua_pcall(luaState, 0, -1, 0));
//Console.WriteLine("zzzzzzzzzzzzzzzzzz");
if (KopiLua.Lua.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
else
ThrowExceptionFromError(oldTop);
ThrowExceptionFromError(oldTop);
return null; // Never reached - keeps compiler happy
return null; // Never reached - keeps compiler happy
}
......@@ -262,9 +263,9 @@ namespace Mono.LuaInterface
get
{
object returnValue=null;
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
string[] path=fullPath.Split(new char[] { '.' });
LuaLib.lua_getglobal(luaState,path[0]);
KopiLua.Lua.lua_getglobal(luaState,path[0]);
returnValue=translator.getObject(luaState,-1);
if(path.Length>1)
{
......@@ -272,28 +273,28 @@ namespace Mono.LuaInterface
Array.Copy(path,1,remainingPath,0,path.Length-1);
returnValue=getObject(remainingPath);
}
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
//Console.WriteLine("get: {0}", returnValue);
return returnValue;
}
set
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
string[] path=fullPath.Split(new char[] { '.' });
//Console.WriteLine("set: {0}", path.Length);
if(path.Length==1)
{
translator.push(luaState,value);
LuaLib.lua_setglobal(luaState,fullPath);
KopiLua.Lua.lua_setglobal(luaState,fullPath);
}
else
{
LuaLib.lua_getglobal(luaState,path[0]);
KopiLua.Lua.lua_getglobal(luaState,path[0]);
string[] remainingPath=new string[path.Length-1];
Array.Copy(path,1,remainingPath,0,path.Length-1);
setObject(remainingPath,value);
}
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
}
}
/*
......@@ -305,12 +306,12 @@ namespace Mono.LuaInterface
object returnValue=null;
for(int i=0;i<remainingPath.Length;i++)
{
LuaLib.lua_pushstring(luaState,remainingPath[i]);
LuaLib.lua_gettable(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState,remainingPath[i]);
KopiLua.Lua.lua_gettable(luaState,-2);
returnValue=translator.getObject(luaState,-1);
if(returnValue==null) break;
}
return returnValue;
return returnValue;
}
/*
* Gets a numeric global variable
......@@ -346,8 +347,8 @@ namespace Mono.LuaInterface
*/
public LuaFunction GetFunction(string fullPath)
{
object obj=this[fullPath];
return (obj is CallbackFunction ? new LuaFunction((CallbackFunction)obj,this) : (LuaFunction)obj);
object obj=this[fullPath];
return (obj is KopiLua.Lua.lua_CFunction ? new LuaFunction((KopiLua.Lua.lua_CFunction)obj,this) : (LuaFunction)obj);
}
/*
* Gets a function global variable as a delegate of
......@@ -363,7 +364,7 @@ namespace Mono.LuaInterface
*/
internal object[] callFunction(object function,object[] args)
{
return callFunction(function, args, null);
return callFunction(function, args, null);
}
......@@ -375,9 +376,9 @@ namespace Mono.LuaInterface
internal object[] callFunction(object function,object[] args,Type[] returnTypes)
{
int nArgs=0;
int oldTop=LuaLib.lua_gettop(luaState);
if(!LuaLib.lua_checkstack(luaState,args.Length+6))
throw new LuaException("Lua stack overflow");
int oldTop=KopiLua.Lua.lua_gettop(luaState);
if(!KopiLua.Lua.lua_checkstack(luaState,args.Length+6).ToBoolean())
throw new LuaException("Lua stack overflow");
translator.push(luaState,function);
if(args!=null)
{
......@@ -387,14 +388,14 @@ namespace Mono.LuaInterface
translator.push(luaState,args[i]);
}
}
LuaEnum error = LuaLib.lua_pcall(luaState, nArgs, -1, 0);
if (error != LuaEnum.Ok)
ThrowExceptionFromError(oldTop);
LuaEnum error = KopiLua.Lua.lua_pcall(luaState, nArgs, -1, 0).ToLuaEnum();
if (error != LuaEnum.Ok)
ThrowExceptionFromError(oldTop);
if(returnTypes != null)
return translator.popValues(luaState,oldTop,returnTypes);
else
return translator.popValues(luaState, oldTop);
if(returnTypes != null)
return translator.popValues(luaState,oldTop,returnTypes);
else
return translator.popValues(luaState, oldTop);
}
/*
* Navigates a table to set the value of one of its fields
......@@ -403,12 +404,12 @@ namespace Mono.LuaInterface
{
for(int i=0; i<remainingPath.Length-1;i++)
{
LuaLib.lua_pushstring(luaState,remainingPath[i]);
LuaLib.lua_gettable(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState,remainingPath[i]);
KopiLua.Lua.lua_gettable(luaState,-2);
}
LuaLib.lua_pushstring(luaState,remainingPath[remainingPath.Length-1]);
KopiLua.Lua.lua_pushstring(luaState,remainingPath[remainingPath.Length-1]);
translator.push(luaState,val);
LuaLib.lua_settable(luaState,-3);
KopiLua.Lua.lua_settable(luaState,-3);
}
/*
* Creates a new table as a global variable or as a field
......@@ -417,42 +418,42 @@ namespace Mono.LuaInterface
public void NewTable(string fullPath)
{
string[] path=fullPath.Split(new char[] { '.' });
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
if(path.Length==1)
{
LuaLib.lua_newtable(luaState);
LuaLib.lua_setglobal(luaState,fullPath);
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_setglobal(luaState,fullPath);
}
else
{
LuaLib.lua_getglobal(luaState,path[0]);
KopiLua.Lua.lua_getglobal(luaState,path[0]);
for(int i=1; i<path.Length-1;i++)
{
LuaLib.lua_pushstring(luaState,path[i]);
LuaLib.lua_gettable(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState,path[i]);
KopiLua.Lua.lua_gettable(luaState,-2);
}
LuaLib.lua_pushstring(luaState,path[path.Length-1]);
LuaLib.lua_newtable(luaState);
LuaLib.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,path[path.Length-1]);
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_settable(luaState,-3);
}
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
}
public ListDictionary GetTableDict(LuaTable table)
{
ListDictionary dict = new ListDictionary();
int oldTop = LuaLib.lua_gettop(luaState);
int oldTop = KopiLua.Lua.lua_gettop(luaState);
translator.push(luaState, table);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
// nem biztos hogy jóóóó
//while (LuaLib.lua_next(luaState, -2) != 0)
while (!LuaLib.lua_next(luaState, -2))
//while (KopiLua.Lua.lua_next(luaState, -2) != 0)
while (!KopiLua.Lua.lua_next(luaState, -2).ToBoolean())
{
dict[translator.getObject(luaState, -2)] = translator.getObject(luaState, -1);
LuaLib.lua_settop(luaState, -2);
KopiLua.Lua.lua_settop(luaState, -2);
}
LuaLib.lua_settop(luaState, oldTop);
KopiLua.Lua.lua_settop(luaState, oldTop);
return dict;
}
......@@ -471,12 +472,12 @@ namespace Mono.LuaInterface
*/
internal object rawGetObject(int reference,string field)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,reference);
LuaLib.lua_pushstring(luaState,field);
LuaLib.lua_rawget(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState,field);
KopiLua.Lua.lua_rawget(luaState,-2);
object obj=translator.getObject(luaState,-1);
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
return obj;
}
/*
......@@ -484,10 +485,10 @@ namespace Mono.LuaInterface
*/
internal object getObject(int reference,string field)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,reference);
object returnValue=getObject(field.Split(new char[] {'.'}));
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
return returnValue;
}
/*
......@@ -495,12 +496,12 @@ namespace Mono.LuaInterface
*/
internal object getObject(int reference,object field)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,reference);
translator.push(luaState,field);
LuaLib.lua_gettable(luaState,-2);
KopiLua.Lua.lua_gettable(luaState,-2);
object returnValue=translator.getObject(luaState,-1);
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
return returnValue;
}
/*
......@@ -509,10 +510,10 @@ namespace Mono.LuaInterface
*/
internal void setObject(int reference, string field, object val)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,reference);
setObject(field.Split(new char[] {'.'}),val);
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
}
/*
* Sets a numeric field of the table or userdata corresponding the the provided reference
......@@ -520,32 +521,32 @@ namespace Mono.LuaInterface
*/
internal void setObject(int reference, object field, object val)
{
int oldTop=LuaLib.lua_gettop(luaState);
int oldTop=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,reference);
translator.push(luaState,field);
translator.push(luaState,val);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_settop(luaState,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,MethodInfo function)
public LuaFunction RegisterFunction(string path, object target,MethodInfo function)
{
// We leave nothing on the stack when we are done
int oldTop = LuaLib.lua_gettop(luaState);
// We leave nothing on the stack when we are done
int oldTop = KopiLua.Lua.lua_gettop(luaState);
LuaMethodWrapper wrapper=new LuaMethodWrapper(translator,target,function.DeclaringType,function);
translator.push(luaState,new CallbackFunction(wrapper.call));
translator.push(luaState,new KopiLua.Lua.lua_CFunction(wrapper.call));
this[path]=translator.getObject(luaState,-1);
LuaFunction f = GetFunction(path);
LuaFunction f = GetFunction(path);
LuaLib.lua_settop(luaState, oldTop);
KopiLua.Lua.lua_settop(luaState, oldTop);
return f;
return f;
}
......@@ -554,36 +555,36 @@ namespace Mono.LuaInterface
*/
internal bool compareRef(int ref1, int ref2)
{
int top=LuaLib.lua_gettop(luaState);
int top=KopiLua.Lua.lua_gettop(luaState);
LuaLib.lua_getref(luaState,ref1);
LuaLib.lua_getref(luaState,ref2);
int equal=LuaLib.lua_equal(luaState,-1,-2);
LuaLib.lua_settop(luaState,top);
int equal=KopiLua.Lua.lua_equal(luaState,-1,-2);
KopiLua.Lua.lua_settop(luaState,top);
return (equal!=0);
}
internal void pushCSFunction(CallbackFunction function)
{
translator.pushFunction(luaState,function);
}
internal void pushCSFunction(KopiLua.Lua.lua_CFunction function)
{
translator.pushFunction(luaState,function);
}
#region IDisposable Members
#region IDisposable Members
public virtual void Dispose()
{
if (translator != null)
{
translator.pendingEvents.Dispose();
public virtual void Dispose()
{
if (translator != null)
{
translator.pendingEvents.Dispose();
translator = null;
}
translator = null;
}
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
#endregion
}
#endregion
}
/*
* Wrapper class for Lua tables
......@@ -662,16 +663,16 @@ namespace Mono.LuaInterface
{
object obj=interpreter.rawGetObject(reference,field);
if(obj is CallbackFunction)
return new LuaFunction((CallbackFunction)obj,interpreter);
else
return obj;
if(obj is KopiLua.Lua.lua_CFunction)
return new LuaFunction((KopiLua.Lua.lua_CFunction)obj,interpreter);
else
return obj;
}
/*
* Pushes this table into the Lua stack
*/
internal void push(IntPtr luaState)
internal void push(KopiLua.Lua.lua_State luaState)
{
LuaLib.lua_getref(luaState,reference);
}
......@@ -696,27 +697,27 @@ namespace Mono.LuaInterface
public class LuaFunction
{
private Lua interpreter;
internal CallbackFunction function;
internal KopiLua.Lua.lua_CFunction function;
internal int reference;
public LuaFunction(int reference, Lua interpreter)
{
this.reference=reference;
this.function=null;
this.function=null;
this.interpreter=interpreter;
}
public LuaFunction(CallbackFunction function, Lua interpreter)
public LuaFunction(KopiLua.Lua.lua_CFunction function, Lua interpreter)
{
this.reference=0;
this.function=function;
this.function=function;
this.interpreter=interpreter;
}
~LuaFunction()
{
if(reference!=0)
interpreter.dispose(reference);
if(reference!=0)
interpreter.dispose(reference);
}
/*
* Calls the function casting return values to the types
......@@ -737,12 +738,12 @@ namespace Mono.LuaInterface
/*
* Pushes the function into the Lua stack
*/
internal void push(IntPtr luaState)
internal void push(KopiLua.Lua.lua_State luaState)
{
if(reference!=0)
LuaLib.lua_getref(luaState,reference);
else
interpreter.pushCSFunction(function);
if(reference!=0)
LuaLib.lua_getref(luaState,reference);
else
interpreter.pushCSFunction(function);
}
public override string ToString()
{
......@@ -753,19 +754,19 @@ namespace Mono.LuaInterface
if(o is LuaFunction)
{
LuaFunction l=(LuaFunction)o;
if(this.reference!=0 && l.reference!=0)
return interpreter.compareRef(l.reference,this.reference);
else
return this.function==l.function;
if(this.reference!=0 && l.reference!=0)
return interpreter.compareRef(l.reference,this.reference);
else
return this.function==l.function;
}
else return false;
}
public override int GetHashCode()
{
if(reference!=0)
return reference;
else
return function.GetHashCode();
if(reference!=0)
return reference;
else
return function.GetHashCode();
}
}
......@@ -821,7 +822,7 @@ namespace Mono.LuaInterface
/*
* Pushes the userdata into the Lua stack
*/
internal void push(IntPtr luaState)
internal void push(KopiLua.Lua.lua_State luaState)
{
LuaLib.lua_getref(luaState,reference);
}
......@@ -843,5 +844,4 @@ namespace Mono.LuaInterface
return reference;
}
}
}
\ No newline at end of file
......@@ -2,16 +2,15 @@ using System;
using System.Collections.Generic;
using System.Text;
namespace Mono.LuaInterface
namespace LuaInterface
{
/// <summary>
/// Add a specific type for Lua exceptions (kevinh)
/// </summary>
public class LuaException : ApplicationException
{
public LuaException(string reason)
: base(reason)
{
}
}
/// <summary>
/// Add a specific type for Lua exceptions (kevinh)
/// </summary>
public class LuaException : ApplicationException
{
public LuaException(string reason) : base(reason)
{
}
}
}
......@@ -9,9 +9,8 @@
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LuaInterface</RootNamespace>
<AssemblyName>Mono.LuaInterface</AssemblyName>
<AssemblyName>LuaInterface</AssemblyName>
<OldToolsVersion>2.0</OldToolsVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
......@@ -62,4 +61,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KopiLua\KopiLua.csproj">
<Project>{E8DDBC21-EF74-4ABA-9C49-BFC702BE25D8}</Project>
<Name>KopiLua</Name>
</ProjectReference>
</ItemGroup>
</Project>
......@@ -26,6 +26,7 @@
using System;
using System.Runtime.InteropServices;
using KopiLua;
namespace LuaWrap
{
......@@ -123,7 +124,7 @@ namespace LuaWrap
CountB = 4,
/// <summary>
/// Performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of data. The function returns 1 if the step finished a garbage-collection cycle.
/// Performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. ifyou want to control the step size you must experimentally tune the value of data. The function returns 1 ifthe step finished a garbage-collection cycle.
/// </summary>
Step = 5,
......@@ -140,925 +141,47 @@ namespace LuaWrap
public enum PseudoIndex : int
{
Registry = -10000,
Environment = -10001,
Globals = -10002
Registry = (-10000),
Environment = (-10001),
Globals = (-10002)
}
/// <summary>
/// A delegate for C# function callbacks passed to Lua.
/// </summary>
public delegate int CallbackFunction( IntPtr state );
public static class LuaLib
{
private const string Lib = "liblua5.1.so";
private static int tag = 0;
#region Core Library
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// If an error happens outside any protected environment, Lua calls a panic function and then calls exit(EXIT_FAILURE), thus exiting the host application. Your panic function can avoid this exit by never returning (e.g., doing a long jump). The panic function can access the error message at the top of the stack.
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="cb">
/// A new panic function. <see cref="CallbackFunction"/>
/// </param>
public static extern void lua_atpanic( IntPtr state, CallbackFunction cb );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// To call a function you must use the following protocol: first, the function to be called is pushed onto the stack; then, the arguments to the function are pushed in direct order; that is, the first argument is pushed first. Finally you call lua_call.
/// </summary>
/// <param name="state">
/// A Lua State <see cref="IntPtr"/>
/// </param>
/// <param name="nargs">
/// Number of arguments to pass to the function. A <see cref="System.Int32"/>
/// </param>
/// <param name="nresults">
/// Number of results expected, or Globals.MultiRet for all results. A <see cref="System.Int32"/>
/// </param>
public static extern void lua_call( IntPtr state, int nargs, int nresults );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Ensures that there are at least extra free stack slots in the stack. It returns false if it cannot grow the stack to that size. This function never shrinks the stack; if the stack is already larger than the new size, it is left unchanged.
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="extra">
/// Extra slots to request. A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool lua_checkstack( IntPtr state, int extra );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Destroys all objects in the given Lua state (calling the corresponding garbage-collection metamethods, if any) and frees all dynamic memory used by this state.
/// </summary>
/// <param name="state">
/// A Lua State to be destroyed. <see cref="IntPtr"/>
/// </param>
public static extern void lua_close( IntPtr state );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Concatenates the n values at the top of the stack, pops them, and leaves the result at the top. If n is 1, the result is the single value on the stack (that is, the function does nothing); if n is 0, the result is the empty string. Concatenation is performed following the usual semantics of Lua.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="n">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_concat( IntPtr state, int n );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Creates a new empty table and pushes it onto the stack. The new table has space pre-allocated for narr array elements and nrec non-array elements. This pre-allocation is useful when you know exactly how many elements the table will have. Otherwise you can use the function lua_newtable.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="narr">
/// Number of pre-allocated array elements. A <see cref="System.Int32"/>
/// </param>
/// <param name="nrec">
/// Number of pre-allocated non-array elements. A <see cref="System.Int32"/>
/// </param>
public static extern void lua_createtable( IntPtr state, int narr, int nrec );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns 1 if the two values in acceptable indices index1 and index2 are equal, following the semantics of the Lua == operator (that is, may call metamethods). Otherwise returns 0. Also returns 0 if any of the indices is non valid.
/// </summary>
/// <param name="state">
/// A Lua State <see cref="IntPtr"/>
/// </param>
/// <param name="index1">
/// First index to compare. A <see cref="System.Int32"/>
/// </param>
/// <param name="index2">
/// Second index to compare. A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A result code integer <see cref="System.Int32"/>
/// </returns>
public static extern int lua_equal( IntPtr state, int index1, int index2 );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Generates a Lua error. The error message (which can actually be a Lua value of any type) must be on the stack top. This function does a long jump, and therefore never returns. (see luaL_error).
/// </summary>
/// <param name="state">
/// A Lua State<see cref="IntPtr"/>
/// </param>
public static extern void lua_error( IntPtr state );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Controls the garbage collector.
/// This function performs several tasks, according to the value of the parameter what:
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="what">
/// Collector option. <see cref="GCOption"/>
/// </param>
/// <param name="data">
/// Value to change. A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int lua_gc( IntPtr state, GCOption what, int data );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the environment table of the value at the given index.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_getfenv( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the value t[k], where t is the value at the given valid index. As in Lua, this function may trigger a metamethod for the "index" event
/// </summary>
/// <param name="state">
/// A Lua State <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// The stack index for the table to query. A <see cref="System.Int32"/>
/// </param>
/// <param name="key">
/// The key to aquire. A <see cref="System.String"/>
/// </param>
public static extern void lua_getfield( IntPtr state, int index, string key );
/// <summary>
/// Pushes onto the stack the value of the global name.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="name">
/// A <see cref="System.String"/>
/// </param>
public static void lua_getglobal( IntPtr state, string name )
{
lua_getfield( state, (int)PseudoIndex.Globals, name );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the metatable of the value at the given acceptable index. If the index is not valid, or if the value does not have a metatable, the function returns 0 and pushes nothing on the stack.
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A valid stack index. <see cref="System.Int32"/>
/// </param>
public static extern int lua_getmetatable( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the value t[k], where t is the value at the given valid index and k is the value at the top of the stack.
/// This function pops the key from the stack (putting the resulting value in its place).
/// As in Lua, this function may trigger a metamethod for the "index" event
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A valid stack index. <see cref="System.Int32"/>
/// </param>
public static extern void lua_gettable( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns the index of the top element in the stack. Because indices start at 1, this result is equal to the number of elements in the stack (and so 0 means an empty stack).
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int lua_gettop( IntPtr state );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Moves the top element into the given valid index, shifting up the elements above this index to open space. Cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.
/// </summary>
/// <param name="state">
/// A Lua State. <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A valid stack index. <see cref="System.Int32"/>
/// </param>
public static extern void lua_insert( IntPtr state, int index );
public static bool lua_isboolean( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Boolean;
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
public static extern bool lua_iscfunction( IntPtr state, int index );
public static bool lua_isfunction( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Function;
}
public static bool lua_islightuserdata( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.LightUserdata;
}
public static bool lua_isnil( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Nil;
}
public static bool lua_isnone( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.None;
}
public static bool lua_isnoneornil( IntPtr state, int index )
{
LuaType t = lua_type( state, index );
return t == LuaType.None || t == LuaType.Nil;
}
public static bool lua_isnumber( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Number;
}
public static bool lua_isstring( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.String;
}
public static bool lua_istable( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Table;
}
public static bool lua_isthread( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.Thread;
}
public static bool lua_isuserdata( IntPtr state, int index )
{
return lua_type( state, index ) == LuaType.UserData;
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns true if the value at acceptable index index1 is smaller than the value at acceptable index index2, following the semantics of the Lua < operator (that is, may call metamethods). Otherwise returns false. Also returns false if any of the indices is non valid.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index1">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="index2">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool lua_lessthan( IntPtr state, int index1, int index2 );
/// <summary>
/// Creates a new empty table and pushes it onto the stack. It is equivalent to lua_createtable(L, 0, 0).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
public static void lua_newtable( IntPtr state )
{
lua_createtable( state, 0, 0 );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// This function allocates a new block of memory with the given size, pushes onto the stack a new full userdata with the block address, and returns this address.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="size">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="IntPtr"/>
/// </returns>
public static extern IntPtr lua_newuserdata( IntPtr state, int size );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pops a key from the stack, and pushes a key-value pair from the table at the given index (the "next" pair after the given key). If there are no more elements in the table, then lua_next returns false (and pushes nothing).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern bool lua_next( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns the "length" of the value at the given acceptable index: for strings, this is the string length; for tables, this is the result of the length operator ('#'); for userdata, this is the size of the block of memory allocated for the userdata; for other values, it is 0.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int lua_objlen( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Calls a function in protected mode.
/// Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. However, if there is any error, lua_pcall catches it, pushes a single value on the stack (the error message), and returns an error code. Like lua_call, lua_pcall always removes the function and its arguments from the stack.
/// If errfunc is 0, then the error message returned on the stack is exactly the original error message. Otherwise, errfunc is the stack index of an error handler function. (In the current implementation, this index cannot be a pseudo-index.) In case of runtime errors, this function will be called with the error message and its return value will be the message returned on the stack by lua_pcall.
/// Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="nargs">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="nresults">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="errfunc">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern LuaEnum lua_pcall( IntPtr state, int nargs, int nresults, int errfunc );
/// <summary>
/// Pops n elements from the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="n">
/// A <see cref="System.Int32"/>
/// </param>
public static void lua_pop( IntPtr state, int n )
{
lua_settop( state, -n - 1 );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a boolean value with value b onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern void lua_pushboolean( IntPtr state, bool b );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a new C closure onto the stack.
/// When a C function is created, it is possible to associate some values with it, thus creating a C closure; these values are then accessible to the function whenever it is called. To associate values with a C function, first these values should be pushed onto the stack (when there are multiple values, the first value is pushed first). Then lua_pushcclosure is called to create and push the C function onto the stack, with the argument n telling how many values should be associated with the function. lua_pushcclosure also pops these values from the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="fn">
/// A <see cref="CallbackFunction"/>
/// </param>
/// <param name="n">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_pushcclosure( IntPtr state, CallbackFunction fn, int n );
/// <summary>
/// Pushes a C function onto the stack. This function receives a pointer to a C function and pushes onto the stack a Lua value of type function that, when called, invokes the corresponding C function.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="fn">
/// A <see cref="CallbackFunction"/>
/// </param>
public static void lua_pushcfunction( IntPtr state, CallbackFunction fn )
{
lua_pushcclosure( state, fn, 0 );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a number with value n onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern void lua_pushinteger( IntPtr state, int i );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a light userdata onto the stack.
/// Userdata represent C values in Lua. A light userdata represents a pointer. It is a value (like a number): you do not create it, it has no individual metatable, and it is not collected (as it was never created). A light userdata is equal to "any" light userdata with the same C address.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="p">
/// A <see cref="IntPtr"/>
/// </param>
public static extern void lua_pushlightuserdata( IntPtr state, IntPtr p );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes the string s with size len onto the stack. Lua makes (or reuses) an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns. The string can contain embedded zeros.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="s">
/// A <see cref="System.String"/>
/// </param>
/// <param name="len">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_pushlstring( IntPtr state, string s, int len );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes nil onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
public static extern void lua_pushnil( IntPtr state );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Push a lua number onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="number">
/// A <see cref="System.Double"/>
/// </param>
public static extern void lua_pushnumber( IntPtr state, double number );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a string onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="s">
/// A <see cref="System.String"/>
/// </param>
public static extern void lua_pushstring( IntPtr state, string s );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes a copy of the object at index onto the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern void lua_pushvalue( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns true if the two values in acceptable indices index1 and index2 are primitively equal (that is, without calling metamethods). Otherwise returns false. Also returns false if any of the indices are non valid.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index1">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="index2">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool lua_rawequal( IntPtr state, int index1, int index2 );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Similar to lua_gettable, but does a raw access (i.e., without metamethods).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_rawget( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the value t[n], where t is the value at the given valid index. The access is raw; that is, it does not invoke metamethods.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="n">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_rawgeti( IntPtr state, int index, int n );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Similar to lua_settable, but does a raw assignment (i.e., without metamethods).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_rawset( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Does the equivalent of t[n] = v, where t is the value at the given valid index and v is the value at the top of the stack.
/// This function pops the value from the stack. The assignment is raw; that is, it does not invoke metamethods.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern void lua_rawseti( IntPtr state, int index, int n );
/// <summary>
/// Registers a C function as the global name.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="name">
/// A <see cref="System.String"/>
/// </param>
/// <param name="fn">
/// A <see cref="CallbackFunction"/>
/// </param>
public static void lua_register( IntPtr state, string name, CallbackFunction fn )
{
lua_pushcfunction( state, fn );
lua_setglobal( state, name );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Removes the element at the given valid index, shifting down the elements above this index to fill the gap. Cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_remove( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Moves the top element into the given position (and pops it), without shifting any element (therefore replacing the value at the given position).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_replace( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pops a table from the stack and sets it as the new environment for the value at the given index. If the value at the given index is neither a function nor a thread nor a userdata, lua_setfenv returns false. Otherwise it returns true.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern bool lua_setfenv( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Does the equivalent to t[k] = v, where t is the value at the given valid index and v is the value at the top of the stack.
/// This function pops the value from the stack. As in Lua, this function may trigger a metamethod for the "newindex" event
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="name">
/// A <see cref="System.String"/>
/// </param>
public static extern void lua_setfield( IntPtr state, int index, string name );
/// <summary>
/// Pops a value from the stack and sets it as the new value of global name.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="name">
/// A <see cref="System.String"/>
/// </param>
public static void lua_setglobal( IntPtr state, string name )
{
lua_setfield( state, (int)PseudoIndex.Globals, name );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pops a table from the stack and sets it as the new metatable for the value at the given acceptable index.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern void lua_setmetatable( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Does the equivalent to t[k] = v, where t is the value at the given valid index, v is the value at the top of the stack, and k is the value just below the top.
/// This function pops both the key and the value from the stack. As in Lua, this function may trigger a metamethod for the "newindex" event.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_settable( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Accepts any acceptable index, or 0, and sets the stack top to this index. If the new top is larger than the old one, then the new elements are filled with nil. If index is 0, then all stack elements are removed.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void lua_settop( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts the Lua value at the given acceptable index to a boolean value. Like all tests in Lua, lua_toboolean returns true for any Lua value different from false and nil; otherwise it returns false. It also returns false when called with a non-valid index. (If you want to accept only actual boolean values, use lua_isboolean to test the value's type.)
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool lua_toboolean( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts a value at the given acceptable index to a C function. That value must be a C function; otherwise, returns NULL.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="CallbackFunction"/>
/// </returns>
public static extern CallbackFunction lua_tocfunction( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts the Lua value at the given acceptable index to the signed integral type lua_Integer. The Lua value must be a number or a string convertible to a number (see §2.2.1); otherwise, lua_tointeger returns 0.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int lua_tointeger( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts the Lua value at the given acceptable index to a C string. If len is not NULL, it also sets *len with the string length. The Lua value must be a string or a number; otherwise, the function returns NULL. If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.)
/// lua_tolstring returns a fully aligned pointer to a string inside the Lua state. This string always has a zero ('\0') after its last character (as in C), but can contain other zeros in its body. Because Lua has garbage collection, there is no guarantee that the pointer returned by lua_tolstring will be valid after the corresponding value is removed from the stack.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern IntPtr lua_tolstring( IntPtr state, int index, out int length );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts the Lua value at the given acceptable index to a number. The Lua value must be a number or a string convertible to a number, otherwise returns 0.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Double"/>
/// </returns>
public static extern double lua_tonumber( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Converts the value at the given acceptable index to a generic pointer. The value can be a userdata, a table, a thread, or a function; otherwise, lua_topointer returns NULL. Different objects will give different pointers. There is no way to convert the pointer back to its original value.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="IntPtr"/>
/// </returns>
public static extern IntPtr lua_topointer( IntPtr state, int index );
/// <summary>
/// Equivalent to lua_tolstring with len equal to NULL.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.String"/>
/// </returns>
public static string lua_tostring( IntPtr state, int index )
public static class LuaLib
{
private static int tag = 0;
public static LuaType ToLuaType(this int type)
{
int length;
IntPtr str = lua_tolstring( state, index, out length );
if( str != IntPtr.Zero )
return Marshal.PtrToStringAnsi( str, length );
return null;
return (LuaType)type;
}
public static LuaEnum ToLuaEnum(this int lenum)
{
return (LuaEnum)lenum;
}
public static bool ToBoolean(this int number)
{
return number == 1;
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// If the value at the given acceptable index is a full userdata, returns its block address. If the value is a light userdata, returns its pointer. Otherwise, returns NULL.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="IntPtr"/>
/// </returns>
public static extern IntPtr lua_touserdata( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns the type of the value in the given acceptable index, or NONE for a non-valid index (that is, an index to an "empty" stack position).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern LuaType lua_type( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
#region Core Library
/// <summary>
/// Returns the name of the type encoded by the value tp.
/// Pushes a C function onto the stack. This function receives a pointer to a C function and pushes onto the stack a Lua value of type function that, when called, invokes the corresponding C function.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="tp">
/// A <see cref="LuaType"/>
/// <param name="fn">
/// A <see cref="CallbackFunction"/>
/// </param>
/// <returns>
/// A <see cref="System.String"/>
/// </returns>
public static extern string lua_typename( IntPtr state, LuaType tp );
public static void lua_pushcfunction(Lua.lua_State state, Lua.lua_CFunction fn)
{
Lua.lua_pushcclosure(state, fn, 0);
}
#endregion
#region Auxiliary Library
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// If the object at index obj has a metatable and this metatable has a field e, this function calls this field and passes the object as its only argument. In this case this function returns 1 and pushes onto the stack the value returned by the call. If there is no metatable or no metamethod, this function returns 0 (without pushing any value on the stack).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="key">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int luaL_callmeta( IntPtr state, int index, string key );
/// <summary>
/// Loads and runs the given file.
/// </summary>
......@@ -1071,9 +194,9 @@ namespace LuaWrap
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static bool luaL_dofile( IntPtr state, string filename )
public static bool luaL_dofile(Lua.lua_State state, string filename)
{
return ( luaL_loadfile( state, filename ) == LuaEnum.Ok ) && ( lua_pcall( state, 0, (int)LuaEnum.MultiRet, 0 ) == LuaEnum.Ok );
return (Lua.luaL_loadfile(state, filename).ToLuaEnum() == LuaEnum.Ok) && (Lua.lua_pcall(state, 0, (int)LuaEnum.MultiRet, 0).ToLuaEnum() == LuaEnum.Ok);
}
/// <summary>
......@@ -1088,175 +211,17 @@ namespace LuaWrap
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static bool luaL_dostring( IntPtr state, string chunk )
{
return ( luaL_loadstring( state, chunk ) == LuaEnum.Ok ) && ( lua_pcall( state, 0, (int)LuaEnum.MultiRet, 0 ) == LuaEnum.Ok );
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Raises an error. The error message format is given by fmt plus any extra arguments, following the same rules of lua_pushfstring. It also adds at the beginning of the message the file name and the line number where the error occurred, if this information is available.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="format">
/// A <see cref="System.String"/>
/// </param>
/// <param name="__arglist">
/// A <see cref="__arglist"/>
/// </param>
public static extern void luaL_error( IntPtr state, string format, IntPtr zero);
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the field key from the metatable of the object at the given index. If the object does not have a metatable, or if the metatable does not have this field, returns false and pushes nothing.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="key">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool luaL_getmetafield( IntPtr state, int index, string key );
//[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack the metatable associated with name tname in the registry (see luaL_newmetatable).
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="key">
/// A <see cref="System.String"/>
/// </param>
//public static extern void luaL_getmetatable( IntPtr state, string key );
public static void luaL_getmetatable( IntPtr luaState, string key )
public static bool luaL_dostring(Lua.lua_State state, string chunk)
{
lua_getfield(luaState, (int) PseudoIndex.Registry, key);
return (Lua.luaL_loadstring(state, chunk).ToLuaEnum() == LuaEnum.Ok) && (Lua.lua_pcall(state, 0, (int)LuaEnum.MultiRet, 0).ToLuaEnum() == LuaEnum.Ok);
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Loads a buffer as a Lua chunk. This function uses lua_load to load the chunk in the buffer pointed to by buff with size sz. name is the chunk name, used for debug and errors.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="buffer">
/// A <see cref="System.String"/>
/// </param>
/// <param name="size">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="name">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="LuaEnum"/>
/// </returns>
public static extern LuaEnum luaL_loadbuffer( IntPtr state, string buffer, int size, string name );
public static LuaEnum luaL_loadbuffer(IntPtr luaState, string buff, string name)
public static LuaEnum luaL_loadbuffer(Lua.lua_State luaState, string buff, string name)
{
//char *cs1 = (char *) Marshal.StringToHGlobalAnsi(buff).ToPointer();
//char *cs2 = (char *) Marshal.StringToHGlobalAnsi(name).ToPointer();
LuaEnum result = luaL_loadbuffer(luaState, buff, buff.Length, name);
//Marshal.FreeHGlobal(new IntPtr(cs1));
//Marshal.FreeHGlobal(new IntPtr(cs2));
LuaEnum result = Lua.luaL_loadbuffer(luaState, buff, (uint)buff.Length, name).ToLuaEnum();
return result;
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Loads a file as a Lua chunk. This function uses lua_load to load the chunk in the file named filename. If filename is NULL, then it loads from the standard input. The first line in the file is ignored if it starts with a #.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern LuaEnum luaL_loadfile( IntPtr state, string filename );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Loads a string as a Lua chunk. This function uses lua_load to load the chunk within the zero-terminated string.
/// </summary>
/// <param name="state">
/// A Lua State.<see cref="IntPtr"/>
/// </param>
/// <param name="str">
/// A chunk to load.<see cref="System.String"/>
/// </param>
/// <returns>
/// A result code. LuaEnum.Ok, LuaEnum.ErrorSyntax or LuaEnum.ErrorMemory<see cref="System.Int32"/>
/// </returns>
public static extern LuaEnum luaL_loadstring( IntPtr state, string str );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// If the registry already has the given key, returns false. Otherwise, creates a new table to be used as a metatable for userdata, adds it to the registry with the given key, and returns true.
/// In both cases pushes onto the stack the final value associated with the given key in the registry.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="key">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public static extern bool luaL_newmetatable( IntPtr state, string key );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Creates a new Lua state. It calls lua_newstate with an allocator based on the standard C realloc function and then sets a panic function (see lua_atpanic) that prints an error message to the standard error output in case of fatal errors.
/// </summary>
/// <returns>
/// A Lua State.<see cref="IntPtr"/>
/// </returns>
public static extern IntPtr luaL_newstate();
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Opens all standard Lua libraries into the given state.
/// </summary>
/// <param name="state">
/// A Lua State.<see cref="IntPtr"/>
/// </param>
public static extern void luaL_openlibs( IntPtr state );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Creates and returns a reference, in the table at index t, for the object at the top of the stack (and pops the object).
/// A reference is a unique integer key. As long as you do not manually add integer keys into table t, luaL_ref ensures the uniqueness of the key it returns. You can retrieve an object referred by reference r by calling lua_rawgeti(L, t, r). Function luaL_unref frees a reference and its associated object.
/// If the object at the top of the stack is nil, luaL_ref returns the constant LUA_REFNIL. The constant LUA_NOREF is guaranteed to be different from any reference returned by luaL_ref.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="t">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int luaL_ref( IntPtr state, int t );
/// <summary>
/// Pops the value referenced by reference by r in the table at index t onto the stack.
/// </summary>
......@@ -1269,199 +234,137 @@ namespace LuaWrap
/// <param name="r">
/// A <see cref="System.Int32"/>
/// </param>
public static void luaL_getref( IntPtr state, int t, int r )
public static void luaL_getref(Lua.lua_State state, int t, int r)
{
lua_rawgeti( state, t, r );
Lua.lua_rawgeti(state, t, r);
}
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Releases reference ref from the table at index t (see luaL_ef). The entry is removed from the table, so that the referred object can be collected. The reference ref is also freed to be used again.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="t">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="r">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.Int32"/>
/// </returns>
public static extern int luaL_unref( IntPtr state, int t, int r );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Returns the name of the type of the value at the given index.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="index">
/// A <see cref="System.Int32"/>
/// </param>
/// <returns>
/// A <see cref="System.String"/>
/// </returns>
public static extern string luaL_typename( IntPtr state, int index );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Generates an error with a message like the following:
/// location: bad argument narg to 'func' (*** expected, got rt)
/// where location is produced by luaL_where, func is the name of the current function, and rt is the type name of the actual argument.
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="narg">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="expected">
/// A <see cref="System.String"/>
/// </param>
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="narg">
/// A <see cref="System.Int32"/>
/// </param>
/// <param name="expected">
/// A <see cref="System.String"/>
/// </param>
public static extern void luaL_typeerror( IntPtr state, int narg, string expected );
[DllImport( Lib, CallingConvention = CallingConvention.Cdecl )]
/// <summary>
/// Pushes onto the stack a string identifying the current position of the control at level lvl in the call stack. Typically this string has the following format:
/// chunkname:currentline:
/// Level 0 is the running function, level 1 is the function that called the running function, etc.
/// </summary>
/// <param name="state">
/// A <see cref="IntPtr"/>
/// </param>
/// <param name="level">
/// A <see cref="System.Int32"/>
/// </param>
public static extern void luaL_where( IntPtr state, int level );
public static bool luaL_checkmetatable(IntPtr luaState,int index)
public static bool luaL_checkmetatable(Lua.lua_State luaState,int index)
{
bool retVal = false;
if(lua_getmetatable(luaState,index)!=0)
if(Lua.lua_getmetatable(luaState,index)!=0)
{
lua_pushlightuserdata(luaState, (IntPtr)tag);
lua_rawget(luaState, -2);
retVal = !lua_isnil(luaState, -1);
lua_settop(luaState, -3);
Lua.lua_pushlightuserdata(luaState, tag);
Lua.lua_rawget(luaState, -2);
retVal = !Lua.lua_isnil(luaState, -1);
Lua.lua_settop(luaState, -3);
}
return retVal;
}
public static IntPtr luanet_gettag()
public static int luanet_gettag()
{
return (IntPtr)tag;
return tag;
}
public static void lua_getref(IntPtr luaState, int reference)
public static void lua_getref(Lua.lua_State luaState, int reference)
{
lua_rawgeti(luaState, (int) PseudoIndex.Registry,reference);
Lua.lua_rawgeti(luaState, (int)PseudoIndex.Registry, reference);
}
public static void lua_unref(IntPtr luaState, int reference)
public static void lua_unref(Lua.lua_State luaState, int reference)
{
luaL_unref(luaState, (int) PseudoIndex.Registry,reference);
Lua.luaL_unref(luaState, (int)PseudoIndex.Registry, reference);
}
public static int luanet_rawnetobj(IntPtr luaState,int obj)
public static int luanet_rawnetobj(Lua.lua_State luaState,int obj)
{
IntPtr udata= lua_touserdata(luaState, obj);
if(udata!=(IntPtr)0) return udata.ToInt32();
int udata= Convert.ToInt32(Lua.lua_touserdata2(luaState, obj));
if(udata!=0)
return udata;
return -1;
}
public static void lua_pushstdcallcfunction(IntPtr luaState, CallbackFunction function)
public static void lua_pushstdcallcfunction(Lua.lua_State luaState, KopiLua.Lua.lua_CFunction function)
{
//IntPtr p = Marshal.GetFunctionPointerForDelegate(function);
lua_pushcfunction(luaState, function);
}
public static IntPtr checkudata_raw(IntPtr luaState, int ud, string tname)
public static int checkudata_raw(Lua.lua_State luaState, int ud, string tname)
{
IntPtr p = lua_touserdata(luaState, ud);
if (p != (IntPtr)0)
{ /* value is a userdata? */
if (lua_getmetatable(luaState, ud)!=0)
{
int p = (int)Lua.lua_touserdata2(luaState, ud);
Console.WriteLine("z:{0}", p);
if(p != 0)
{
/* value is a userdata? */
Console.WriteLine("z0:{0}", p);
//Console.WriteLine("z2:{0}", Lua.lua_getmetatable(luaState, ud));
if(Lua.lua_getmetatable(luaState, ud)!=0)
{
/* does it have a metatable? */
lua_getfield(luaState, (int) PseudoIndex.Registry, tname); /* get correct metatable */
bool isEqual = lua_rawequal(luaState, -1, -2);
Console.WriteLine("z1:{0}", p);
Lua.lua_getfield(luaState, (int)PseudoIndex.Registry, tname); /* get correct metatable */
//Console.WriteLine("z3:{0}", p);
bool isEqual = Lua.lua_rawequal(luaState, -1, -2).ToBoolean();
Console.WriteLine("z2:{0}", p);
Console.WriteLine("z2-1:{0}", isEqual);
// NASTY - we need our own version of the lua_pop macro
// lua_pop(L, 2); /* remove both metatables */
lua_settop(luaState, -(2) - 1);
if (isEqual) /* does it have the correct mt? */
Lua.lua_settop(luaState, -(2) - 1);
Console.WriteLine("z3:{0}", p);
if(isEqual) /* does it have the correct mt? */
return p;
}
}
}
}
return (IntPtr)0;
return 0;
}
public static int luanet_checkudata(IntPtr luaState, int ud, string tname)
public static int luanet_checkudata(Lua.lua_State luaState, int ud, string tname)
{
//char *cs = (char *) Marshal::StringToHGlobalAnsi(tname).ToPointer();
IntPtr udata= checkudata_raw(luaState, ud, tname);
int udata = checkudata_raw(luaState, ud, tname);
//Marshal::FreeHGlobal(IntPtr(cs));
if(udata != 0)
return udata;
if(udata!=(IntPtr)0) return udata.ToInt32();
return -1;
}
public static void luanet_newudata(IntPtr luaState,int val)
public static void luanet_newudata(Lua.lua_State luaState, int val)
{
IntPtr pointer = lua_newuserdata(luaState, sizeof(int));
pointer = (IntPtr)val;
Lua.lua_newuserdata(luaState, (uint)val);
}
public static int luanet_tonetobject(IntPtr luaState,int index)
public static int luanet_tonetobject(Lua.lua_State luaState, int index)
{
IntPtr udata;
int udata;
if(lua_type(luaState,index)==LuaType.UserData)
Console.WriteLine("asd:"+(Lua.lua_type(luaState, index).ToLuaType() == LuaType.UserData).ToString());
Console.WriteLine("asd:1"+Lua.lua_type(luaState, index));
if(Lua.lua_type(luaState, index).ToLuaType() == LuaType.UserData)
{
if(luaL_checkmetatable(luaState, index))
{
udata=(IntPtr) lua_touserdata(luaState,index);
if(udata!=(IntPtr)0)
return udata.ToInt32();
udata = (int)Lua.lua_touserdata2(luaState, index);
Console.WriteLine("asd0:{0}",udata);
if(udata != 0)
return udata;
}
udata = checkudata_raw(luaState, index, "luaNet_class");
Console.WriteLine("asd2:{0}",udata);
if(udata != 0)
return udata;
udata=(IntPtr)checkudata_raw(luaState,index, "luaNet_class");
if(udata!=(IntPtr)0) return udata.ToInt32();
udata=(IntPtr)checkudata_raw(luaState,index, "luaNet_searchbase");
if(udata!=(IntPtr)0) return udata.ToInt32();
udata=(IntPtr)checkudata_raw(luaState,index, "luaNet_function");
if(udata!=(IntPtr)0) return udata.ToInt32();
udata = checkudata_raw(luaState, index, "luaNet_searchbase");
Console.WriteLine("asd3:{0}",udata);
if(udata != 0)
return udata;
udata = checkudata_raw(luaState, index, "luaNet_function");
Console.WriteLine("asd4:{0}",udata);
if(udata != 0)
return udata;
}
return -1;
}
public static int lua_ref(IntPtr luaState, int lockRef)
public static int lua_ref(Lua.lua_State luaState, int lockRef)
{
if(lockRef!=0)
{
return luaL_ref(luaState, (int) PseudoIndex.Registry);
}
else return 0;
if(lockRef != 0)
return Lua.luaL_ref(luaState, (int)PseudoIndex.Registry);
else
return 0;
}
#endregion
......
namespace Mono.LuaInterface
namespace LuaInterface
{
using System;
using System.IO;
......@@ -39,37 +39,37 @@ namespace Mono.LuaInterface
private ObjectTranslator translator;
private Hashtable memberCache = new Hashtable();
internal CallbackFunction gcFunction, indexFunction, newindexFunction,
internal KopiLua.Lua.lua_CFunction gcFunction, indexFunction, newindexFunction,
baseIndexFunction, classIndexFunction, classNewindexFunction,
execDelegateFunction, callConstructorFunction, toStringFunction;
public MetaFunctions(ObjectTranslator translator)
{
this.translator = translator;
gcFunction = new CallbackFunction(this.collectObject);
toStringFunction = new CallbackFunction(this.toString);
indexFunction = new CallbackFunction(this.getMethod);
newindexFunction = new CallbackFunction(this.setFieldOrProperty);
baseIndexFunction = new CallbackFunction(this.getBaseMethod);
callConstructorFunction = new CallbackFunction(this.callConstructor);
classIndexFunction = new CallbackFunction(this.getClassMethod);
classNewindexFunction = new CallbackFunction(this.setClassFieldOrProperty);
execDelegateFunction = new CallbackFunction(this.runFunctionDelegate);
gcFunction = new KopiLua.Lua.lua_CFunction(this.collectObject);
toStringFunction = new KopiLua.Lua.lua_CFunction(this.toString);
indexFunction = new KopiLua.Lua.lua_CFunction(this.getMethod);
newindexFunction = new KopiLua.Lua.lua_CFunction(this.setFieldOrProperty);
baseIndexFunction = new KopiLua.Lua.lua_CFunction(this.getBaseMethod);
callConstructorFunction = new KopiLua.Lua.lua_CFunction(this.callConstructor);
classIndexFunction = new KopiLua.Lua.lua_CFunction(this.getClassMethod);
classNewindexFunction = new KopiLua.Lua.lua_CFunction(this.setClassFieldOrProperty);
execDelegateFunction = new KopiLua.Lua.lua_CFunction(this.runFunctionDelegate);
}
/*
* __call metafunction of CLR delegates, retrieves and calls the delegate.
*/
private int runFunctionDelegate(IntPtr luaState)
private int runFunctionDelegate(KopiLua.Lua.lua_State luaState)
{
CallbackFunction func = (CallbackFunction)translator.getRawNetObject(luaState, 1);
LuaLib.lua_remove(luaState, 1);
KopiLua.Lua.lua_CFunction func = (KopiLua.Lua.lua_CFunction)translator.getRawNetObject(luaState, 1);
KopiLua.Lua.lua_remove(luaState, 1);
return func(luaState);
}
/*
* __gc metafunction of CLR objects.
*/
private int collectObject(IntPtr luaState)
private int collectObject(KopiLua.Lua.lua_State luaState)
{
int udata = LuaLib.luanet_rawnetobj(luaState, 1);
if (udata != -1)
......@@ -85,14 +85,14 @@ namespace Mono.LuaInterface
/*
* __tostring metafunction of CLR objects.
*/
private int toString(IntPtr luaState)
private int toString(KopiLua.Lua.lua_State luaState)
{
object obj = translator.getRawNetObject(luaState, 1);
if (obj != null)
{
translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode());
}
else LuaLib.lua_pushnil(luaState);
else KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
......@@ -101,18 +101,18 @@ namespace Mono.LuaInterface
/// Debug tool to dump the lua stack
/// </summary>
/// FIXME, move somewhere else
public static void dumpStack(ObjectTranslator translator, IntPtr luaState)
public static void dumpStack(ObjectTranslator translator, KopiLua.Lua.lua_State luaState)
{
int depth = LuaLib.lua_gettop(luaState);
int depth = KopiLua.Lua.lua_gettop(luaState);
Debug.WriteLine("lua stack depth: " + depth);
for (int i = 1; i <= depth; i++)
{
LuaType type = LuaLib.lua_type(luaState, i);
LuaType type = KopiLua.Lua.lua_type(luaState, i).ToLuaType();
// we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types
string typestr = (type == LuaType.Table) ? "table" : LuaLib.lua_typename(luaState, type);
string typestr = (type == LuaType.Table) ? "table" : KopiLua.Lua.lua_typename(luaState, Convert.ToInt32(type)).ToString();
string strrep = LuaLib.lua_tostring(luaState, i);
string strrep = KopiLua.Lua.lua_tostring(luaState, i).ToString();
if (type == LuaType.UserData)
{
object obj = translator.getRawNetObject(luaState, i);
......@@ -131,13 +131,13 @@ namespace Mono.LuaInterface
* either the value of the member or a delegate to call it.
* If the member does not exist returns nil.
*/
private int getMethod(IntPtr luaState)
private int getMethod(KopiLua.Lua.lua_State luaState)
{
object obj = translator.getRawNetObject(luaState, 1);
if (obj == null)
{
translator.throwError(luaState, "trying to index an invalid object reference");
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
......@@ -168,7 +168,7 @@ namespace Mono.LuaInterface
{
translator.throwError(luaState, "method not found (or no indexer): " + index);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
else
{
......@@ -192,12 +192,12 @@ namespace Mono.LuaInterface
else
translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
}
}
LuaLib.lua_pushboolean(luaState, false);
KopiLua.Lua.lua_pushboolean(luaState, 0);
return 2;
}
......@@ -206,31 +206,31 @@ namespace Mono.LuaInterface
* __index metafunction of base classes (the base field of Lua tables).
* Adds a prefix to the method name to call the base version of the method.
*/
private int getBaseMethod(IntPtr luaState)
private int getBaseMethod(KopiLua.Lua.lua_State luaState)
{
object obj = translator.getRawNetObject(luaState, 1);
if (obj == null)
{
translator.throwError(luaState, "trying to index an invalid object reference");
LuaLib.lua_pushnil(luaState);
LuaLib.lua_pushboolean(luaState, false);
KopiLua.Lua.lua_pushnil(luaState);
KopiLua.Lua.lua_pushboolean(luaState, 0);
return 2;
}
string methodName = LuaLib.lua_tostring(luaState, 2);
string methodName = KopiLua.Lua.lua_tostring(luaState, 2).ToString();
if (methodName == null)
{
LuaLib.lua_pushnil(luaState);
LuaLib.lua_pushboolean(luaState, false);
KopiLua.Lua.lua_pushnil(luaState);
KopiLua.Lua.lua_pushboolean(luaState, 0);
return 2;
}
getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance);
LuaLib.lua_settop(luaState, -2);
if (LuaLib.lua_type(luaState, -1) == LuaType.Nil)
KopiLua.Lua.lua_settop(luaState, -2);
if (KopiLua.Lua.lua_type(luaState, -1).ToLuaType() == LuaType.Nil)
{
LuaLib.lua_settop(luaState, -2);
KopiLua.Lua.lua_settop(luaState, -2);
return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance);
}
LuaLib.lua_pushboolean(luaState, false);
KopiLua.Lua.lua_pushboolean(luaState, 0);
return 2;
}
......@@ -258,15 +258,15 @@ namespace Mono.LuaInterface
* Uses reflection to find members, and stores the reflected MemberInfo object in
* a cache (indexed by the type of the object and the name of the member).
*/
private int getMember(IntPtr luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType)
private int getMember(KopiLua.Lua.lua_State luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType)
{
bool implicitStatic = false;
MemberInfo member = null;
object cachedMember = checkMemberCache(memberCache, objType, methodName);
//object cachedMember=null;
if (cachedMember is CallbackFunction)
if (cachedMember is KopiLua.Lua.lua_CFunction)
{
translator.pushFunction(luaState, (CallbackFunction)cachedMember);
translator.pushFunction(luaState, (KopiLua.Lua.lua_CFunction)cachedMember);
translator.push(luaState, true);
return 2;
}
......@@ -304,7 +304,7 @@ namespace Mono.LuaInterface
}
catch
{
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
}
else if (member.MemberType == MemberTypes.Property)
......@@ -325,12 +325,12 @@ namespace Mono.LuaInterface
if (objType is Type && !(((Type)objType) == typeof(object)))
return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType);
else
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
catch(TargetInvocationException e) // Convert this exception into a Lua error
{
ThrowError(luaState, e);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
}
else if (member.MemberType == MemberTypes.Event)
......@@ -361,7 +361,7 @@ namespace Mono.LuaInterface
else
{
// Member type must be 'method'
CallbackFunction wrapper = new CallbackFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call);
KopiLua.Lua.lua_CFunction wrapper = new KopiLua.Lua.lua_CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call);
if (cachedMember == null) setMemberCache(memberCache, objType, methodName, wrapper);
translator.pushFunction(luaState, wrapper);
translator.push(luaState, true);
......@@ -373,7 +373,7 @@ namespace Mono.LuaInterface
// If we reach this point we found a static method, but can't use it in this context because the user passed in an instance
translator.throwError(luaState, "can't pass instance to static method " + methodName);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
}
else
......@@ -384,7 +384,7 @@ namespace Mono.LuaInterface
translator.throwError(luaState, "unknown member name " + methodName);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
// push false because we are NOT returning a function (see luaIndexFunction)
......@@ -420,7 +420,7 @@ namespace Mono.LuaInterface
* the member name and the value to be stored as arguments. Throws
* and error if the assignment is invalid.
*/
private int setFieldOrProperty(IntPtr luaState)
private int setFieldOrProperty(KopiLua.Lua.lua_State luaState)
{
object target = translator.getRawNetObject(luaState, 1);
if (target == null)
......@@ -440,9 +440,9 @@ namespace Mono.LuaInterface
// We didn't find a property name, now see if we can use a [] style this accessor to set array contents
try
{
if (type.IsArray && LuaLib.lua_isnumber(luaState, 2))
if (type.IsArray && KopiLua.Lua.lua_isnumber(luaState, 2).ToBoolean())
{
int index = (int)LuaLib.lua_tonumber(luaState, 2);
int index = (int)KopiLua.Lua.lua_tonumber(luaState, 2);
Array arr = (Array)target;
object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType());
......@@ -497,7 +497,7 @@ namespace Mono.LuaInterface
/// <param name="target"></param>
/// <param name="bindingType"></param>
/// <returns>false if unable to find the named member, true for success</returns>
private bool trySetMember(IntPtr luaState, IReflect targetType, object target, BindingFlags bindingType, out string detailMessage)
private bool trySetMember(KopiLua.Lua.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType, out string detailMessage)
{
detailMessage = null; // No error yet
......@@ -505,14 +505,14 @@ namespace Mono.LuaInterface
// changing the lua typecode to string
// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
// be true for isstring.
if (LuaLib.lua_type(luaState, 2) != LuaType.String)
if (KopiLua.Lua.lua_type(luaState, 2).ToLuaType() != LuaType.String)
{
detailMessage = "property names must be strings";
return false;
}
// We only look up property names by string
string fieldName = LuaLib.lua_tostring(luaState, 2);
string fieldName = KopiLua.Lua.lua_tostring(luaState, 2).ToString();
if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter(fieldName[0]) || fieldName[0] == '_'))
{
detailMessage = "invalid property name";
......@@ -576,7 +576,7 @@ namespace Mono.LuaInterface
* Writes to fields or properties, either static or instance. Throws an error
* if the operation is invalid.
*/
private int setMember(IntPtr luaState, IReflect targetType, object target, BindingFlags bindingType)
private int setMember(KopiLua.Lua.lua_State luaState, IReflect targetType, object target, BindingFlags bindingType)
{
string detail;
bool success = trySetMember(luaState, targetType, target, bindingType, out detail);
......@@ -592,7 +592,7 @@ namespace Mono.LuaInterface
/// </summary>
/// <param name="e"></param>
/// We try to look into the exception to give the most meaningful description
void ThrowError(IntPtr luaState, Exception e)
void ThrowError(KopiLua.Lua.lua_State luaState, Exception e)
{
// If we got inside a reflection show what really happened
TargetInvocationException te = e as TargetInvocationException;
......@@ -606,29 +606,29 @@ namespace Mono.LuaInterface
/*
* __index metafunction of type references, works on static members.
*/
private int getClassMethod(IntPtr luaState)
private int getClassMethod(KopiLua.Lua.lua_State luaState)
{
IReflect klass;
object obj = translator.getRawNetObject(luaState, 1);
if (obj == null || !(obj is IReflect))
{
translator.throwError(luaState, "trying to index an invalid type reference");
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
else klass = (IReflect)obj;
if (LuaLib.lua_isnumber(luaState, 2))
if (KopiLua.Lua.lua_isnumber(luaState, 2).ToBoolean())
{
int size = (int)LuaLib.lua_tonumber(luaState, 2);
int size = (int)KopiLua.Lua.lua_tonumber(luaState, 2);
translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size));
return 1;
}
else
{
string methodName = LuaLib.lua_tostring(luaState, 2);
string methodName = KopiLua.Lua.lua_tostring(luaState, 2).ToString();
if (methodName == null)
{
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
else return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static);
......@@ -637,7 +637,7 @@ namespace Mono.LuaInterface
/*
* __newindex function of type references, works on static members.
*/
private int setClassFieldOrProperty(IntPtr luaState)
private int setClassFieldOrProperty(KopiLua.Lua.lua_State luaState)
{
IReflect target;
object obj = translator.getRawNetObject(luaState, 1);
......@@ -655,7 +655,7 @@ namespace Mono.LuaInterface
* found or if the arguments are invalid. Throws an error if the constructor
* generates an exception.
*/
private int callConstructor(IntPtr luaState)
private int callConstructor(KopiLua.Lua.lua_State luaState)
{
MethodCache validConstructor = new MethodCache();
IReflect klass;
......@@ -663,11 +663,11 @@ namespace Mono.LuaInterface
if (obj == null || !(obj is IReflect))
{
translator.throwError(luaState, "trying to call constructor on an invalid type reference");
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
else klass = (IReflect)obj;
LuaLib.lua_remove(luaState, 1);
KopiLua.Lua.lua_remove(luaState, 1);
ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
foreach (ConstructorInfo constructor in constructors)
{
......@@ -681,11 +681,11 @@ namespace Mono.LuaInterface
catch (TargetInvocationException e)
{
ThrowError(luaState, e);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
catch
{
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
return 1;
}
......@@ -696,7 +696,7 @@ namespace Mono.LuaInterface
translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
klass.UnderlyingSystemType,
constructorName));
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
/*
......@@ -704,13 +704,13 @@ namespace Mono.LuaInterface
* if the match was succesful. It it was also returns the information
* necessary to invoke the method.
*/
internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
internal bool matchParameters(KopiLua.Lua.lua_State luaState, MethodBase method, ref MethodCache methodCache)
{
ExtractValue extractValue;
bool isMethod = true;
ParameterInfo[] paramInfo = method.GetParameters();
int currentLuaParam = 1;
int nLuaParams = LuaLib.lua_gettop(luaState);
int nLuaParams = KopiLua.Lua.lua_gettop(luaState);
ArrayList paramList = new ArrayList();
List<int> outList = new List<int>();
List<MethodArgs> argTypes = new List<MethodArgs>();
......@@ -754,7 +754,7 @@ namespace Mono.LuaInterface
}
}
if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
isMethod = false;
isMethod = false;
if (isMethod)
{
methodCache.args = paramList.ToArray();
......
namespace Mono.LuaInterface
namespace LuaInterface
{
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
using LuaWrap;
using System.Collections.Generic;
using System.Diagnostics;
using LuaWrap;
/*
* Cached method
......@@ -36,7 +36,7 @@ namespace Mono.LuaInterface
/*
* Argument extraction with type-conversion function
*/
delegate object ExtractValue(IntPtr luaState, int stackPos);
delegate object ExtractValue(KopiLua.Lua.lua_State luaState, int stackPos);
/*
* Wrapper class for methods/constructors accessed from Lua.
......@@ -85,49 +85,49 @@ namespace Mono.LuaInterface
}
/// <summary>
/// Convert C# exceptions into Lua errors
/// </summary>
/// <returns>num of things on stack</returns>
/// <param name="e">null for no pending exception</param>
int SetPendingException(Exception e)
{
return translator.interpreter.SetPendingException(e);
}
/// <summary>
/// Convert C# exceptions into Lua errors
/// </summary>
/// <returns>num of things on stack</returns>
/// <param name="e">null for no pending exception</param>
int SetPendingException(Exception e)
{
return translator.interpreter.SetPendingException(e);
}
/*
* Calls the method. Receives the arguments from the Lua stack
* and returns values in it.
*/
public int call(IntPtr luaState)
public int call(KopiLua.Lua.lua_State luaState)
{
MethodBase methodToCall=method;
MethodBase methodToCall=method;
object targetObject=target;
bool failedCall=true;
int nReturnValues=0;
if(!LuaLib.lua_checkstack(luaState,5))
if(!KopiLua.Lua.lua_checkstack(luaState,5).ToBoolean())
throw new LuaException("Lua stack overflow");
bool isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
bool isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
SetPendingException(null);
SetPendingException(null);
if(methodToCall==null) // Method from name
{
if (isStatic)
if (isStatic)
targetObject=null;
else
targetObject=extractTarget(luaState,1);
//LuaLib.lua_remove(luaState,1); // Pops the receiver
//KopiLua.Lua.lua_remove(luaState,1); // Pops the receiver
if(lastCalledMethod.cachedMethod!=null) // Cached?
{
int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject
int numArgsPassed = LuaLib.lua_gettop(luaState) - numStackToSkip;
int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject
int numArgsPassed = KopiLua.Lua.lua_gettop(luaState) - numStackToSkip;
if(numArgsPassed == lastCalledMethod.argTypes.Length) // No. of args match?
{
if(!LuaLib.lua_checkstack(luaState,lastCalledMethod.outList.Length+6))
if(!KopiLua.Lua.lua_checkstack(luaState,lastCalledMethod.outList.Length+6).ToBoolean())
throw new LuaException("Lua stack overflow");
try
{
......@@ -137,7 +137,7 @@ namespace Mono.LuaInterface
lastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip);
if(lastCalledMethod.args[lastCalledMethod.argTypes[i].index]==null &&
!LuaLib.lua_isnil(luaState, i + 1 + numStackToSkip))
!KopiLua.Lua.lua_isnil(luaState, i + 1 + numStackToSkip))
{
throw new LuaException("argument number "+(i+1)+" is invalid");
}
......@@ -172,27 +172,27 @@ namespace Mono.LuaInterface
// Cache miss
if(failedCall)
{
// System.Diagnostics.Debug.WriteLine("cache miss on " + methodName);
// System.Diagnostics.Debug.WriteLine("cache miss on " + methodName);
// If we are running an instance variable, we can now pop the targetObject from the stack
if (!isStatic)
{
if (targetObject == null)
{
translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", methodName));
LuaLib.lua_pushnil(luaState);
return 1;
}
LuaLib.lua_remove(luaState, 1); // Pops the receiver
}
if (!isStatic)
{
if (targetObject == null)
{
translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", methodName));
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
KopiLua.Lua.lua_remove(luaState, 1); // Pops the receiver
}
bool hasMatch=false;
string candidateName = null;
string candidateName = null;
foreach(MemberInfo member in members)
{
candidateName = member.ReflectedType.Name + "." + member.Name;
candidateName = member.ReflectedType.Name + "." + member.Name;
MethodBase m=(MethodInfo)member;
......@@ -205,12 +205,12 @@ namespace Mono.LuaInterface
}
if(!hasMatch)
{
string msg = (candidateName == null)
? "invalid arguments to method call"
: ("invalid arguments to method: " + candidateName);
string msg = (candidateName == null)
? "invalid arguments to method call"
: ("invalid arguments to method: " + candidateName);
translator.throwError(luaState, msg);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
}
......@@ -220,23 +220,23 @@ namespace Mono.LuaInterface
if(!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject==null)
{
targetObject=extractTarget(luaState,1);
LuaLib.lua_remove(luaState,1); // Pops the receiver
KopiLua.Lua.lua_remove(luaState,1); // Pops the receiver
}
if(!translator.matchParameters(luaState,methodToCall,ref lastCalledMethod))
{
translator.throwError(luaState,"invalid arguments to method call");
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
}
if(failedCall)
{
if(!LuaLib.lua_checkstack(luaState,lastCalledMethod.outList.Length+6))
if(!KopiLua.Lua.lua_checkstack(luaState,lastCalledMethod.outList.Length+6).ToBoolean())
throw new LuaException("Lua stack overflow");
try
{
if (isStatic)
if (isStatic)
{
translator.push(luaState,lastCalledMethod.cachedMethod.Invoke(null,lastCalledMethod.args));
}
......@@ -254,7 +254,7 @@ namespace Mono.LuaInterface
}
catch(Exception e)
{
return SetPendingException(e);
return SetPendingException(e);
}
}
......@@ -272,37 +272,37 @@ namespace Mono.LuaInterface
/// <summary>
/// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session
/// </summary>
class EventHandlerContainer : IDisposable
{
Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>();
/// <summary>
/// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session
/// </summary>
class EventHandlerContainer : IDisposable
{
Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>();
public void Add(Delegate handler, RegisterEventHandler eventInfo)
{
dict.Add(handler, eventInfo);
}
public void Add(Delegate handler, RegisterEventHandler eventInfo)
{
dict.Add(handler, eventInfo);
}
public void Remove(Delegate handler)
{
bool found = dict.Remove(handler);
Debug.Assert(found);
}
public void Remove(Delegate handler)
{
bool found = dict.Remove(handler);
Debug.Assert(found);
}
/// <summary>
/// Remove any still registered handlers
/// </summary>
public void Dispose()
{
foreach (KeyValuePair<Delegate, RegisterEventHandler> pair in dict)
{
pair.Value.RemovePending(pair.Key);
}
/// <summary>
/// Remove any still registered handlers
/// </summary>
public void Dispose()
{
foreach (KeyValuePair<Delegate, RegisterEventHandler> pair in dict)
{
pair.Value.RemovePending(pair.Key);
}
dict.Clear();
}
}
dict.Clear();
}
}
/*
......@@ -316,13 +316,13 @@ namespace Mono.LuaInterface
{
object target;
EventInfo eventInfo;
EventHandlerContainer pendingEvents;
EventHandlerContainer pendingEvents;
public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo)
{
this.target=target;
this.eventInfo=eventInfo;
this.pendingEvents = pendingEvents;
this.pendingEvents = pendingEvents;
}
......@@ -337,7 +337,7 @@ namespace Mono.LuaInterface
Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent");
eventInfo.AddEventHandler(target,handlerDelegate);
pendingEvents.Add(handlerDelegate, this);
pendingEvents.Add(handlerDelegate, this);
return handlerDelegate;
}
......@@ -348,16 +348,16 @@ namespace Mono.LuaInterface
public void Remove(Delegate handlerDelegate)
{
RemovePending(handlerDelegate);
pendingEvents.Remove(handlerDelegate);
pendingEvents.Remove(handlerDelegate);
}
/*
* Removes an existing event handler (without updating the pending handlers list)
*/
internal void RemovePending(Delegate handlerDelegate)
{
eventInfo.RemoveEventHandler(target, handlerDelegate);
}
/*
* Removes an existing event handler (without updating the pending handlers list)
*/
internal void RemovePending(Delegate handlerDelegate)
{
eventInfo.RemoveEventHandler(target, handlerDelegate);
}
}
/*
......@@ -441,7 +441,7 @@ namespace Mono.LuaInterface
object funcObj=luaTable.rawget(name);
if(funcObj is LuaFunction)
return (LuaFunction)funcObj;
else
else
return null;
}
/*
......
namespace Mono.LuaInterface
namespace LuaInterface
{
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
using LuaWrap;
using System.Collections.Generic;
using System.Diagnostics;
using LuaWrap;
/*
* Passes objects from the CLR to Lua and vice-versa
......@@ -18,31 +18,31 @@ namespace Mono.LuaInterface
{
internal CheckType typeChecker;
// object # to object (FIXME - it should be possible to get object address as an object #)
public readonly Dictionary<int, object> objects = new Dictionary<int, object>();
// object to object #
public readonly Dictionary<object, int> objectsBackMap = new Dictionary<object, int>();
internal Lua interpreter;
// object # to object (FIXME - it should be possible to get object address as an object #)
public readonly Dictionary<int, object> objects = new Dictionary<int, object>();
// object to object #
public readonly Dictionary<object, int> objectsBackMap = new Dictionary<object, int>();
internal Lua interpreter;
private MetaFunctions metaFunctions;
private List<Assembly> assemblies;
private CallbackFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction,
private KopiLua.Lua.lua_CFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction,
getConstructorSigFunction,importTypeFunction,loadAssemblyFunction;
internal EventHandlerContainer pendingEvents = new EventHandlerContainer();
internal EventHandlerContainer pendingEvents = new EventHandlerContainer();
public ObjectTranslator(Lua interpreter,IntPtr luaState)
public ObjectTranslator(Lua interpreter,KopiLua.Lua.lua_State luaState)
{
this.interpreter=interpreter;
typeChecker=new CheckType(this);
metaFunctions=new MetaFunctions(this);
assemblies=new List<Assembly>();
importTypeFunction=new CallbackFunction(this.importType);
loadAssemblyFunction=new CallbackFunction(this.loadAssembly);
registerTableFunction=new CallbackFunction(this.registerTable);
unregisterTableFunction=new CallbackFunction(this.unregisterTable);
getMethodSigFunction=new CallbackFunction(this.getMethodSignature);
getConstructorSigFunction=new CallbackFunction(this.getConstructorSignature);
importTypeFunction=new KopiLua.Lua.lua_CFunction(this.importType);
loadAssemblyFunction=new KopiLua.Lua.lua_CFunction(this.loadAssembly);
registerTableFunction=new KopiLua.Lua.lua_CFunction(this.registerTable);
unregisterTableFunction=new KopiLua.Lua.lua_CFunction(this.unregisterTable);
getMethodSigFunction=new KopiLua.Lua.lua_CFunction(this.getMethodSignature);
getConstructorSigFunction=new KopiLua.Lua.lua_CFunction(this.getConstructorSignature);
createLuaObjectList(luaState);
createIndexingMetaFunction(luaState);
......@@ -55,151 +55,151 @@ namespace Mono.LuaInterface
/*
* Sets up the list of objects in the Lua side
*/
private void createLuaObjectList(IntPtr luaState)
private void createLuaObjectList(KopiLua.Lua.lua_State luaState)
{
LuaLib.lua_pushstring(luaState,"luaNet_objects");
LuaLib.lua_newtable(luaState);
LuaLib.lua_newtable(luaState);
LuaLib.lua_pushstring(luaState,"__mode");
LuaLib.lua_pushstring(luaState,"v");
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_setmetatable(luaState,-2);
LuaLib.lua_settable(luaState, (int) PseudoIndex.Registry);
KopiLua.Lua.lua_pushstring(luaState,"luaNet_objects");
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_pushstring(luaState,"__mode");
KopiLua.Lua.lua_pushstring(luaState,"v");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_setmetatable(luaState,-2);
KopiLua.Lua.lua_settable(luaState, (int) PseudoIndex.Registry);
}
/*
* Registers the indexing function of CLR objects
* passed to Lua
*/
private void createIndexingMetaFunction(IntPtr luaState)
private void createIndexingMetaFunction(KopiLua.Lua.lua_State luaState)
{
LuaLib.lua_pushstring(luaState,"luaNet_indexfunction");
KopiLua.Lua.lua_pushstring(luaState,"luaNet_indexfunction");
LuaLib.luaL_dostring(luaState,MetaFunctions.luaIndexFunction); // steffenj: lua_dostring renamed to luaL_dostring
//LuaLib.lua_pushstdcallcfunction(luaState,indexFunction);
LuaLib.lua_rawset(luaState, (int) PseudoIndex.Registry);
KopiLua.Lua.lua_rawset(luaState, (int) PseudoIndex.Registry);
}
/*
* Creates the metatable for superclasses (the base
* field of registered tables)
*/
private void createBaseClassMetatable(IntPtr luaState)
private void createBaseClassMetatable(KopiLua.Lua.lua_State luaState)
{
LuaLib.luaL_newmetatable(luaState,"luaNet_searchbase");
LuaLib.lua_pushstring(luaState,"__gc");
KopiLua.Lua.luaL_newmetatable(luaState,"luaNet_searchbase");
KopiLua.Lua.lua_pushstring(luaState,"__gc");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__tostring");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__tostring");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__index");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__index");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__newindex");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__newindex");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_settop(luaState,-2);
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_settop(luaState,-2);
}
/*
* Creates the metatable for type references
*/
private void createClassMetatable(IntPtr luaState)
private void createClassMetatable(KopiLua.Lua.lua_State luaState)
{
LuaLib.luaL_newmetatable(luaState,"luaNet_class");
LuaLib.lua_pushstring(luaState,"__gc");
KopiLua.Lua.luaL_newmetatable(luaState,"luaNet_class");
KopiLua.Lua.lua_pushstring(luaState,"__gc");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__tostring");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__tostring");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__index");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__index");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__newindex");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__newindex");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__call");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__call");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_settop(luaState,-2);
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_settop(luaState,-2);
}
/*
* Registers the global functions used by LuaInterface
*/
private void setGlobalFunctions(IntPtr luaState)
private void setGlobalFunctions(KopiLua.Lua.lua_State luaState)
{
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction);
LuaLib.lua_setglobal(luaState,"get_object_member");
KopiLua.Lua.lua_setglobal(luaState,"get_object_member");
LuaLib.lua_pushstdcallcfunction(luaState,importTypeFunction);
LuaLib.lua_setglobal(luaState,"import_type");
KopiLua.Lua.lua_setglobal(luaState,"import_type");
LuaLib.lua_pushstdcallcfunction(luaState,loadAssemblyFunction);
LuaLib.lua_setglobal(luaState,"load_assembly");
KopiLua.Lua.lua_setglobal(luaState,"load_assembly");
LuaLib.lua_pushstdcallcfunction(luaState,registerTableFunction);
LuaLib.lua_setglobal(luaState,"make_object");
KopiLua.Lua.lua_setglobal(luaState,"make_object");
LuaLib.lua_pushstdcallcfunction(luaState,unregisterTableFunction);
LuaLib.lua_setglobal(luaState,"free_object");
KopiLua.Lua.lua_setglobal(luaState,"free_object");
LuaLib.lua_pushstdcallcfunction(luaState,getMethodSigFunction);
LuaLib.lua_setglobal(luaState,"get_method_bysig");
KopiLua.Lua.lua_setglobal(luaState,"get_method_bysig");
LuaLib.lua_pushstdcallcfunction(luaState,getConstructorSigFunction);
LuaLib.lua_setglobal(luaState,"get_constructor_bysig");
KopiLua.Lua.lua_setglobal(luaState,"get_constructor_bysig");
}
/*
* Creates the metatable for delegates
*/
private void createFunctionMetatable(IntPtr luaState)
private void createFunctionMetatable(KopiLua.Lua.lua_State luaState)
{
LuaLib.luaL_newmetatable(luaState,"luaNet_function");
LuaLib.lua_pushstring(luaState,"__gc");
KopiLua.Lua.luaL_newmetatable(luaState,"luaNet_function");
KopiLua.Lua.lua_pushstring(luaState,"__gc");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_pushstring(luaState,"__call");
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__call");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction);
LuaLib.lua_settable(luaState,-3);
LuaLib.lua_settop(luaState,-2);
KopiLua.Lua.lua_settable(luaState,-3);
KopiLua.Lua.lua_settop(luaState,-2);
}
/*
* Passes errors (argument e) to the Lua interpreter
*/
internal void throwError(IntPtr luaState,object e)
internal void throwError(KopiLua.Lua.lua_State luaState,object e)
{
// If the argument is a mere string, we are free to add extra info to it (as opposed to some private C# exception object or somesuch, which we just pass up)
if (e is string)
{
// We use this to remove anything pushed by luaL_where
int oldTop = LuaLib.lua_gettop(luaState);
// If the argument is a mere string, we are free to add extra info to it (as opposed to some private C# exception object or somesuch, which we just pass up)
if (e is string)
{
// We use this to remove anything pushed by luaL_where
int oldTop = KopiLua.Lua.lua_gettop(luaState);
// Stack frame #1 is our C# wrapper, so not very interesting to the user
// Stack frame #2 must be the lua code that called us, so that's what we want to use
LuaLib.luaL_where(luaState, 2);
object[] curlev = popValues(luaState, oldTop);
// Debug.WriteLine(curlev);
// Stack frame #1 is our C# wrapper, so not very interesting to the user
// Stack frame #2 must be the lua code that called us, so that's what we want to use
KopiLua.Lua.luaL_where(luaState, 2);
object[] curlev = popValues(luaState, oldTop);
// Debug.WriteLine(curlev);
if (curlev.Length > 0)
e = curlev[0].ToString() + e;
}
if (curlev.Length > 0)
e = curlev[0].ToString() + e;
}
push(luaState,e);
LuaLib.lua_error(luaState);
KopiLua.Lua.lua_error(luaState);
}
/*
* Implementation of load_assembly. Throws an error
* if the assembly is not found.
*/
private int loadAssembly(IntPtr luaState)
private int loadAssembly(KopiLua.Lua.lua_State luaState)
{
string assemblyName=LuaLib.lua_tostring(luaState,1);
string assemblyName=KopiLua.Lua.lua_tostring(luaState,1).ToString();
try
{
Assembly assembly=Assembly.LoadWithPartialName(assemblyName);
try
{
// If we couldn't find it based on a name, see if we can use it as a filename and find it
if (assembly == null)
assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
}
catch (Exception)
{
// ignore - it might not even be a filename
}
try
{
// If we couldn't find it based on a name, see if we can use it as a filename and find it
if (assembly == null)
assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
}
catch (Exception)
{
// ignore - it might not even be a filename
}
if(assembly!=null && !assemblies.Contains(assembly))
assemblies.Add(assembly);
......@@ -210,9 +210,9 @@ namespace Mono.LuaInterface
}
return 0;
}
internal Type FindType(string className)
{
internal Type FindType(string className)
{
foreach(Assembly assembly in assemblies)
{
Type klass=assembly.GetType(className);
......@@ -221,64 +221,64 @@ namespace Mono.LuaInterface
return klass;
}
}
return null;
}
return null;
}
/*
* Implementation of import_type. Returns nil if the
* type is not found.
*/
private int importType(IntPtr luaState)
private int importType(KopiLua.Lua.lua_State luaState)
{
string className=LuaLib.lua_tostring(luaState,1);
Type klass=FindType(className);
if(klass!=null)
string className=KopiLua.Lua.lua_tostring(luaState,1).ToString();
Type klass=FindType(className);
if(klass!=null)
pushType(luaState,klass);
else
LuaLib.lua_pushnil(luaState);
return 1;
}
else
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
/*
* Implementation of make_object. Registers a table (first
* argument in the stack) as an object subclassing the
* type passed as second argument in the stack.
*/
private int registerTable(IntPtr luaState)
private int registerTable(KopiLua.Lua.lua_State luaState)
{
if(LuaLib.lua_type(luaState,1)==LuaType.Table)
if(KopiLua.Lua.lua_type(luaState,1).ToLuaType()==LuaType.Table)
{
LuaTable luaTable=getTable(luaState,1);
string superclassName = LuaLib.lua_tostring(luaState, 2);
if (superclassName != null)
{
Type klass = FindType(superclassName);
if (klass != null)
{
// Creates and pushes the object in the stack, setting
// it as the metatable of the first argument
object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
pushObject(luaState, obj, "luaNet_metatable");
LuaLib.lua_newtable(luaState);
LuaLib.lua_pushstring(luaState, "__index");
LuaLib.lua_pushvalue(luaState, -3);
LuaLib.lua_settable(luaState, -3);
LuaLib.lua_pushstring(luaState, "__newindex");
LuaLib.lua_pushvalue(luaState, -3);
LuaLib.lua_settable(luaState, -3);
LuaLib.lua_setmetatable(luaState, 1);
// Pushes the object again, this time as the base field
// of the table and with the luaNet_searchbase metatable
LuaLib.lua_pushstring(luaState, "base");
//int index = addObject(obj);
//pushNewObject(luaState, obj, index, "luaNet_searchbase");
string superclassName = KopiLua.Lua.lua_tostring(luaState, 2).ToString();
if (superclassName != null)
{
Type klass = FindType(superclassName);
if (klass != null)
{
// Creates and pushes the object in the stack, setting
// it as the metatable of the first argument
object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
pushObject(luaState, obj, "luaNet_metatable");
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_pushstring(luaState, "__index");
KopiLua.Lua.lua_pushvalue(luaState, -3);
KopiLua.Lua.lua_settable(luaState, -3);
KopiLua.Lua.lua_pushstring(luaState, "__newindex");
KopiLua.Lua.lua_pushvalue(luaState, -3);
KopiLua.Lua.lua_settable(luaState, -3);
KopiLua.Lua.lua_setmetatable(luaState, 1);
// Pushes the object again, this time as the base field
// of the table and with the luaNet_searchbase metatable
KopiLua.Lua.lua_pushstring(luaState, "base");
//int index = addObject(obj);
//pushNewObject(luaState, obj, index, "luaNet_searchbase");
pushNewObject(luaState, obj, 0, "luaNet_searchbase");
LuaLib.lua_rawset(luaState, 1);
}
else
throwError(luaState, "register_table: can not find superclass '" + superclassName + "'");
}
else
throwError(luaState, "register_table: superclass name can not be null");
KopiLua.Lua.lua_rawset(luaState, 1);
}
else
throwError(luaState, "register_table: can not find superclass '" + superclassName + "'");
}
else
throwError(luaState, "register_table: superclass name can not be null");
}
else throwError(luaState,"register_table: first arg is not a table");
return 0;
......@@ -287,24 +287,24 @@ namespace Mono.LuaInterface
* Implementation of free_object. Clears the metatable and the
* base field, freeing the created object for garbage-collection
*/
private int unregisterTable(IntPtr luaState)
private int unregisterTable(KopiLua.Lua.lua_State luaState)
{
try
{
if(LuaLib.lua_getmetatable(luaState,1)!=0)
if(KopiLua.Lua.lua_getmetatable(luaState,1)!=0)
{
LuaLib.lua_pushstring(luaState,"__index");
LuaLib.lua_gettable(luaState,-2);
KopiLua.Lua.lua_pushstring(luaState,"__index");
KopiLua.Lua.lua_gettable(luaState,-2);
object obj=getRawNetObject(luaState,-1);
if(obj==null) throwError(luaState,"unregister_table: arg is not valid table");
FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable");
if(luaTableField==null) throwError(luaState,"unregister_table: arg is not valid table");
luaTableField.SetValue(obj,null);
LuaLib.lua_pushnil(luaState);
LuaLib.lua_setmetatable(luaState,1);
LuaLib.lua_pushstring(luaState,"base");
LuaLib.lua_pushnil(luaState);
LuaLib.lua_settable(luaState,1);
KopiLua.Lua.lua_pushnil(luaState);
KopiLua.Lua.lua_setmetatable(luaState,1);
KopiLua.Lua.lua_pushstring(luaState,"base");
KopiLua.Lua.lua_pushnil(luaState);
KopiLua.Lua.lua_settable(luaState,1);
}
else throwError(luaState,"unregister_table: arg is not valid table");
}
......@@ -318,7 +318,7 @@ namespace Mono.LuaInterface
* Implementation of get_method_bysig. Returns nil
* if no matching method is not found.
*/
private int getMethodSignature(IntPtr luaState)
private int getMethodSignature(KopiLua.Lua.lua_State luaState)
{
IReflect klass; object target;
int udata=LuaLib.luanet_checkudata(luaState,1,"luaNet_class");
......@@ -333,25 +333,25 @@ namespace Mono.LuaInterface
if(target==null)
{
throwError(luaState,"get_method_bysig: first arg is not type or object reference");
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return 1;
}
klass=target.GetType();
}
string methodName=LuaLib.lua_tostring(luaState,2);
Type[] signature=new Type[LuaLib.lua_gettop(luaState)-2];
string methodName=KopiLua.Lua.lua_tostring(luaState,2).ToString();
Type[] signature=new Type[KopiLua.Lua.lua_gettop(luaState)-2];
for(int i=0;i<signature.Length;i++)
signature[i]=FindType(LuaLib.lua_tostring(luaState,i+3));
signature[i]=FindType(KopiLua.Lua.lua_tostring(luaState,i+3).ToString());
try
{
MethodInfo method=klass.GetMethod(methodName,BindingFlags.Public | BindingFlags.Static |
BindingFlags.Instance | BindingFlags.FlattenHierarchy,null,signature,null);
pushFunction(luaState,new CallbackFunction((new LuaMethodWrapper(this,target,klass,method)).call));
BindingFlags.Instance | BindingFlags.FlattenHierarchy,null,signature,null);
pushFunction(luaState,new KopiLua.Lua.lua_CFunction((new LuaMethodWrapper(this,target,klass,method)).call));
}
catch(Exception e)
{
throwError(luaState,e);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
return 1;
}
......@@ -359,7 +359,7 @@ namespace Mono.LuaInterface
* Implementation of get_constructor_bysig. Returns nil
* if no matching constructor is found.
*/
private int getConstructorSignature(IntPtr luaState)
private int getConstructorSignature(KopiLua.Lua.lua_State luaState)
{
IReflect klass=null;
int udata=LuaLib.luanet_checkudata(luaState,1,"luaNet_class");
......@@ -371,32 +371,32 @@ namespace Mono.LuaInterface
{
throwError(luaState,"get_constructor_bysig: first arg is invalid type reference");
}
Type[] signature=new Type[LuaLib.lua_gettop(luaState)-1];
Type[] signature=new Type[KopiLua.Lua.lua_gettop(luaState)-1];
for(int i=0;i<signature.Length;i++)
signature[i]=FindType(LuaLib.lua_tostring(luaState,i+2));
signature[i]=FindType(KopiLua.Lua.lua_tostring(luaState,i+2).ToString());
try
{
ConstructorInfo constructor=klass.UnderlyingSystemType.GetConstructor(signature);
pushFunction(luaState,new CallbackFunction((new LuaMethodWrapper(this,null,klass,constructor)).call));
pushFunction(luaState,new KopiLua.Lua.lua_CFunction((new LuaMethodWrapper(this,null,klass,constructor)).call));
}
catch(Exception e)
{
throwError(luaState,e);
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
return 1;
}
/*
* Pushes a type reference into the stack
*/
internal void pushType(IntPtr luaState, Type t)
internal void pushType(KopiLua.Lua.lua_State luaState, Type t)
{
pushObject(luaState,new ProxyType(t),"luaNet_class");
}
/*
* Pushes a delegate into the stack
*/
internal void pushFunction(IntPtr luaState, CallbackFunction func)
internal void pushFunction(KopiLua.Lua.lua_State luaState, KopiLua.Lua.lua_CFunction func)
{
pushObject(luaState,func,"luaNet_function");
}
......@@ -404,46 +404,46 @@ namespace Mono.LuaInterface
* Pushes a CLR object into the Lua stack as an userdata
* with the provided metatable
*/
internal void pushObject(IntPtr luaState, object o, string metatable)
internal void pushObject(KopiLua.Lua.lua_State luaState, object o, string metatable)
{
int index = -1;
// Pushes nil
if(o==null)
{
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
return;
}
// Object already in the list of Lua objects? Push the stored reference.
bool found = objectsBackMap.TryGetValue(o, out index);
bool found = objectsBackMap.TryGetValue(o, out index);
if(found)
{
LuaLib.luaL_getmetatable(luaState,"luaNet_objects");
LuaLib.lua_rawgeti(luaState,-1,index);
KopiLua.Lua.luaL_getmetatable(luaState,"luaNet_objects");
KopiLua.Lua.lua_rawgeti(luaState,-1,index);
// Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep
// occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later. During that window we might call
// this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called. In that case, we go ahead and call collect
// object here
// did we find a non nil object in our table? if not, we need to call collect object
LuaType type = LuaLib.lua_type(luaState, -1);
if (type != LuaType.Nil)
{
LuaLib.lua_remove(luaState, -2); // drop the metatable - we're going to leave our object on the stack
// Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep
// occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later. During that window we might call
// this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called. In that case, we go ahead and call collect
// object here
// did we find a non nil object in our table? if not, we need to call collect object
LuaType type = KopiLua.Lua.lua_type(luaState, -1).ToLuaType();
if (type != LuaType.Nil)
{
KopiLua.Lua.lua_remove(luaState, -2); // drop the metatable - we're going to leave our object on the stack
return;
}
return;
}
// MetaFunctions.dumpStack(this, luaState);
LuaLib.lua_remove(luaState, -1); // remove the nil object value
LuaLib.lua_remove(luaState, -1); // remove the metatable
// MetaFunctions.dumpStack(this, luaState);
KopiLua.Lua.lua_remove(luaState, -1); // remove the nil object value
KopiLua.Lua.lua_remove(luaState, -1); // remove the metatable
collectObject(o, index); // Remove from both our tables and fall out to get a new ID
collectObject(o, index); // Remove from both our tables and fall out to get a new ID
}
//index = addObject(o);
index = addObject(o);
//Console.WriteLine("pushObject: {0}", index);
pushNewObject(luaState,o,0,metatable);
//pushNewObject(luaState,o,index,metatable);
//pushNewObject(luaState,o,0,metatable);
pushNewObject(luaState,o,index,metatable);
}
......@@ -451,64 +451,65 @@ namespace Mono.LuaInterface
* Pushes a new object into the Lua stack with the provided
* metatable
*/
private void pushNewObject(IntPtr luaState,object o,int index,string metatable)
private void pushNewObject(KopiLua.Lua.lua_State luaState,object o,int index,string metatable)
{
if(metatable=="luaNet_metatable")
{
// Gets or creates the metatable for the object's type
LuaLib.luaL_getmetatable(luaState,o.GetType().AssemblyQualifiedName);
KopiLua.Lua.luaL_getmetatable(luaState,o.GetType().AssemblyQualifiedName);
if(LuaLib.lua_isnil(luaState,-1))
if(KopiLua.Lua.lua_isnil(luaState,-1))
{
LuaLib.lua_settop(luaState,-2);
LuaLib.luaL_newmetatable(luaState,o.GetType().AssemblyQualifiedName);
LuaLib.lua_pushstring(luaState,"cache");
LuaLib.lua_newtable(luaState);
LuaLib.lua_rawset(luaState,-3);
LuaLib.lua_pushlightuserdata(luaState,LuaLib.luanet_gettag());
LuaLib.lua_pushnumber(luaState,1);
LuaLib.lua_rawset(luaState,-3);
LuaLib.lua_pushstring(luaState,"__index");
LuaLib.lua_pushstring(luaState,"luaNet_indexfunction");
LuaLib.lua_rawget(luaState, (int) PseudoIndex.Registry);
LuaLib.lua_rawset(luaState,-3);
LuaLib.lua_pushstring(luaState,"__gc");
KopiLua.Lua.lua_settop(luaState,-2);
KopiLua.Lua.luaL_newmetatable(luaState,o.GetType().AssemblyQualifiedName);
KopiLua.Lua.lua_pushstring(luaState,"cache");
KopiLua.Lua.lua_newtable(luaState);
KopiLua.Lua.lua_rawset(luaState,-3);
KopiLua.Lua.lua_pushlightuserdata(luaState,LuaLib.luanet_gettag());
KopiLua.Lua.lua_pushnumber(luaState,1);
KopiLua.Lua.lua_rawset(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__index");
KopiLua.Lua.lua_pushstring(luaState,"luaNet_indexfunction");
KopiLua.Lua.lua_rawget(luaState, (int) PseudoIndex.Registry);
KopiLua.Lua.lua_rawset(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__gc");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaLib.lua_rawset(luaState,-3);
LuaLib.lua_pushstring(luaState,"__tostring");
KopiLua.Lua.lua_rawset(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__tostring");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaLib.lua_rawset(luaState,-3);
LuaLib.lua_pushstring(luaState,"__newindex");
KopiLua.Lua.lua_rawset(luaState,-3);
KopiLua.Lua.lua_pushstring(luaState,"__newindex");
LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
LuaLib.lua_rawset(luaState,-3);
KopiLua.Lua.lua_rawset(luaState,-3);
}
}
else
{
LuaLib.luaL_getmetatable(luaState,metatable);
KopiLua.Lua.luaL_getmetatable(luaState,metatable);
}
// Stores the object index in the Lua list and pushes the
// index into the Lua stack
LuaLib.luaL_getmetatable(luaState,"luaNet_objects");
KopiLua.Lua.luaL_getmetatable(luaState,"luaNet_objects");
//Console.WriteLine("luaState2:" + luaState);
nextObj++;
index = LuaLib.lua_newuserdata(luaState, nextObj).ToInt32();
addObject(o, index);
//LuaLib.luanet_newudata(luaState,index);
//nextObj++;
//index = (int)KopiLua.Lua.lua_newuserdata2(luaState, (uint)nextObj);
//Console.WriteLine(index);
//addObject(o, index);
LuaLib.luanet_newudata(luaState,index);
//Console.WriteLine("index:"+index);
LuaLib.lua_pushvalue(luaState,-3);
LuaLib.lua_remove(luaState,-4);
LuaLib.lua_setmetatable(luaState,-2);
LuaLib.lua_pushvalue(luaState,-1);
LuaLib.lua_rawseti(luaState,-3,index);
LuaLib.lua_remove(luaState,-2);
KopiLua.Lua.lua_pushvalue(luaState,-3);
KopiLua.Lua.lua_remove(luaState,-4);
KopiLua.Lua.lua_setmetatable(luaState,-2);
KopiLua.Lua.lua_pushvalue(luaState,-1);
KopiLua.Lua.lua_rawseti(luaState,-3,index);
KopiLua.Lua.lua_remove(luaState,-2);
}
/*
* Gets an object from the Lua stack with the desired type, if it matches, otherwise
* returns null.
*/
internal object getAsType(IntPtr luaState,int stackPos,Type paramType)
internal object getAsType(KopiLua.Lua.lua_State luaState,int stackPos,Type paramType)
{
ExtractValue extractor=typeChecker.checkType(luaState,stackPos,paramType);
if(extractor!=null) return extractor(luaState,stackPos);
......@@ -516,90 +517,90 @@ namespace Mono.LuaInterface
}
/// <summary>
/// Given the Lua int ID for an object remove it from our maps
/// </summary>
/// <param name="udata"></param>
/// <summary>
/// Given the Lua int ID for an object remove it from our maps
/// </summary>
/// <param name="udata"></param>
internal void collectObject(int udata)
{
object o;
bool found = objects.TryGetValue(udata, out o);
bool found = objects.TryGetValue(udata, out o);
// The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry
if (found)
{
// Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
// The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry
if (found)
{
// Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
objects.Remove(udata);
objectsBackMap.Remove(o);
}
objects.Remove(udata);
objectsBackMap.Remove(o);
}
}
/// <summary>
/// Given an object reference, remove it from our maps
/// </summary>
/// <param name="udata"></param>
void collectObject(object o, int udata)
{
// Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
/// <summary>
/// Given an object reference, remove it from our maps
/// </summary>
/// <param name="udata"></param>
void collectObject(object o, int udata)
{
// Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
objects.Remove(udata);
objectsBackMap.Remove(o);
}
objects.Remove(udata);
objectsBackMap.Remove(o);
}
/// <summary>
/// We want to ensure that objects always have a unique ID
/// </summary>
int nextObj = 0;
/// <summary>
/// We want to ensure that objects always have a unique ID
/// </summary>
int nextObj = 0;
int addObject(object obj)
{
// New object: inserts it in the list
int index = nextObj++;
int addObject(object obj)
{
// New object: inserts it in the list
int index = nextObj++;
//Console.WriteLine("Adding " + obj.ToString() + " @ " + index);
//Console.WriteLine("Adding " + obj.ToString() + " @ " + index);
objects[index] = obj;
objectsBackMap[obj] = index;
objects[index] = obj;
objectsBackMap[obj] = index;
return index;
}
return index;
}
int addObject(object obj, int index)
{
// New object: inserts it in the list
//int index = nextObj++;
int addObject(object obj, int index)
{
// New object: inserts it in the list
//int index = nextObj++;
//Console.WriteLine("Adding " + obj.ToString() + " @ " + index);
//Console.WriteLine("Adding " + obj.ToString() + " @ " + index);
objects[index] = obj;
objectsBackMap[obj] = index;
objects[index] = obj;
objectsBackMap[obj] = index;
return index;
}
return index;
}
/*
* Gets an object from the Lua stack according to its Lua type.
*/
internal object getObject(IntPtr luaState,int index)
internal object getObject(KopiLua.Lua.lua_State luaState,int index)
{
LuaType type=LuaLib.lua_type(luaState,index);
LuaType type=KopiLua.Lua.lua_type(luaState,index).ToLuaType();
switch(type)
{
case LuaType.Number:
{
return LuaLib.lua_tonumber(luaState,index);
return KopiLua.Lua.lua_tonumber(luaState,index);
}
case LuaType.String:
{
return LuaLib.lua_tostring(luaState,index);
return KopiLua.Lua.lua_tostring(luaState,index);
}
case LuaType.Boolean:
{
return LuaLib.lua_toboolean(luaState,index);
return KopiLua.Lua.lua_toboolean(luaState,index);
}
case LuaType.Table:
{
......@@ -612,6 +613,7 @@ namespace Mono.LuaInterface
case LuaType.UserData:
{
int udata=LuaLib.luanet_tonetobject(luaState,index);
Console.WriteLine("udata: {0}", udata);
if(udata!=-1)
return objects[udata];
......@@ -625,32 +627,32 @@ namespace Mono.LuaInterface
/*
* Gets the table in the index positon of the Lua stack.
*/
internal LuaTable getTable(IntPtr luaState,int index)
internal LuaTable getTable(KopiLua.Lua.lua_State luaState,int index)
{
LuaLib.lua_pushvalue(luaState,index);
KopiLua.Lua.lua_pushvalue(luaState,index);
return new LuaTable(LuaLib.lua_ref(luaState,1),interpreter);
}
/*
* Gets the userdata in the index positon of the Lua stack.
*/
internal LuaUserData getUserData(IntPtr luaState,int index)
internal LuaUserData getUserData(KopiLua.Lua.lua_State luaState,int index)
{
LuaLib.lua_pushvalue(luaState,index);
KopiLua.Lua.lua_pushvalue(luaState,index);
return new LuaUserData(LuaLib.lua_ref(luaState,1),interpreter);
}
/*
* Gets the function in the index positon of the Lua stack.
*/
internal LuaFunction getFunction(IntPtr luaState,int index)
internal LuaFunction getFunction(KopiLua.Lua.lua_State luaState,int index)
{
LuaLib.lua_pushvalue(luaState,index);
KopiLua.Lua.lua_pushvalue(luaState,index);
return new LuaFunction(LuaLib.lua_ref(luaState,1),interpreter);
}
/*
* Gets the CLR object in the index positon of the Lua stack. Returns
* delegates as Lua functions.
*/
internal object getNetObject(IntPtr luaState,int index)
internal object getNetObject(KopiLua.Lua.lua_State luaState,int index)
{
int idx=LuaLib.luanet_tonetobject(luaState,index);
if(idx!=-1)
......@@ -662,7 +664,7 @@ namespace Mono.LuaInterface
* Gets the CLR object in the index positon of the Lua stack. Returns
* delegates as is.
*/
internal object getRawNetObject(IntPtr luaState,int index)
internal object getRawNetObject(KopiLua.Lua.lua_State luaState,int index)
{
int udata=LuaLib.luanet_rawnetobj(luaState,index);
if(udata!=-1)
......@@ -675,9 +677,9 @@ namespace Mono.LuaInterface
* Pushes the entire array into the Lua stack and returns the number
* of elements pushed.
*/
internal int returnValues(IntPtr luaState, object[] returnValues)
internal int returnValues(KopiLua.Lua.lua_State luaState, object[] returnValues)
{
if(LuaLib.lua_checkstack(luaState,returnValues.Length+5))
if(KopiLua.Lua.lua_checkstack(luaState,returnValues.Length+5).ToBoolean())
{
for(int i=0;i<returnValues.Length;i++)
{
......@@ -691,9 +693,9 @@ namespace Mono.LuaInterface
* Gets the values from the provided index to
* the top of the stack and returns them in an array.
*/
internal object[] popValues(IntPtr luaState,int oldTop)
internal object[] popValues(KopiLua.Lua.lua_State luaState,int oldTop)
{
int newTop=LuaLib.lua_gettop(luaState);
int newTop=KopiLua.Lua.lua_gettop(luaState);
if(oldTop==newTop)
{
return null;
......@@ -705,7 +707,7 @@ namespace Mono.LuaInterface
{
returnValues.Add(getObject(luaState,i));
}
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
return returnValues.ToArray();
}
}
......@@ -714,9 +716,9 @@ namespace Mono.LuaInterface
* the top of the stack and returns them in an array, casting
* them to the provided types.
*/
internal object[] popValues(IntPtr luaState,int oldTop,Type[] popTypes)
internal object[] popValues(KopiLua.Lua.lua_State luaState,int oldTop,Type[] popTypes)
{
int newTop=LuaLib.lua_gettop(luaState);
int newTop=KopiLua.Lua.lua_gettop(luaState);
if(oldTop==newTop)
{
return null;
......@@ -734,57 +736,57 @@ namespace Mono.LuaInterface
returnValues.Add(getAsType(luaState,i,popTypes[iTypes]));
iTypes++;
}
LuaLib.lua_settop(luaState,oldTop);
KopiLua.Lua.lua_settop(luaState,oldTop);
return returnValues.ToArray();
}
}
// kevinh - the following line doesn't work for remoting proxies - they always return a match for 'is'
// kevinh - the following line doesn't work for remoting proxies - they always return a match for 'is'
// else if(o is ILuaGeneratedType)
static bool IsILua(object o)
{
if(o is ILuaGeneratedType)
{
// Make sure we are _really_ ILuaGenerated
Type typ = o.GetType();
return (typ.GetInterface("ILuaGeneratedType") != null);
}
else
return false;
}
static bool IsILua(object o)
{
if(o is ILuaGeneratedType)
{
// Make sure we are _really_ ILuaGenerated
Type typ = o.GetType();
return (typ.GetInterface("ILuaGeneratedType") != null);
}
else
return false;
}
/*
* Pushes the object into the Lua stack according to its type.
*/
internal void push(IntPtr luaState, object o)
internal void push(KopiLua.Lua.lua_State luaState, object o)
{
//Console.WriteLine("push: {0}, {1}", o, luaState);
if(o==null)
{
LuaLib.lua_pushnil(luaState);
KopiLua.Lua.lua_pushnil(luaState);
}
else if(o is sbyte || o is byte || o is short || o is ushort ||
o is int || o is uint || o is long || o is float ||
o is ulong || o is decimal || o is double)
{
double d=Convert.ToDouble(o);
LuaLib.lua_pushnumber(luaState,d);
KopiLua.Lua.lua_pushnumber(luaState,d);
}
else if(o is char)
{
double d = (char)o;
LuaLib.lua_pushnumber(luaState,d);
KopiLua.Lua.lua_pushnumber(luaState,d);
}
else if(o is string)
{
string str=(string)o;
LuaLib.lua_pushstring(luaState,str);
KopiLua.Lua.lua_pushstring(luaState,str);
}
else if(o is bool)
{
bool b=(bool)o;
LuaLib.lua_pushboolean(luaState,b);
KopiLua.Lua.lua_pushboolean(luaState,(b == true) ? 1 : 0);
}
else if(IsILua(o))
{
......@@ -794,9 +796,9 @@ namespace Mono.LuaInterface
{
((LuaTable)o).push(luaState);
}
else if(o is CallbackFunction)
else if(o is KopiLua.Lua.lua_CFunction)
{
pushFunction(luaState,(CallbackFunction)o);
pushFunction(luaState,(KopiLua.Lua.lua_CFunction)o);
}
else if(o is LuaFunction)
{
......@@ -811,7 +813,7 @@ namespace Mono.LuaInterface
* Checks if the method matches the arguments in the Lua stack, getting
* the arguments if it does.
*/
internal bool matchParameters(IntPtr luaState,MethodBase method,ref MethodCache methodCache)
internal bool matchParameters(KopiLua.Lua.lua_State luaState,MethodBase method,ref MethodCache methodCache)
{
return metaFunctions.matchParameters(luaState,method,ref methodCache);
}
......
......@@ -2,14 +2,13 @@ using System;
using System.Globalization;
using System.Reflection;
namespace Mono.LuaInterface
namespace LuaInterface
{
/// <summary>
/// Summary description for ProxyType.
/// </summary>
public class ProxyType : IReflect
{
Type proxy;
public ProxyType(Type proxy)
......@@ -17,14 +16,14 @@ namespace Mono.LuaInterface
this.proxy = proxy;
}
/// <summary>
/// Provide human readable short hand for this proxy object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ProxyType(" + UnderlyingSystemType + ")";
}
/// <summary>
/// Provide human readable short hand for this proxy object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ProxyType(" + UnderlyingSystemType + ")";
}
public Type UnderlyingSystemType
......@@ -91,4 +90,4 @@ namespace Mono.LuaInterface
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment