Commit 25079f4b authored by capresti's avatar capresti
Browse files

- Added a check for a passed state on Close

- Added overloaded DoString 
- Added some more test cases

git-svn-id: http://luainterface.googlecode.com/svn/trunk@6 63eb109e-e254-0410-a61e-ed0b8f8614f5
parent 45286744
...@@ -101,33 +101,41 @@ namespace LuaInterface ...@@ -101,33 +101,41 @@ namespace LuaInterface
//LuaDLL.lua_atunlock(luaState, unlockCallback = new LuaCSFunction(UnlockCallback)); //LuaDLL.lua_atunlock(luaState, unlockCallback = new LuaCSFunction(UnlockCallback));
} }
private bool _StatePassed;
/* /*
* CAUTION: LuaInterface.Lua instances can't share the same lua state! * CAUTION: LuaInterface.Lua instances can't share the same lua state!
*/ */
public Lua(Int64 luaState) public Lua(Int64 luaState)
{ {
IntPtr lState = new IntPtr(luaState); IntPtr lState = new IntPtr(luaState);
LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED");
LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX);
if(LuaDLL.lua_toboolean(lState,-1))
{
LuaDLL.lua_settop(lState,-2);
throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
}
else
{
LuaDLL.lua_settop(lState,-2);
LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED");
LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_pushboolean(lState, true);
if(LuaDLL.lua_toboolean(lState,-1)) { LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX);
LuaDLL.lua_settop(lState,-2); this.luaState=lState;
throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state"); LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
} else { LuaDLL.lua_getglobal(lState, "luanet");
LuaDLL.lua_settop(lState,-2); LuaDLL.lua_pushstring(lState, "getmetatable");
LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaDLL.lua_getglobal(lState, "getmetatable");
LuaDLL.lua_pushboolean(lState, true); LuaDLL.lua_settable(lState, -3);
LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
this.luaState=lState; translator=new ObjectTranslator(this, this.luaState);
LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
LuaDLL.lua_getglobal(lState, "luanet"); LuaDLL.luaL_dostring(lState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
LuaDLL.lua_pushstring(lState, "getmetatable"); }
LuaDLL.lua_getglobal(lState, "getmetatable");
LuaDLL.lua_settable(lState, -3); _StatePassed = true;
LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
translator=new ObjectTranslator(this, this.luaState);
LuaDLL.lua_replace(lState, (int)LuaIndexes.LUA_GLOBALSINDEX);
LuaDLL.luaL_dostring(lState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
}
} }
/// <summary> /// <summary>
...@@ -156,9 +164,12 @@ namespace LuaInterface ...@@ -156,9 +164,12 @@ namespace LuaInterface
public void Close() public void Close()
{ {
if (_StatePassed)
return;
if (luaState != IntPtr.Zero) if (luaState != IntPtr.Zero)
LuaDLL.lua_close(luaState); LuaDLL.lua_close(luaState);
luaState = IntPtr.Zero; //luaState = IntPtr.Zero; <- suggested by Christopher Cebulski http://luaforge.net/forum/forum.php?thread_id=44593&forum_id=146
} }
static int PanicCallback(IntPtr luaState) static int PanicCallback(IntPtr luaState)
...@@ -266,6 +277,29 @@ namespace LuaInterface ...@@ -266,6 +277,29 @@ namespace LuaInterface
return null; // Never reached - keeps compiler happy return null; // Never reached - keeps compiler happy
} }
/// <summary>
/// Executes a Lua chnk and returns all the chunk's return values in an array.
/// </summary>
/// <param name="chunk">Chunk to execute</param>
/// <param name="chunkName">Name to associate with the chunk</param>
/// <returns></returns>
public object[] DoString(string chunk, string chunkName)
{
int oldTop = LuaDLL.lua_gettop(luaState);
if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunkName) == 0)
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
else
ThrowExceptionFromError(oldTop);
return null; // Never reached - keeps compiler happy
}
/* /*
* Excutes a Lua file and returns all the chunk's return * Excutes a Lua file and returns all the chunk's return
* values in an array * values in an array
......
...@@ -95,6 +95,33 @@ namespace LuaInterface.Tests ...@@ -95,6 +95,33 @@ namespace LuaInterface.Tests
} }
} }
public class TestClassGeneric<T>
{
private bool _RegularMethodSuccess;
public bool RegularMethodSuccess
{
get { return _RegularMethodSuccess; }
}
private bool _GenericMethodSuccess;
public bool GenericMethodSuccess
{
get { return _GenericMethodSuccess; }
}
public void GenericMethod<T>(T value)
{
_GenericMethodSuccess = true;
}
public void RegularMethod()
{
_RegularMethodSuccess = true;
}
}
/* /*
* Sample class used in several test cases to check if * Sample class used in several test cases to check if
* Lua scripts are accessing objects correctly * Lua scripts are accessing objects correctly
......
...@@ -1077,12 +1077,34 @@ namespace LuaInterface.Tests ...@@ -1077,12 +1077,34 @@ namespace LuaInterface.Tests
for (int i = 0; i < 10000; i++) for (int i = 0; i < 10000; i++)
{ {
using (Lua lua = new Lua()) using (Lua lua = new Lua())
{ } {
_Calc(lua, i);
}
} }
Console.WriteLine("Was using " + startingMem / 1024 / 1024 + "MB, now using: " + System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024 + "MB"); Console.WriteLine("Was using " + startingMem / 1024 / 1024 + "MB, now using: " + System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024 + "MB");
} }
private void _Calc(Lua lua, int i)
{
lua.DoString(
"sqrt = math.sqrt;" +
"sqr = function(x) return math.pow(x,2); end;" +
"log = math.log;" +
"log10 = math.log10;" +
"exp = math.exp;" +
"sin = math.sin;" +
"cos = math.cos;" +
"tan = math.tan;" +
"abs = math.abs;"
);
lua.DoString("function calcVP(a,b) return a+b end");
LuaFunction lf = lua.GetFunction("calcVP");
Object[] ret = lf.Call(i, 20);
}
private void TestThreading() private void TestThreading()
{ {
Init(); Init();
...@@ -1104,7 +1126,6 @@ namespace LuaInterface.Tests ...@@ -1104,7 +1126,6 @@ namespace LuaInterface.Tests
} }
catch catch
{ {
//Console.WriteLine("Failure detected");
failureDetected = true; failureDetected = true;
} }
completed++; completed++;
...@@ -1265,6 +1286,49 @@ namespace LuaInterface.Tests ...@@ -1265,6 +1286,49 @@ namespace LuaInterface.Tests
} }
public void TestExceptionWithChunkOverload()
{
Init();
try
{
_Lua.DoString("thiswillthrowanerror", "MyChunk");
}
catch(Exception e)
{
if (e.Message.StartsWith("[string \"MyChunk\"]"))
Console.WriteLine("Chunk overload passed");
else
Console.WriteLine("Chunk overload failed");
}
}
public void TestGenerics()
{
Init();
TestClassGeneric<string> genericClass = new TestClassGeneric<string>();
_Lua.RegisterFunction("genericMethod", genericClass, typeof(TestClassGeneric<>).GetMethod("GenericMethod"));
_Lua.RegisterFunction("regularMethod", genericClass, typeof(TestClassGeneric<>).GetMethod("RegularMethod"));
try
{
_Lua.DoString("genericMethod('thestring')");
}
catch { }
try
{
_Lua.DoString("regularMethod()");
}
catch { }
if (genericClass.GenericMethodSuccess && genericClass.RegularMethodSuccess)
Console.WriteLine("Generics passed");
else
Console.WriteLine("Generics failed");
}
public static int func(int x, int y) public static int func(int x, int y)
{ {
...@@ -1415,6 +1479,12 @@ namespace LuaInterface.Tests ...@@ -1415,6 +1479,12 @@ namespace LuaInterface.Tests
Console.WriteLine("Test event exceptions..."); Console.WriteLine("Test event exceptions...");
obj.TestEventException(); obj.TestEventException();
Console.WriteLine("Test chunk overload exception...");
obj.TestExceptionWithChunkOverload();
Console.WriteLine("Test generics...");
obj.TestGenerics();
Console.WriteLine("Test threading..."); Console.WriteLine("Test threading...");
obj.TestThreading(); obj.TestThreading();
......
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