Commit 4ab4bad3 authored by Megax's avatar Megax
Browse files

bridge from LuaInterface(capresti) to LuaInterface (megax) part 3

parent 6336b46a
*.obj
*.pidb
*.mdb
*/bin/*
Run/
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
UpgradeLog.XML
*.ReSharper
*.userprefs
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaInterface", "src\LuaInterface\LuaInterface.csproj", "{F55CABBB-4108-4A39-94E1-581FD46DC021}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaInterface", "LuaInterface\LuaInterface.csproj", "{F55CABBB-4108-4A39-94E1-581FD46DC021}"
ProjectSection(ProjectDependencies) = postProject
{0A82CC4C-9A27-461C-8DB0-A65AC6393748} = {0A82CC4C-9A27-461C-8DB0-A65AC6393748}
EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaRunner", "src\LuaRunner\LuaRunner.csproj", "{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaWrap", "LuaWrap\LuaWrap.csproj", "{76D7F266-456D-4A7C-916E-E35D057E5F98}"
ProjectSection(ProjectDependencies) = postProject
{0A82CC4C-9A27-461C-8DB0-A65AC6393748} = {0A82CC4C-9A27-461C-8DB0-A65AC6393748}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLuaInterface", "src\TestLuaInterface\TestLuaInterface.csproj", "{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaInterface.Test", "src\LuaInterface.Test\LuaInterface.Test.csproj", "{F97A7B76-AD92-49F9-B733-F347B7C8439F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{2EC66587-FF70-440C-9206-FA9E8FB2905A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaInterface.net35", "src\LuaInterface.net35\LuaInterface.net35.csproj", "{817FF371-DB5F-4382-8E68-F1E569D20A81}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua51", "..\lua-5.1.4\src\lua514.vcxproj", "{0A82CC4C-9A27-461C-8DB0-A65AC6393748}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{76D7F266-456D-4A7C-916E-E35D057E5F98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76D7F266-456D-4A7C-916E-E35D057E5F98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76D7F266-456D-4A7C-916E-E35D057E5F98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76D7F266-456D-4A7C-916E-E35D057E5F98}.Release|Any CPU.Build.0 = Release|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Any CPU.Build.0 = Debug|Any CPU {F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Debug|Win32.ActiveCfg = Debug|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Any CPU.ActiveCfg = Release|Any CPU {F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Any CPU.Build.0 = Release|Any CPU {F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Any CPU.Build.0 = Release|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F55CABBB-4108-4A39-94E1-581FD46DC021}.Release|Win32.ActiveCfg = Release|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Debug|Win32.ActiveCfg = Debug|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Any CPU.Build.0 = Release|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3CE4CCB6-3465-43E3-B5ED-5FB9B70D20E5}.Release|Win32.ActiveCfg = Release|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Debug|Win32.ActiveCfg = Debug|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Any CPU.Build.0 = Release|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E}.Release|Win32.ActiveCfg = Release|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Debug|Win32.ActiveCfg = Debug|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Release|Any CPU.Build.0 = Release|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F97A7B76-AD92-49F9-B733-F347B7C8439F}.Release|Win32.ActiveCfg = Release|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Debug|Win32.ActiveCfg = Debug|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Release|Any CPU.Build.0 = Release|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{817FF371-DB5F-4382-8E68-F1E569D20A81}.Release|Win32.ActiveCfg = Release|Any CPU
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Debug|Any CPU.ActiveCfg = Debug|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Debug|Win32.ActiveCfg = Debug|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Debug|Win32.Build.0 = Debug|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Release|Any CPU.ActiveCfg = Release|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Release|Mixed Platforms.Build.0 = Release|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Release|Win32.ActiveCfg = Release|Win32
{0A82CC4C-9A27-461C-8DB0-A65AC6393748}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(MonoDevelopProperties) = preSolution
{F97A7B76-AD92-49F9-B733-F347B7C8439F} = {2EC66587-FF70-440C-9206-FA9E8FB2905A} StartupItem = LuaInterface.csproj
{AEAB974E-4F69-4840-A2C4-7BC55F7C7C3E} = {2EC66587-FF70-440C-9206-FA9E8FB2905A}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
...@@ -22,7 +22,7 @@ using System.Security.Permissions; ...@@ -22,7 +22,7 @@ using System.Security.Permissions;
// You can specify all the values or you can default the Revision and Build Numbers // You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("2.0.4.*")] [assembly: AssemblyVersion("2.0.0.*")]
// //
// In order to sign your assembly you must specify a key to use. Refer to the // In order to sign your assembly you must specify a key to use. Refer to the
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using Lua511; using LuaWrap;
namespace LuaInterface namespace LuaInterface
{ {
...@@ -66,7 +66,7 @@ namespace LuaInterface ...@@ -66,7 +66,7 @@ namespace LuaInterface
internal ExtractValue checkType(IntPtr luaState,int stackPos,Type paramType) internal ExtractValue checkType(IntPtr luaState,int stackPos,Type paramType)
{ {
LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); LuaType luatype = LuaLib.lua_type(luaState, stackPos);
if(paramType.IsByRef) paramType=paramType.GetElementType(); if(paramType.IsByRef) paramType=paramType.GetElementType();
...@@ -79,76 +79,57 @@ namespace LuaInterface ...@@ -79,76 +79,57 @@ namespace LuaInterface
long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64();
if (paramType.Equals(typeof(object))) if (paramType.Equals(typeof(object)))
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
//CP: Added support for generic parameters if (LuaLib.lua_isnumber(luaState, stackPos))
if (paramType.IsGenericParameter) return extractValues[runtimeHandleValue];
{
if (luatype == LuaTypes.LUA_TBOOLEAN)
return extractValues[typeof(bool).TypeHandle.Value.ToInt64()];
else if (luatype == LuaTypes.LUA_TSTRING)
return extractValues[typeof(string).TypeHandle.Value.ToInt64()];
else if (luatype == LuaTypes.LUA_TTABLE)
return extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()];
else if (luatype == LuaTypes.LUA_TUSERDATA)
return extractValues[typeof(object).TypeHandle.Value.ToInt64()];
else if (luatype == LuaTypes.LUA_TFUNCTION)
return extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()];
else if (luatype == LuaTypes.LUA_TNUMBER)
return extractValues[typeof(double).TypeHandle.Value.ToInt64()];
else
;//an unsupported type was encountered
}
if (LuaDLL.lua_isnumber(luaState, stackPos))
return extractValues[runtimeHandleValue];
if (paramType == typeof(bool)) if (paramType == typeof(bool))
{ {
if (LuaDLL.lua_isboolean(luaState, stackPos)) if (LuaLib.lua_isboolean(luaState, stackPos))
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
} }
else if (paramType == typeof(string)) else if (paramType == typeof(string))
{ {
if (LuaDLL.lua_isstring(luaState, stackPos)) if (LuaLib.lua_isstring(luaState, stackPos))
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
else if (luatype == LuaTypes.LUA_TNIL) else if (luatype == LuaType.Nil)
return extractNetObject; // kevinh - silently convert nil to a null string pointer return extractNetObject; // kevinh - silently convert nil to a null string pointer
} }
else if (paramType == typeof(LuaTable)) else if (paramType == typeof(LuaTable))
{ {
if (luatype == LuaTypes.LUA_TTABLE) if (luatype == LuaType.Table)
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
} }
else if (paramType == typeof(LuaUserData)) else if (paramType == typeof(LuaUserData))
{ {
if (luatype == LuaTypes.LUA_TUSERDATA) if (luatype == LuaType.UserData)
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
} }
else if (paramType == typeof(LuaFunction)) else if (paramType == typeof(LuaFunction))
{ {
if (luatype == LuaTypes.LUA_TFUNCTION) if (luatype == LuaType.Function)
return extractValues[runtimeHandleValue]; return extractValues[runtimeHandleValue];
} }
else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaType.Function)
{ {
return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated);
} }
else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) else if (paramType.IsInterface && luatype == LuaType.Table)
{ {
return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated);
} }
else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaType.Nil)
{ {
// kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found
return extractNetObject; return extractNetObject;
} }
else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) else if (LuaLib.lua_type(luaState, stackPos) == LuaType.Table)
{ {
if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) if (LuaLib.luaL_getmetafield(luaState, stackPos, "__index"))
{ {
object obj = translator.getNetObject(luaState, -1); object obj = translator.getNetObject(luaState, -1);
LuaDLL.lua_settop(luaState, -2); LuaLib.lua_settop(luaState, -2);
if (obj != null && paramType.IsAssignableFrom(obj.GetType())) if (obj != null && paramType.IsAssignableFrom(obj.GetType()))
return extractNetObject; return extractNetObject;
} }
...@@ -172,84 +153,84 @@ namespace LuaInterface ...@@ -172,84 +153,84 @@ namespace LuaInterface
*/ */
private object getAsSbyte(IntPtr luaState,int stackPos) private object getAsSbyte(IntPtr luaState,int stackPos)
{ {
sbyte retVal=(sbyte)LuaDLL.lua_tonumber(luaState,stackPos); sbyte retVal=(sbyte)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsByte(IntPtr luaState,int stackPos) private object getAsByte(IntPtr luaState,int stackPos)
{ {
byte retVal=(byte)LuaDLL.lua_tonumber(luaState,stackPos); byte retVal=(byte)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsShort(IntPtr luaState,int stackPos) private object getAsShort(IntPtr luaState,int stackPos)
{ {
short retVal=(short)LuaDLL.lua_tonumber(luaState,stackPos); short retVal=(short)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsUshort(IntPtr luaState,int stackPos) private object getAsUshort(IntPtr luaState,int stackPos)
{ {
ushort retVal=(ushort)LuaDLL.lua_tonumber(luaState,stackPos); ushort retVal=(ushort)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsInt(IntPtr luaState,int stackPos) private object getAsInt(IntPtr luaState,int stackPos)
{ {
int retVal=(int)LuaDLL.lua_tonumber(luaState,stackPos); int retVal=(int)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsUint(IntPtr luaState,int stackPos) private object getAsUint(IntPtr luaState,int stackPos)
{ {
uint retVal=(uint)LuaDLL.lua_tonumber(luaState,stackPos); uint retVal=(uint)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsLong(IntPtr luaState,int stackPos) private object getAsLong(IntPtr luaState,int stackPos)
{ {
long retVal=(long)LuaDLL.lua_tonumber(luaState,stackPos); long retVal=(long)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsUlong(IntPtr luaState,int stackPos) private object getAsUlong(IntPtr luaState,int stackPos)
{ {
ulong retVal=(ulong)LuaDLL.lua_tonumber(luaState,stackPos); ulong retVal=(ulong)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsDouble(IntPtr luaState,int stackPos) private object getAsDouble(IntPtr luaState,int stackPos)
{ {
double retVal=LuaDLL.lua_tonumber(luaState,stackPos); double retVal=LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsChar(IntPtr luaState,int stackPos) private object getAsChar(IntPtr luaState,int stackPos)
{ {
char retVal=(char)LuaDLL.lua_tonumber(luaState,stackPos); char retVal=(char)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsFloat(IntPtr luaState,int stackPos) private object getAsFloat(IntPtr luaState,int stackPos)
{ {
float retVal=(float)LuaDLL.lua_tonumber(luaState,stackPos); float retVal=(float)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsDecimal(IntPtr luaState,int stackPos) private object getAsDecimal(IntPtr luaState,int stackPos)
{ {
decimal retVal=(decimal)LuaDLL.lua_tonumber(luaState,stackPos); decimal retVal=(decimal)LuaLib.lua_tonumber(luaState,stackPos);
if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; if(retVal==0 && !LuaLib.lua_isnumber(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsBoolean(IntPtr luaState,int stackPos) private object getAsBoolean(IntPtr luaState,int stackPos)
{ {
return LuaDLL.lua_toboolean(luaState,stackPos); return LuaLib.lua_toboolean(luaState,stackPos);
} }
private object getAsString(IntPtr luaState,int stackPos) private object getAsString(IntPtr luaState,int stackPos)
{ {
string retVal=LuaDLL.lua_tostring(luaState,stackPos); string retVal=LuaLib.lua_tostring(luaState,stackPos);
if(retVal=="" && !LuaDLL.lua_isstring(luaState,stackPos)) return null; if(retVal=="" && !LuaLib.lua_isstring(luaState,stackPos)) return null;
return retVal; return retVal;
} }
private object getAsTable(IntPtr luaState,int stackPos) private object getAsTable(IntPtr luaState,int stackPos)
...@@ -266,18 +247,18 @@ namespace LuaInterface ...@@ -266,18 +247,18 @@ namespace LuaInterface
} }
public object getAsObject(IntPtr luaState,int stackPos) public object getAsObject(IntPtr luaState,int stackPos)
{ {
if(LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) if(LuaLib.lua_type(luaState,stackPos)==LuaType.Table)
{ {
if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) if(LuaLib.luaL_getmetafield(luaState,stackPos,"__index"))
{ {
if(LuaDLL.luaL_checkmetatable(luaState,-1)) if(LuaLib.luaL_checkmetatable(luaState,-1))
{ {
LuaDLL.lua_insert(luaState,stackPos); LuaLib.lua_insert(luaState,stackPos);
LuaDLL.lua_remove(luaState,stackPos+1); LuaLib.lua_remove(luaState,stackPos+1);
} }
else else
{ {
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
} }
} }
} }
...@@ -287,19 +268,19 @@ namespace LuaInterface ...@@ -287,19 +268,19 @@ namespace LuaInterface
public object getAsNetObject(IntPtr luaState,int stackPos) public object getAsNetObject(IntPtr luaState,int stackPos)
{ {
object obj=translator.getNetObject(luaState,stackPos); object obj=translator.getNetObject(luaState,stackPos);
if(obj==null && LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) if(obj==null && LuaLib.lua_type(luaState,stackPos)==LuaType.Table)
{ {
if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) if(LuaLib.luaL_getmetafield(luaState,stackPos,"__index"))
{ {
if(LuaDLL.luaL_checkmetatable(luaState,-1)) if(LuaLib.luaL_checkmetatable(luaState,-1))
{ {
LuaDLL.lua_insert(luaState,stackPos); LuaLib.lua_insert(luaState,stackPos);
LuaDLL.lua_remove(luaState,stackPos+1); LuaLib.lua_remove(luaState,stackPos+1);
obj=translator.getNetObject(luaState,stackPos); obj=translator.getNetObject(luaState,stackPos);
} }
else else
{ {
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
} }
} }
} }
......
namespace LuaInterface namespace LuaInterface
{ {
using System; using System;
using System.IO; using System.IO;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using Lua511; using LuaWrap;
/* /*
* Main class of LuaInterface * Main class of LuaInterface
...@@ -21,8 +21,7 @@ namespace LuaInterface ...@@ -21,8 +21,7 @@ namespace LuaInterface
* - removed all Open*Lib() functions * - removed all Open*Lib() functions
* - all libs automatically open in the Lua class constructor (just assign nil to unwanted libs) * - all libs automatically open in the Lua class constructor (just assign nil to unwanted libs)
* */ * */
[CLSCompliant(true)] public class Lua : IDisposable
public class Lua : IDisposable
{ {
static string init_luanet = static string init_luanet =
...@@ -65,10 +64,10 @@ namespace LuaInterface ...@@ -65,10 +64,10 @@ namespace LuaInterface
"-- Preload the mscorlib assembly \n"+ "-- Preload the mscorlib assembly \n"+
"luanet.load_assembly(\"mscorlib\") \n"; "luanet.load_assembly(\"mscorlib\") \n";
/*readonly */ IntPtr luaState; readonly IntPtr luaState;
ObjectTranslator translator; ObjectTranslator translator;
LuaCSFunction panicCallback, lockCallback, unlockCallback; CallbackFunction panicCallback, lockCallback, unlockCallback;
/// <summary> /// <summary>
/// Used to ensure multiple .net threads all get serialized by this single lock for access to the lua stack/objects /// Used to ensure multiple .net threads all get serialized by this single lock for access to the lua stack/objects
...@@ -77,67 +76,59 @@ namespace LuaInterface ...@@ -77,67 +76,59 @@ namespace LuaInterface
public Lua() public Lua()
{ {
luaState = LuaDLL.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone) luaState = LuaLib.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone)
//LuaDLL.luaopen_base(luaState); // steffenj: luaopen_* no longer used //LuaLib.luaopen_base(luaState); // steffenj: luaopen_* no longer used
LuaDLL.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here) LuaLib.luaL_openlibs(luaState); // steffenj: Lua 5.1.1 API change (luaopen_base is gone, just open all libs right here)
LuaDLL.lua_pushstring(luaState, "LUAINTERFACE LOADED"); LuaLib.lua_pushstring(luaState, "LUAINTERFACE LOADED");
LuaDLL.lua_pushboolean(luaState, true); LuaLib.lua_pushboolean(luaState, true);
LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_settable(luaState, (int) PseudoIndex.Registry);
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_setglobal(luaState, "luanet"); LuaLib.lua_setglobal(luaState, "luanet");
LuaDLL.lua_pushvalue(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaLib.lua_pushvalue(luaState, (int)PseudoIndex.Globals);
LuaDLL.lua_getglobal(luaState, "luanet"); LuaLib.lua_getglobal(luaState, "luanet");
LuaDLL.lua_pushstring(luaState, "getmetatable"); LuaLib.lua_pushstring(luaState, "getmetatable");
LuaDLL.lua_getglobal(luaState, "getmetatable"); LuaLib.lua_getglobal(luaState, "getmetatable");
LuaDLL.lua_settable(luaState, -3); LuaLib.lua_settable(luaState, -3);
LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaLib.lua_replace(luaState, (int)PseudoIndex.Globals);
translator=new ObjectTranslator(this,luaState); translator=new ObjectTranslator(this,luaState);
LuaDLL.lua_replace(luaState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaLib.lua_replace(luaState, (int)PseudoIndex.Globals);
LuaDLL.luaL_dostring(luaState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring 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 // We need to keep this in a managed reference so the delegate doesn't get garbage collected
panicCallback = new LuaCSFunction(PanicCallback); panicCallback = new CallbackFunction(PanicCallback);
LuaDLL.lua_atpanic(luaState, panicCallback); LuaLib.lua_atpanic(luaState, panicCallback);
//LuaDLL.lua_atlock(luaState, lockCallback = new LuaCSFunction(LockCallback)); // LuaLib.lua_atlock(luaState, lockCallback = new CallbackFunction(LockCallback));
//LuaDLL.lua_atunlock(luaState, unlockCallback = new LuaCSFunction(UnlockCallback)); // LuaLib.lua_atunlock(luaState, unlockCallback = new CallbackFunction(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"); LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_gettable(lState, (int)PseudoIndex.Registry);
if(LuaLib.lua_toboolean(lState,-1)) {
if(LuaDLL.lua_toboolean(lState,-1)) LuaLib.lua_settop(lState,-2);
{ throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state");
LuaDLL.lua_settop(lState,-2); } else {
throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state"); LuaLib.lua_settop(lState,-2);
} LuaLib.lua_pushstring(lState, "LUAINTERFACE LOADED");
else LuaLib.lua_pushboolean(lState, true);
{ LuaLib.lua_settable(lState, (int)PseudoIndex.Registry);
LuaDLL.lua_settop(lState,-2); this.luaState=lState;
LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); LuaLib.lua_pushvalue(lState, (int)PseudoIndex.Globals);
LuaDLL.lua_pushboolean(lState, true); LuaLib.lua_getglobal(lState, "luanet");
LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_pushstring(lState, "getmetatable");
this.luaState=lState; LuaLib.lua_getglobal(lState, "getmetatable");
LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); LuaLib.lua_settable(lState, -3);
LuaDLL.lua_getglobal(lState, "luanet"); LuaLib.lua_replace(lState, (int)PseudoIndex.Globals);
LuaDLL.lua_pushstring(lState, "getmetatable"); translator=new ObjectTranslator(this, this.luaState);
LuaDLL.lua_getglobal(lState, "getmetatable"); LuaLib.lua_replace(lState, (int)PseudoIndex.Globals);
LuaDLL.lua_settable(lState, -3); LuaLib.luaL_dostring(lState, Lua.init_luanet); // steffenj: lua_dostring renamed to luaL_dostring
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
}
_StatePassed = true;
} }
/// <summary> /// <summary>
...@@ -164,20 +155,10 @@ namespace LuaInterface ...@@ -164,20 +155,10 @@ namespace LuaInterface
return 0; return 0;
} }
public void Close()
{
if (_StatePassed)
return;
if (luaState != IntPtr.Zero)
LuaDLL.lua_close(luaState);
//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)
{ {
// string desc = LuaDLL.lua_tostring(luaState, 1); // string desc = LuaLib.lua_tostring(luaState, 1);
string reason = String.Format("unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(luaState, -1)); string reason = String.Format("unprotected error in call to Lua API ({0})", LuaLib.lua_tostring(luaState, -1));
// lua_tostring(L, -1); // lua_tostring(L, -1);
...@@ -189,19 +170,24 @@ namespace LuaInterface ...@@ -189,19 +170,24 @@ namespace LuaInterface
/// <summary> /// <summary>
/// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
/// </summary> /// </summary>
/// <exception cref="LuaScriptException">Thrown if the script caused an exception</exception>
void ThrowExceptionFromError(int oldTop) void ThrowExceptionFromError(int oldTop)
{ {
object err = translator.getObject(luaState, -1); object err = translator.getObject(luaState, -1);
LuaDLL.lua_settop(luaState, oldTop); LuaLib.lua_settop(luaState, oldTop);
// A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved) // If the 'error' on the stack is an actual C# exception, just rethrow it. Otherwise the value must have started
LuaScriptException luaEx = err as LuaScriptException; // as a true Lua error and is best interpreted as a string - wrap it in a LuaException and rethrow.
if (luaEx != null) throw luaEx; Exception thrown = err as Exception;
// A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it if (thrown == null)
if (err == null) err = "Unknown Lua Error"; {
throw new LuaScriptException(err.ToString(), ""); if (err == null)
err = "Unknown Lua Error";
thrown = new LuaException(err.ToString());
}
throw thrown;
} }
...@@ -218,7 +204,7 @@ namespace LuaInterface ...@@ -218,7 +204,7 @@ namespace LuaInterface
if (caughtExcept != null) if (caughtExcept != null)
{ {
translator.throwError(luaState, caughtExcept); translator.throwError(luaState, caughtExcept);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
...@@ -226,54 +212,6 @@ namespace LuaInterface ...@@ -226,54 +212,6 @@ namespace LuaInterface
return 0; return 0;
} }
private bool executing;
/// <summary>
/// True while a script is being executed
/// </summary>
public bool IsExecuting { get { return executing; } }
/// <summary>
///
/// </summary>
/// <param name="chunk"></param>
/// <param name="name"></param>
/// <returns></returns>
public LuaFunction LoadString(string chunk, string name)
{
int oldTop = LuaDLL.lua_gettop(luaState);
executing = true;
try
{
if (LuaDLL.luaL_loadbuffer(luaState, chunk, name) != 0)
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
LuaFunction result = translator.getFunction(luaState, -1);
translator.popValues(luaState, oldTop);
return result;
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public LuaFunction LoadFile(string fileName)
{
int oldTop = LuaDLL.lua_gettop(luaState);
if (LuaDLL.luaL_loadfile(luaState, fileName) != 0)
ThrowExceptionFromError(oldTop);
LuaFunction result = translator.getFunction(luaState, -1);
translator.popValues(luaState, oldTop);
return result;
}
/* /*
* Excutes a Lua chunk and returns all the chunk's return * Excutes a Lua chunk and returns all the chunk's return
...@@ -281,70 +219,32 @@ namespace LuaInterface ...@@ -281,70 +219,32 @@ namespace LuaInterface
*/ */
public object[] DoString(string chunk) public object[] DoString(string chunk)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
if (LuaDLL.luaL_loadbuffer(luaState, chunk, "chunk") == 0) if(LuaLib.luaL_loadbuffer(luaState,chunk,"chunk")== LuaEnum.Ok)
{ {
executing = true; if (LuaLib.lua_pcall(luaState, 0, -1, 0) == 0)
try return translator.popValues(luaState, oldTop);
{ else
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0) ThrowExceptionFromError(oldTop);
return translator.popValues(luaState, oldTop); }
else else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
}
else
ThrowExceptionFromError(oldTop); ThrowExceptionFromError(oldTop);
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);
executing = true;
if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunkName) == 0)
{
try
{
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0)
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
}
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
*/ */
public object[] DoFile(string fileName) public object[] DoFile(string fileName)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
if(LuaDLL.luaL_loadfile(luaState,fileName)==0) if(LuaLib.luaL_loadfile(luaState,fileName)==0)
{ {
executing = true; if (LuaLib.lua_pcall(luaState, 0, -1, 0) == 0)
try return translator.popValues(luaState, oldTop);
{ else
if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0) ThrowExceptionFromError(oldTop);
return translator.popValues(luaState, oldTop);
else
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
} }
else else
ThrowExceptionFromError(oldTop); ThrowExceptionFromError(oldTop);
...@@ -362,9 +262,9 @@ namespace LuaInterface ...@@ -362,9 +262,9 @@ namespace LuaInterface
get get
{ {
object returnValue=null; object returnValue=null;
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
string[] path=fullPath.Split(new char[] { '.' }); string[] path=fullPath.Split(new char[] { '.' });
LuaDLL.lua_getglobal(luaState,path[0]); LuaLib.lua_getglobal(luaState,path[0]);
returnValue=translator.getObject(luaState,-1); returnValue=translator.getObject(luaState,-1);
if(path.Length>1) if(path.Length>1)
{ {
...@@ -372,144 +272,28 @@ namespace LuaInterface ...@@ -372,144 +272,28 @@ namespace LuaInterface
Array.Copy(path,1,remainingPath,0,path.Length-1); Array.Copy(path,1,remainingPath,0,path.Length-1);
returnValue=getObject(remainingPath); returnValue=getObject(remainingPath);
} }
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return returnValue; return returnValue;
} }
set set
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
string[] path=fullPath.Split(new char[] { '.' }); string[] path=fullPath.Split(new char[] { '.' });
if(path.Length==1) if(path.Length==1)
{ {
translator.push(luaState,value); translator.push(luaState,value);
LuaDLL.lua_setglobal(luaState,fullPath); LuaLib.lua_setglobal(luaState,fullPath);
} }
else else
{ {
LuaDLL.lua_getglobal(luaState,path[0]); LuaLib.lua_getglobal(luaState,path[0]);
string[] remainingPath=new string[path.Length-1]; string[] remainingPath=new string[path.Length-1];
Array.Copy(path,1,remainingPath,0,path.Length-1); Array.Copy(path,1,remainingPath,0,path.Length-1);
setObject(remainingPath,value); setObject(remainingPath,value);
} }
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
}
// Globals auto-complete
if (value == null)
{
// Remove now obsolete entries
globals.Remove(fullPath);
}
else
{
// Add new entries
if (!globals.Contains(fullPath))
registerGlobal(fullPath, value.GetType(), 0);
}
}
} }
#region Globals auto-complete
private readonly List<string> globals = new List<string>();
private bool globalsSorted;
/// <summary>
/// An alphabetically sorted list of all globals (objects, methods, etc.) externally added to this Lua instance
/// </summary>
/// <remarks>Members of globals are also listed. The formatting is optimized for text input auto-completion.</remarks>
public IEnumerable<string> Globals
{
get
{
// Only sort list when necessary
if (!globalsSorted)
{
globals.Sort();
globalsSorted = true;
}
return globals;
}
}
/// <summary>
/// Adds an entry to <see cref="globals"/> (recursivley handles 2 levels of members)
/// </summary>
/// <param name="path">The index accessor path ot the entry</param>
/// <param name="type">The type of the entry</param>
/// <param name="recursionCounter">How deep have we gone with recursion?</param>
private void registerGlobal(string path, Type type, int recursionCounter)
{
// If the type is a global method, list it directly
if (type == typeof(LuaCSFunction))
{
// Format for easy method invocation
globals.Add(path + "(");
}
// If the type is a class or an interface and recursion hasn't been running too long, list the members
else if ((type.IsClass || type.IsInterface) && type != typeof(string) && recursionCounter < 2)
{
#region Methods
foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
if (
// Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
(method.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
(method.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) &&
// Exclude some generic .NET methods that wouldn't be very usefull in Lua
method.Name != "GetType" && method.Name != "GetHashCode" && method.Name != "Equals" &&
method.Name != "ToString" && method.Name != "Clone" && method.Name != "Dispose" &&
method.Name != "GetEnumerator" && method.Name != "CopyTo" &&
!method.Name.StartsWith("get_", StringComparison.Ordinal) &&
!method.Name.StartsWith("set_", StringComparison.Ordinal) &&
!method.Name.StartsWith("add_", StringComparison.Ordinal) &&
!method.Name.StartsWith("remove_", StringComparison.Ordinal))
{
// Format for easy method invocation
string command = path + ":" + method.Name + "(";
if (method.GetParameters().Length == 0) command += ")";
globals.Add(command);
}
}
#endregion
#region Fields
foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance))
{
if (
// Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
(field.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
(field.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0))
{
// Go into recursion for members
registerGlobal(path + "." + field.Name, field.FieldType, recursionCounter + 1);
}
}
#endregion
#region Properties
foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (
// Check that the LuaHideAttribute and LuaGlobalAttribute were not applied
(property.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) &&
(property.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0)
// Exclude some generic .NET properties that wouldn't be very usefull in Lua
&& property.Name != "Item")
{
// Go into recursion for members
registerGlobal(path + "." + property.Name, property.PropertyType, recursionCounter + 1);
}
}
#endregion
}
// Otherwise simply add the element to the list
else globals.Add(path);
// List will need to be sorted on next access
globalsSorted = false;
}
#endregion
/* /*
* Navigates a table in the top of the stack, returning * Navigates a table in the top of the stack, returning
* the value of the specified field * the value of the specified field
...@@ -519,8 +303,8 @@ namespace LuaInterface ...@@ -519,8 +303,8 @@ namespace LuaInterface
object returnValue=null; object returnValue=null;
for(int i=0;i<remainingPath.Length;i++) for(int i=0;i<remainingPath.Length;i++)
{ {
LuaDLL.lua_pushstring(luaState,remainingPath[i]); LuaLib.lua_pushstring(luaState,remainingPath[i]);
LuaDLL.lua_gettable(luaState,-2); LuaLib.lua_gettable(luaState,-2);
returnValue=translator.getObject(luaState,-1); returnValue=translator.getObject(luaState,-1);
if(returnValue==null) break; if(returnValue==null) break;
} }
...@@ -561,7 +345,7 @@ namespace LuaInterface ...@@ -561,7 +345,7 @@ namespace LuaInterface
public LuaFunction GetFunction(string fullPath) public LuaFunction GetFunction(string fullPath)
{ {
object obj=this[fullPath]; object obj=this[fullPath];
return (obj is LuaCSFunction ? new LuaFunction((LuaCSFunction)obj,this) : (LuaFunction)obj); return (obj is CallbackFunction ? new LuaFunction((CallbackFunction)obj,this) : (LuaFunction)obj);
} }
/* /*
* Gets a function global variable as a delegate of * Gets a function global variable as a delegate of
...@@ -589,8 +373,8 @@ namespace LuaInterface ...@@ -589,8 +373,8 @@ namespace LuaInterface
internal object[] callFunction(object function,object[] args,Type[] returnTypes) internal object[] callFunction(object function,object[] args,Type[] returnTypes)
{ {
int nArgs=0; int nArgs=0;
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
if(!LuaDLL.lua_checkstack(luaState,args.Length+6)) if(!LuaLib.lua_checkstack(luaState,args.Length+6))
throw new LuaException("Lua stack overflow"); throw new LuaException("Lua stack overflow");
translator.push(luaState,function); translator.push(luaState,function);
if(args!=null) if(args!=null)
...@@ -600,15 +384,10 @@ namespace LuaInterface ...@@ -600,15 +384,10 @@ namespace LuaInterface
{ {
translator.push(luaState,args[i]); translator.push(luaState,args[i]);
} }
} }
executing = true; LuaEnum error = LuaLib.lua_pcall(luaState, nArgs, -1, 0);
try if (error != LuaEnum.Ok)
{ ThrowExceptionFromError(oldTop);
int error = LuaDLL.lua_pcall(luaState, nArgs, -1, 0);
if (error != 0)
ThrowExceptionFromError(oldTop);
}
finally { executing = false; }
if(returnTypes != null) if(returnTypes != null)
return translator.popValues(luaState,oldTop,returnTypes); return translator.popValues(luaState,oldTop,returnTypes);
...@@ -622,12 +401,12 @@ namespace LuaInterface ...@@ -622,12 +401,12 @@ namespace LuaInterface
{ {
for(int i=0; i<remainingPath.Length-1;i++) for(int i=0; i<remainingPath.Length-1;i++)
{ {
LuaDLL.lua_pushstring(luaState,remainingPath[i]); LuaLib.lua_pushstring(luaState,remainingPath[i]);
LuaDLL.lua_gettable(luaState,-2); LuaLib.lua_gettable(luaState,-2);
} }
LuaDLL.lua_pushstring(luaState,remainingPath[remainingPath.Length-1]); LuaLib.lua_pushstring(luaState,remainingPath[remainingPath.Length-1]);
translator.push(luaState,val); translator.push(luaState,val);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
} }
/* /*
* Creates a new table as a global variable or as a field * Creates a new table as a global variable or as a field
...@@ -636,40 +415,42 @@ namespace LuaInterface ...@@ -636,40 +415,42 @@ namespace LuaInterface
public void NewTable(string fullPath) public void NewTable(string fullPath)
{ {
string[] path=fullPath.Split(new char[] { '.' }); string[] path=fullPath.Split(new char[] { '.' });
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
if(path.Length==1) if(path.Length==1)
{ {
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_setglobal(luaState,fullPath); LuaLib.lua_setglobal(luaState,fullPath);
} }
else else
{ {
LuaDLL.lua_getglobal(luaState,path[0]); LuaLib.lua_getglobal(luaState,path[0]);
for(int i=1; i<path.Length-1;i++) for(int i=1; i<path.Length-1;i++)
{ {
LuaDLL.lua_pushstring(luaState,path[i]); LuaLib.lua_pushstring(luaState,path[i]);
LuaDLL.lua_gettable(luaState,-2); LuaLib.lua_gettable(luaState,-2);
} }
LuaDLL.lua_pushstring(luaState,path[path.Length-1]); LuaLib.lua_pushstring(luaState,path[path.Length-1]);
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
} }
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
} }
public ListDictionary GetTableDict(LuaTable table) public ListDictionary GetTableDict(LuaTable table)
{ {
ListDictionary dict = new ListDictionary(); ListDictionary dict = new ListDictionary();
int oldTop = LuaDLL.lua_gettop(luaState); int oldTop = LuaLib.lua_gettop(luaState);
translator.push(luaState, table); translator.push(luaState, table);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
while (LuaDLL.lua_next(luaState, -2) != 0) // nem biztos hogy jóóóó
//while (LuaLib.lua_next(luaState, -2) != 0)
while (!LuaLib.lua_next(luaState, -2))
{ {
dict[translator.getObject(luaState, -2)] = translator.getObject(luaState, -1); dict[translator.getObject(luaState, -2)] = translator.getObject(luaState, -1);
LuaDLL.lua_settop(luaState, -2); LuaLib.lua_settop(luaState, -2);
} }
LuaDLL.lua_settop(luaState, oldTop); LuaLib.lua_settop(luaState, oldTop);
return dict; return dict;
} }
...@@ -678,247 +459,9 @@ namespace LuaInterface ...@@ -678,247 +459,9 @@ namespace LuaInterface
* Lets go of a previously allocated reference to a table, function * Lets go of a previously allocated reference to a table, function
* or userdata * or userdata
*/ */
#region lua debug functions
/// <summary>
/// lua hook calback delegate
/// </summary>
/// <author>Reinhard Ostermeier</author>
private LuaHookFunction hookCallback = null;
/// <summary>
/// Activates the debug hook
/// </summary>
/// <param name="mask">Mask</param>
/// <param name="count">Count</param>
/// <returns>see lua docs. -1 if hook is already set</returns>
/// <author>Reinhard Ostermeier</author>
public int SetDebugHook(EventMasks mask, int count)
{
if (hookCallback == null)
{
hookCallback = new LuaHookFunction(DebugHookCallback);
return LuaDLL.lua_sethook(luaState, hookCallback, (int)mask, count);
}
return -1;
}
/// <summary>
/// Removes the debug hook
/// </summary>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public int RemoveDebugHook()
{
hookCallback = null;
return LuaDLL.lua_sethook(luaState, null, 0, 0);
}
/// <summary>
/// Gets the hook mask.
/// </summary>
/// <returns>hook mask</returns>
/// <author>Reinhard Ostermeier</author>
public EventMasks GetHookMask()
{
return (EventMasks)LuaDLL.lua_gethookmask(luaState);
}
/// <summary>
/// Gets the hook count
/// </summary>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public int GetHookCount()
{
return LuaDLL.lua_gethookcount(luaState);
}
/// <summary>
/// Gets the stack entry on a given level
/// </summary>
/// <param name="level">level</param>
/// <param name="luaDebug">lua debug structure</param>
/// <returns>Returns true if level was allowed, false if level was invalid.</returns>
/// <author>Reinhard Ostermeier</author>
public bool GetStack(int level, out LuaDebug luaDebug)
{
luaDebug = new LuaDebug();
IntPtr ld = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(luaDebug));
System.Runtime.InteropServices.Marshal.StructureToPtr(luaDebug, ld, false);
try
{
return LuaDLL.lua_getstack(luaState, level, ld) != 0;
}
finally
{
luaDebug = (LuaDebug)System.Runtime.InteropServices.Marshal.PtrToStructure(ld, typeof(LuaDebug));
System.Runtime.InteropServices.Marshal.FreeHGlobal(ld);
}
}
/// <summary>
/// Gets info (see lua docs)
/// </summary>
/// <param name="what">what (see lua docs)</param>
/// <param name="luaDebug">lua debug structure</param>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public int GetInfo(String what, ref LuaDebug luaDebug)
{
IntPtr ld = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(luaDebug));
System.Runtime.InteropServices.Marshal.StructureToPtr(luaDebug, ld, false);
try
{
return LuaDLL.lua_getinfo(luaState, what, ld);
}
finally
{
luaDebug = (LuaDebug)System.Runtime.InteropServices.Marshal.PtrToStructure(ld, typeof(LuaDebug));
System.Runtime.InteropServices.Marshal.FreeHGlobal(ld);
}
}
/// <summary>
/// Gets local (see lua docs)
/// </summary>
/// <param name="luaDebug">lua debug structure</param>
/// <param name="n">see lua docs</param>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public String GetLocal(LuaDebug luaDebug, int n)
{
IntPtr ld = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(luaDebug));
System.Runtime.InteropServices.Marshal.StructureToPtr(luaDebug, ld, false);
try
{
return LuaDLL.lua_getlocal(luaState, ld, n);
}
finally
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(ld);
}
}
/// <summary>
/// Sets local (see lua docs)
/// </summary>
/// <param name="luaDebug">lua debug structure</param>
/// <param name="n">see lua docs</param>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public String SetLocal(LuaDebug luaDebug, int n)
{
IntPtr ld = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(luaDebug));
System.Runtime.InteropServices.Marshal.StructureToPtr(luaDebug, ld, false);
try
{
return LuaDLL.lua_setlocal(luaState, ld, n);
}
finally
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(ld);
}
}
/// <summary>
/// Gets up value (see lua docs)
/// </summary>
/// <param name="funcindex">see lua docs</param>
/// <param name="n">see lua docs</param>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public String GetUpValue(int funcindex, int n)
{
return LuaDLL.lua_getupvalue(luaState, funcindex, n);
}
/// <summary>
/// Sets up value (see lua docs)
/// </summary>
/// <param name="funcindex">see lua docs</param>
/// <param name="n">see lua docs</param>
/// <returns>see lua docs</returns>
/// <author>Reinhard Ostermeier</author>
public String SetUpValue(int funcindex, int n)
{
return LuaDLL.lua_setupvalue(luaState, funcindex, n);
}
/// <summary>
/// Delegate that is called on lua hook callback
/// </summary>
/// <param name="luaState">lua state</param>
/// <param name="luaDebug">Pointer to LuaDebug (lua_debug) structure</param>
/// <author>Reinhard Ostermeier</author>
private void DebugHookCallback(IntPtr luaState, IntPtr luaDebug)
{
try
{
LuaDebug ld = (LuaDebug)System.Runtime.InteropServices.Marshal.PtrToStructure(luaDebug, typeof(LuaDebug));
EventHandler<DebugHookEventArgs> temp = DebugHook;
if (temp != null)
{
temp(this, new DebugHookEventArgs(ld));
}
}
catch (Exception ex)
{
OnHookException(new HookExceptionEventArgs(ex));
}
}
/// <summary>
/// Event that is raised when an exception occures during a hook call.
/// </summary>
/// <author>Reinhard Ostermeier</author>
public event EventHandler<HookExceptionEventArgs> HookException;
private void OnHookException(HookExceptionEventArgs e)
{
EventHandler<HookExceptionEventArgs> temp = HookException;
if (temp != null)
{
temp(this, e);
}
}
/// <summary>
/// Event when lua hook callback is called
/// </summary>
/// <remarks>
/// Is only raised if SetDebugHook is called before.
/// </remarks>
/// <author>Reinhard Ostermeier</author>
public event EventHandler<DebugHookEventArgs> DebugHook;
/// <summary>
/// Pops a value from the lua stack.
/// </summary>
/// <returns>Returns the top value from the lua stack.</returns>
/// <author>Reinhard Ostermeier</author>
public object Pop()
{
int top = Lua511.LuaDLL.lua_gettop(luaState);
return translator.popValues(luaState, top - 1)[0];
}
/// <summary>
/// Pushes a value onto the lua stack.
/// </summary>
/// <param name="value">Value to push.</param>
/// <author>Reinhard Ostermeier</author>
public void Push(object value)
{
translator.push(luaState, value);
}
#endregion
internal void dispose(int reference) internal void dispose(int reference)
{ {
if (luaState != IntPtr.Zero) //Fix submitted by Qingrui Li LuaLib.lua_unref(luaState,reference);
LuaDLL.lua_unref(luaState,reference);
} }
/* /*
* Gets a field of the table corresponding to the provided reference * Gets a field of the table corresponding to the provided reference
...@@ -926,12 +469,12 @@ namespace LuaInterface ...@@ -926,12 +469,12 @@ namespace LuaInterface
*/ */
internal object rawGetObject(int reference,string field) internal object rawGetObject(int reference,string field)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,reference); LuaLib.lua_getref(luaState,reference);
LuaDLL.lua_pushstring(luaState,field); LuaLib.lua_pushstring(luaState,field);
LuaDLL.lua_rawget(luaState,-2); LuaLib.lua_rawget(luaState,-2);
object obj=translator.getObject(luaState,-1); object obj=translator.getObject(luaState,-1);
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return obj; return obj;
} }
/* /*
...@@ -939,10 +482,10 @@ namespace LuaInterface ...@@ -939,10 +482,10 @@ namespace LuaInterface
*/ */
internal object getObject(int reference,string field) internal object getObject(int reference,string field)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,reference); LuaLib.lua_getref(luaState,reference);
object returnValue=getObject(field.Split(new char[] {'.'})); object returnValue=getObject(field.Split(new char[] {'.'}));
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return returnValue; return returnValue;
} }
/* /*
...@@ -950,12 +493,12 @@ namespace LuaInterface ...@@ -950,12 +493,12 @@ namespace LuaInterface
*/ */
internal object getObject(int reference,object field) internal object getObject(int reference,object field)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,reference); LuaLib.lua_getref(luaState,reference);
translator.push(luaState,field); translator.push(luaState,field);
LuaDLL.lua_gettable(luaState,-2); LuaLib.lua_gettable(luaState,-2);
object returnValue=translator.getObject(luaState,-1); object returnValue=translator.getObject(luaState,-1);
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return returnValue; return returnValue;
} }
/* /*
...@@ -964,10 +507,10 @@ namespace LuaInterface ...@@ -964,10 +507,10 @@ namespace LuaInterface
*/ */
internal void setObject(int reference, string field, object val) internal void setObject(int reference, string field, object val)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,reference); LuaLib.lua_getref(luaState,reference);
setObject(field.Split(new char[] {'.'}),val); setObject(field.Split(new char[] {'.'}),val);
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
} }
/* /*
* Sets a numeric field of the table or userdata corresponding the the provided reference * Sets a numeric field of the table or userdata corresponding the the provided reference
...@@ -975,30 +518,30 @@ namespace LuaInterface ...@@ -975,30 +518,30 @@ namespace LuaInterface
*/ */
internal void setObject(int reference, object field, object val) internal void setObject(int reference, object field, object val)
{ {
int oldTop=LuaDLL.lua_gettop(luaState); int oldTop=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,reference); LuaLib.lua_getref(luaState,reference);
translator.push(luaState,field); translator.push(luaState,field);
translator.push(luaState,val); translator.push(luaState,val);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
} }
/* /*
* Registers an object's method as a Lua function (global or table field) * Registers an object's method as a Lua function (global or table field)
* The method may have any signature * The method may have any signature
*/ */
public LuaFunction RegisterFunction(string path, object target, MethodBase function /*MethodInfo function*/) //CP: Fix for struct constructor by Alexander Kappner (link: http://luaforge.net/forum/forum.php?thread_id=2859&forum_id=145) public LuaFunction RegisterFunction(string path, object target,MethodInfo function)
{ {
// We leave nothing on the stack when we are done // We leave nothing on the stack when we are done
int oldTop = LuaDLL.lua_gettop(luaState); int oldTop = LuaLib.lua_gettop(luaState);
LuaMethodWrapper wrapper=new LuaMethodWrapper(translator,target,function.DeclaringType,function); LuaMethodWrapper wrapper=new LuaMethodWrapper(translator,target,function.DeclaringType,function);
translator.push(luaState,new LuaCSFunction(wrapper.call)); translator.push(luaState,new CallbackFunction(wrapper.call));
this[path]=translator.getObject(luaState,-1); this[path]=translator.getObject(luaState,-1);
LuaFunction f = GetFunction(path); LuaFunction f = GetFunction(path);
LuaDLL.lua_settop(luaState, oldTop); LuaLib.lua_settop(luaState, oldTop);
return f; return f;
} }
...@@ -1009,15 +552,15 @@ namespace LuaInterface ...@@ -1009,15 +552,15 @@ namespace LuaInterface
*/ */
internal bool compareRef(int ref1, int ref2) internal bool compareRef(int ref1, int ref2)
{ {
int top=LuaDLL.lua_gettop(luaState); int top=LuaLib.lua_gettop(luaState);
LuaDLL.lua_getref(luaState,ref1); LuaLib.lua_getref(luaState,ref1);
LuaDLL.lua_getref(luaState,ref2); LuaLib.lua_getref(luaState,ref2);
int equal=LuaDLL.lua_equal(luaState,-1,-2); int equal=LuaLib.lua_equal(luaState,-1,-2);
LuaDLL.lua_settop(luaState,top); LuaLib.lua_settop(luaState,top);
return (equal!=0); return (equal!=0);
} }
internal void pushCSFunction(LuaCSFunction function) internal void pushCSFunction(CallbackFunction function)
{ {
translator.pushFunction(luaState,function); translator.pushFunction(luaState,function);
} }
...@@ -1029,108 +572,274 @@ namespace LuaInterface ...@@ -1029,108 +572,274 @@ namespace LuaInterface
if (translator != null) if (translator != null)
{ {
translator.pendingEvents.Dispose(); translator.pendingEvents.Dispose();
translator = null; translator = null;
} }
this.Close();
System.GC.Collect(); System.GC.Collect();
System.GC.WaitForPendingFinalizers(); System.GC.WaitForPendingFinalizers();
} }
#endregion #endregion
} }
/// <summary> /*
/// Event codes for lua hook function * Wrapper class for Lua tables
/// </summary> *
/// <remarks> * Author: Fabio Mascarenhas
/// Do not change any of the values because they must match the lua values * Version: 1.0
/// </remarks> */
/// <author>Reinhard Ostermeier</author> public class LuaTable
public enum EventCodes {
{ internal int reference;
LUA_HOOKCALL = 0, private Lua interpreter;
LUA_HOOKRET = 1, public LuaTable(int reference, Lua interpreter)
LUA_HOOKLINE = 2, {
LUA_HOOKCOUNT = 3, this.reference=reference;
LUA_HOOKTAILRET = 4, this.interpreter=interpreter;
} }
~LuaTable()
/// <summary> {
/// Event masks for lua hook callback interpreter.dispose(reference);
/// </summary> }
/// <remarks> /*
/// Do not change any of the values because they must match the lua values * Indexer for string fields of the table
/// </remarks> */
/// <author>Reinhard Ostermeier</author> public object this[string field]
[Flags] {
public enum EventMasks get
{ {
LUA_MASKCALL = (1 << EventCodes.LUA_HOOKCALL), return interpreter.getObject(reference,field);
LUA_MASKRET = (1 << EventCodes.LUA_HOOKRET), }
LUA_MASKLINE = (1 << EventCodes.LUA_HOOKLINE), set
LUA_MASKCOUNT = (1 << EventCodes.LUA_HOOKCOUNT), {
LUA_MASKALL = Int32.MaxValue, interpreter.setObject(reference,field,value);
} }
}
/// <summary> /*
/// Structure for lua debug information * Indexer for numeric fields of the table
/// </summary> */
/// <remarks> public object this[object field]
/// Do not change this struct because it must match the lua structure lua_debug {
/// </remarks> get
/// <author>Reinhard Ostermeier</author> {
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] return interpreter.getObject(reference,field);
public struct LuaDebug }
{ set
public EventCodes eventCode; {
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)] interpreter.setObject(reference,field,value);
public String name; }
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)] }
public String namewhat;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public String what; public System.Collections.IEnumerator GetEnumerator()
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)] {
public String source; return interpreter.GetTableDict(this).GetEnumerator();
public int currentline; }
public int nups;
public int linedefined; public ICollection Keys
public int lastlinedefined; {
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 60/*LUA_IDSIZE*/)] get { return interpreter.GetTableDict(this).Keys; }
public String shortsrc; }
public int i_ci;
} public ICollection Values
{
/// <summary> get { return interpreter.GetTableDict(this).Values; }
/// Event args for hook callback event }
/// </summary>
/// <author>Reinhard Ostermeier</author> /*
public class DebugHookEventArgs : EventArgs * Gets an string fields of a table ignoring its metatable,
{ * if it exists
private readonly LuaDebug luaDebug; */
internal object rawget(string field)
public DebugHookEventArgs(LuaDebug luaDebug) {
{ return interpreter.rawGetObject(reference,field);
this.luaDebug = luaDebug; }
}
internal object rawgetFunction(string field)
public LuaDebug LuaDebug {
{ object obj=interpreter.rawGetObject(reference,field);
get { return luaDebug; }
} if(obj is CallbackFunction)
} return new LuaFunction((CallbackFunction)obj,interpreter);
else
public class HookExceptionEventArgs : EventArgs return obj;
{ }
private readonly Exception m_Exception;
public Exception Exception /*
{ * Pushes this table into the Lua stack
get { return m_Exception; } */
} internal void push(IntPtr luaState)
{
public HookExceptionEventArgs(Exception ex) LuaLib.lua_getref(luaState,reference);
{ }
m_Exception = ex; public override string ToString()
} {
} return "table";
}
public override bool Equals(object o)
{
if(o is LuaTable)
{
LuaTable l=(LuaTable)o;
return interpreter.compareRef(l.reference,this.reference);
} else return false;
}
public override int GetHashCode()
{
return reference;
}
}
public class LuaFunction
{
private Lua interpreter;
internal CallbackFunction function;
internal int reference;
public LuaFunction(int reference, Lua interpreter)
{
this.reference=reference;
this.function=null;
this.interpreter=interpreter;
}
public LuaFunction(CallbackFunction function, Lua interpreter)
{
this.reference=0;
this.function=function;
this.interpreter=interpreter;
}
~LuaFunction()
{
if(reference!=0)
interpreter.dispose(reference);
}
/*
* Calls the function casting return values to the types
* in returnTypes
*/
internal object[] call(object[] args, Type[] returnTypes)
{
return interpreter.callFunction(this,args,returnTypes);
}
/*
* Calls the function and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
return interpreter.callFunction(this,args);
}
/*
* Pushes the function into the Lua stack
*/
internal void push(IntPtr luaState)
{
if(reference!=0)
LuaLib.lua_getref(luaState,reference);
else
interpreter.pushCSFunction(function);
}
public override string ToString()
{
return "function";
}
public override bool Equals(object o)
{
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;
}
else return false;
}
public override int GetHashCode()
{
if(reference!=0)
return reference;
else
return function.GetHashCode();
}
}
public class LuaUserData
{
internal int reference;
private Lua interpreter;
public LuaUserData(int reference, Lua interpreter)
{
this.reference=reference;
this.interpreter=interpreter;
}
~LuaUserData()
{
interpreter.dispose(reference);
}
/*
* Indexer for string fields of the userdata
*/
public object this[string field]
{
get
{
return interpreter.getObject(reference,field);
}
set
{
interpreter.setObject(reference,field,value);
}
}
/*
* Indexer for numeric fields of the userdata
*/
public object this[object field]
{
get
{
return interpreter.getObject(reference,field);
}
set
{
interpreter.setObject(reference,field,value);
}
}
/*
* Calls the userdata and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
return interpreter.callFunction(this,args);
}
/*
* Pushes the userdata into the Lua stack
*/
internal void push(IntPtr luaState)
{
LuaLib.lua_getref(luaState,reference);
}
public override string ToString()
{
return "userdata";
}
public override bool Equals(object o)
{
if(o is LuaUserData)
{
LuaUserData l=(LuaUserData)o;
return interpreter.compareRef(l.reference,this.reference);
}
else return false;
}
public override int GetHashCode()
{
return reference;
}
}
} }
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
namespace LuaInterface
{
/// <summary>
/// Base class to provide consistent disposal flow across lua objects. Uses code provided by Yves Duhoux and suggestions by Hans Schmeidenbacher and Qingrui Li
/// </summary>
public abstract class LuaBase : IDisposable
{
private bool _Disposed;
protected int _Reference;
protected Lua _Interpreter;
~LuaBase()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposeManagedResources)
{
if (!_Disposed)
{
if (disposeManagedResources)
{
if (_Reference != 0)
_Interpreter.dispose(_Reference);
}
_Interpreter = null;
_Disposed = true;
}
}
public override bool Equals(object o)
{
if (o is LuaBase)
{
LuaBase l = (LuaBase)o;
return _Interpreter.compareRef(l._Reference, _Reference);
}
else return false;
}
public override int GetHashCode()
{
return _Reference;
}
}
}
using System; using System;
using System.Runtime.Serialization; using System.Collections.Generic;
using System.Text;
namespace LuaInterface namespace LuaInterface
{ {
/// <summary> /// <summary>
/// Exceptions thrown by the Lua runtime /// Add a specific type for Lua exceptions (kevinh)
/// </summary> /// </summary>
[Serializable] public class LuaException : ApplicationException
public class LuaException : Exception
{ {
public LuaException() public LuaException(string reason)
{} : base(reason)
{
public LuaException(string message) : base(message) }
{}
public LuaException(string message, Exception innerException) : base(message, innerException)
{}
protected LuaException(SerializationInfo info, StreamingContext context) : base(info, context)
{}
} }
} }
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using Lua511;
namespace LuaInterface
{
public class LuaFunction : LuaBase
{
//private Lua interpreter;
internal LuaCSFunction function;
//internal int reference;
public LuaFunction(int reference, Lua interpreter)
{
_Reference = reference;
this.function = null;
_Interpreter = interpreter;
}
public LuaFunction(LuaCSFunction function, Lua interpreter)
{
_Reference = 0;
this.function = function;
_Interpreter = interpreter;
}
//~LuaFunction()
//{
// if (reference != 0)
// interpreter.dispose(reference);
//}
//bool disposed = false;
//~LuaFunction()
//{
// Dispose(false);
//}
//public void Dispose()
//{
// Dispose(true);
// GC.SuppressFinalize(this);
//}
//public virtual void Dispose(bool disposeManagedResources)
//{
// if (!this.disposed)
// {
// if (disposeManagedResources)
// {
// if (_Reference != 0)
// _Interpreter.dispose(_Reference);
// }
// disposed = true;
// }
//}
/*
* Calls the function casting return values to the types
* in returnTypes
*/
internal object[] call(object[] args, Type[] returnTypes)
{
return _Interpreter.callFunction(this, args, returnTypes);
}
/*
* Calls the function and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
return _Interpreter.callFunction(this, args);
}
/*
* Pushes the function into the Lua stack
*/
internal void push(IntPtr luaState)
{
if (_Reference != 0)
LuaDLL.lua_getref(luaState, _Reference);
else
_Interpreter.pushCSFunction(function);
}
public override string ToString()
{
return "function";
}
public override bool Equals(object o)
{
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;
}
else return false;
}
public override int GetHashCode()
{
if (_Reference != 0)
return _Reference;
else
return function.GetHashCode();
}
}
}
using System;
namespace LuaInterface
{
/// <summary>
/// Marks a method for global usage in Lua scripts
/// </summary>
/// <see cref="LuaRegistrationHelper.TaggedInstanceMethods"/>
/// <see cref="LuaRegistrationHelper.TaggedStaticMethods"/>
[AttributeUsage(AttributeTargets.Method)]
public sealed class LuaGlobalAttribute : Attribute
{
/// <summary>
/// An alternative name to use for calling the function in Lua - leave empty for CLR name
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description of the function
/// </summary>
public string Description { get; set; }
}
}
using System;
namespace LuaInterface
{
/// <summary>
/// Marks a method, field or property to be hidden from Lua auto-completion
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public sealed class LuaHideAttribute : Attribute
{}
}
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F55CABBB-4108-4A39-94E1-581FD46DC021}</ProjectGuid> <ProjectGuid>{F55CABBB-4108-4A39-94E1-581FD46DC021}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LuaInterface</RootNamespace> <RootNamespace>LuaInterface</RootNamespace>
<AssemblyName>LuaInterface</AssemblyName> <AssemblyName>LuaInterface</AssemblyName>
<SignAssembly>true</SignAssembly> <OldToolsVersion>2.0</OldToolsVersion>
<AssemblyOriginatorKeyFile>luainterface.snk</AssemblyOriginatorKeyFile>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\..\Built\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
...@@ -63,13 +29,8 @@ ...@@ -63,13 +29,8 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="lua51, Version=0.0.0.0, Culture=neutral, PublicKeyToken=1e1fb15b02227b8a, processorArchitecture=x86">
<HintPath>..\..\lib\lua51\net40\lua51.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
...@@ -79,43 +40,15 @@ ...@@ -79,43 +40,15 @@
<Compile Include="CheckType.cs" /> <Compile Include="CheckType.cs" />
<Compile Include="GenerateEventAssembly.cs" /> <Compile Include="GenerateEventAssembly.cs" />
<Compile Include="Lua.cs" /> <Compile Include="Lua.cs" />
<Compile Include="LuaBase.cs" />
<Compile Include="LuaException.cs" /> <Compile Include="LuaException.cs" />
<Compile Include="LuaFunction.cs" />
<Compile Include="LuaGlobalAttribute.cs" />
<Compile Include="LuaHideAttribute.cs" />
<Compile Include="LuaRegistrationHelper.cs" />
<Compile Include="LuaScriptException.cs" />
<Compile Include="LuaTable.cs" />
<Compile Include="LuaUserData.cs" />
<Compile Include="Metatables.cs" /> <Compile Include="Metatables.cs" />
<Compile Include="MethodWrapper.cs" /> <Compile Include="MethodWrapper.cs" />
<Compile Include="ObjectTranslator.cs" /> <Compile Include="ObjectTranslator.cs" />
<Compile Include="ProxyType.cs" /> <Compile Include="ProxyType.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="luainterface.snk" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
...@@ -124,4 +57,10 @@ ...@@ -124,4 +57,10 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> <ItemGroup>
\ No newline at end of file <ProjectReference Include="..\LuaWrap\LuaWrap.csproj">
<Project>{76D7F266-456D-4A7C-916E-E35D057E5F98}</Project>
<Name>LuaWrap</Name>
</ProjectReference>
</ItemGroup>
</Project>
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace LuaInterface
{
public static class LuaRegistrationHelper
{
#region Tagged instance methods
/// <summary>
/// Registers all public instance methods in an object tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary>
/// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="o">The object to get the methods from</param>
public static void TaggedInstanceMethods(Lua lua, object o)
{
#region Sanity checks
if (lua == null) throw new ArgumentNullException("lua");
if (o == null) throw new ArgumentNullException("o");
#endregion
foreach (MethodInfo method in o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public))
{
foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), true))
{
if (string.IsNullOrEmpty(attribute.Name))
lua.RegisterFunction(method.Name, o, method); // CLR name
else
lua.RegisterFunction(attribute.Name, o, method); // Custom name
}
}
}
#endregion
#region Tagged static methods
/// <summary>
/// Registers all public static methods in a class tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary>
/// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="type">The class type to get the methods from</param>
public static void TaggedStaticMethods(Lua lua, Type type)
{
#region Sanity checks
if (lua == null) throw new ArgumentNullException("lua");
if (type == null) throw new ArgumentNullException("type");
if (!type.IsClass) throw new ArgumentException("The type must be a class!", "type");
#endregion
foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), false))
{
if (string.IsNullOrEmpty(attribute.Name))
lua.RegisterFunction(method.Name, null, method); // CLR name
else
lua.RegisterFunction(attribute.Name, null, method); // Custom name
}
}
}
#endregion
#region Enumeration
/// <summary>
/// Registers an enumeration's values for usage as a Lua variable table
/// </summary>
/// <typeparam name="T">The enum type to register</typeparam>
/// <param name="lua">The Lua VM to add the enum to</param>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")]
public static void Enumeration<T>(Lua lua)
{
#region Sanity checks
if (lua == null) throw new ArgumentNullException("lua");
#endregion
Type type = typeof(T);
if (!type.IsEnum) throw new ArgumentException("The type must be an enumeration!");
string[] names = Enum.GetNames(type);
var values = (T[])Enum.GetValues(type);
lua.NewTable(type.Name);
for (int i = 0; i < names.Length; i++)
{
string path = type.Name + "." + names[i];
lua[path] = values[i];
}
}
#endregion
}
}
using System;
namespace LuaInterface
{
/// <summary>
/// Exceptions thrown by the Lua runtime because of errors in the script
/// </summary>
public class LuaScriptException : LuaException
{
/// <summary>
/// Returns true if the exception has occured as the result of a .NET exception in user code
/// </summary>
public bool IsNetException { get; private set; }
private readonly string source;
/// <summary>
/// The position in the script where the exception was triggered.
/// </summary>
public override string Source { get { return source; } }
/// <summary>
/// Creates a new Lua-only exception.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(string message, string source) : base(message)
{
this.source = source;
}
/// <summary>
/// Creates a new .NET wrapping exception.
/// </summary>
/// <param name="innerException">The .NET exception triggered by user-code.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(Exception innerException, string source)
: base("A .NET exception occured in user-code", innerException)
{
this.source = source;
this.IsNetException = true;
}
public override string ToString()
{
// Prepend the error source
return GetType().FullName + ": " + source + Message;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using Lua511;
using System.Collections;
namespace LuaInterface
{
/*
* Wrapper class for Lua tables
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaTable : LuaBase
{
//internal int _Reference;
//private Lua _Interpreter;
public LuaTable(int reference, Lua interpreter)
{
_Reference = reference;
_Interpreter = interpreter;
}
//bool disposed = false;
//~LuaTable()
//{
// Dispose(false);
//}
//public void Dispose()
//{
// Dispose(true);
// GC.SuppressFinalize(this);
//}
//public virtual void Dispose(bool disposeManagedResources)
//{
// if (!this.disposed)
// {
// if (disposeManagedResources)
// {
// if (_Reference != 0)
// _Interpreter.dispose(_Reference);
// }
// disposed = true;
// }
//}
//~LuaTable()
//{
// _Interpreter.dispose(_Reference);
//}
/*
* Indexer for string fields of the table
*/
public object this[string field]
{
get
{
return _Interpreter.getObject(_Reference, field);
}
set
{
_Interpreter.setObject(_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the table
*/
public object this[object field]
{
get
{
return _Interpreter.getObject(_Reference, field);
}
set
{
_Interpreter.setObject(_Reference, field, value);
}
}
public System.Collections.IDictionaryEnumerator GetEnumerator()
{
return _Interpreter.GetTableDict(this).GetEnumerator();
}
public ICollection Keys
{
get { return _Interpreter.GetTableDict(this).Keys; }
}
public ICollection Values
{
get { return _Interpreter.GetTableDict(this).Values; }
}
/*
* Gets an string fields of a table ignoring its metatable,
* if it exists
*/
internal object rawget(string field)
{
return _Interpreter.rawGetObject(_Reference, field);
}
internal object rawgetFunction(string field)
{
object obj = _Interpreter.rawGetObject(_Reference, field);
if (obj is LuaCSFunction)
return new LuaFunction((LuaCSFunction)obj, _Interpreter);
else
return obj;
}
/*
* Pushes this table into the Lua stack
*/
internal void push(IntPtr luaState)
{
LuaDLL.lua_getref(luaState, _Reference);
}
public override string ToString()
{
return "table";
}
//public override bool Equals(object o)
//{
// if (o is LuaTable)
// {
// LuaTable l = (LuaTable)o;
// return _Interpreter.compareRef(l._Reference, _Reference);
// }
// else return false;
//}
//public override int GetHashCode()
//{
// return _Reference;
//}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Lua511;
namespace LuaInterface
{
public class LuaUserData : LuaBase
{
//internal int _Reference;
//private Lua _Interpreter;
public LuaUserData(int reference, Lua interpreter)
{
_Reference = reference;
_Interpreter = interpreter;
}
//~LuaUserData()
//{
// if (_Reference != 0)
// _Interpreter.dispose(_Reference);
//}
/*
* Indexer for string fields of the userdata
*/
public object this[string field]
{
get
{
return _Interpreter.getObject(_Reference, field);
}
set
{
_Interpreter.setObject(_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the userdata
*/
public object this[object field]
{
get
{
return _Interpreter.getObject(_Reference, field);
}
set
{
_Interpreter.setObject(_Reference, field, value);
}
}
/*
* Calls the userdata and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
return _Interpreter.callFunction(this, args);
}
/*
* Pushes the userdata into the Lua stack
*/
internal void push(IntPtr luaState)
{
LuaDLL.lua_getref(luaState, _Reference);
}
public override string ToString()
{
return "userdata";
}
//public override bool Equals(object o)
//{
// if (o is LuaUserData)
// {
// LuaUserData l = (LuaUserData)o;
// return _Interpreter.compareRef(l._Reference, _Reference);
// }
// else return false;
//}
//public override int GetHashCode()
//{
// return _Reference;
//}
}
}
...@@ -6,7 +6,7 @@ namespace LuaInterface ...@@ -6,7 +6,7 @@ namespace LuaInterface
using System.Reflection; using System.Reflection;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
using Lua511; using LuaWrap;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
/* /*
...@@ -39,22 +39,22 @@ namespace LuaInterface ...@@ -39,22 +39,22 @@ namespace LuaInterface
private ObjectTranslator translator; private ObjectTranslator translator;
private Hashtable memberCache = new Hashtable(); private Hashtable memberCache = new Hashtable();
internal LuaCSFunction gcFunction, indexFunction, newindexFunction, internal CallbackFunction gcFunction, indexFunction, newindexFunction,
baseIndexFunction, classIndexFunction, classNewindexFunction, baseIndexFunction, classIndexFunction, classNewindexFunction,
execDelegateFunction, callConstructorFunction, toStringFunction; execDelegateFunction, callConstructorFunction, toStringFunction;
public MetaFunctions(ObjectTranslator translator) public MetaFunctions(ObjectTranslator translator)
{ {
this.translator = translator; this.translator = translator;
gcFunction = new LuaCSFunction(this.collectObject); gcFunction = new CallbackFunction(this.collectObject);
toStringFunction = new LuaCSFunction(this.toString); toStringFunction = new CallbackFunction(this.toString);
indexFunction = new LuaCSFunction(this.getMethod); indexFunction = new CallbackFunction(this.getMethod);
newindexFunction = new LuaCSFunction(this.setFieldOrProperty); newindexFunction = new CallbackFunction(this.setFieldOrProperty);
baseIndexFunction = new LuaCSFunction(this.getBaseMethod); baseIndexFunction = new CallbackFunction(this.getBaseMethod);
callConstructorFunction = new LuaCSFunction(this.callConstructor); callConstructorFunction = new CallbackFunction(this.callConstructor);
classIndexFunction = new LuaCSFunction(this.getClassMethod); classIndexFunction = new CallbackFunction(this.getClassMethod);
classNewindexFunction = new LuaCSFunction(this.setClassFieldOrProperty); classNewindexFunction = new CallbackFunction(this.setClassFieldOrProperty);
execDelegateFunction = new LuaCSFunction(this.runFunctionDelegate); execDelegateFunction = new CallbackFunction(this.runFunctionDelegate);
} }
/* /*
...@@ -62,8 +62,8 @@ namespace LuaInterface ...@@ -62,8 +62,8 @@ namespace LuaInterface
*/ */
private int runFunctionDelegate(IntPtr luaState) private int runFunctionDelegate(IntPtr luaState)
{ {
LuaCSFunction func = (LuaCSFunction)translator.getRawNetObject(luaState, 1); CallbackFunction func = (CallbackFunction)translator.getRawNetObject(luaState, 1);
LuaDLL.lua_remove(luaState, 1); LuaLib.lua_remove(luaState, 1);
return func(luaState); return func(luaState);
} }
/* /*
...@@ -71,7 +71,7 @@ namespace LuaInterface ...@@ -71,7 +71,7 @@ namespace LuaInterface
*/ */
private int collectObject(IntPtr luaState) private int collectObject(IntPtr luaState)
{ {
int udata = LuaDLL.luanet_rawnetobj(luaState, 1); int udata = LuaLib.luanet_rawnetobj(luaState, 1);
if (udata != -1) if (udata != -1)
{ {
translator.collectObject(udata); translator.collectObject(udata);
...@@ -92,7 +92,7 @@ namespace LuaInterface ...@@ -92,7 +92,7 @@ namespace LuaInterface
{ {
translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode()); translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode());
} }
else LuaDLL.lua_pushnil(luaState); else LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
...@@ -103,17 +103,17 @@ namespace LuaInterface ...@@ -103,17 +103,17 @@ namespace LuaInterface
/// FIXME, move somewhere else /// FIXME, move somewhere else
public static void dumpStack(ObjectTranslator translator, IntPtr luaState) public static void dumpStack(ObjectTranslator translator, IntPtr luaState)
{ {
int depth = LuaDLL.lua_gettop(luaState); int depth = LuaLib.lua_gettop(luaState);
Debug.WriteLine("lua stack depth: " + depth); Debug.WriteLine("lua stack depth: " + depth);
for (int i = 1; i <= depth; i++) for (int i = 1; i <= depth; i++)
{ {
LuaTypes type = LuaDLL.lua_type(luaState, i); LuaType type = LuaLib.lua_type(luaState, i);
// we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types // 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 == LuaTypes.LUA_TTABLE) ? "table" : LuaDLL.lua_typename(luaState, type); string typestr = (type == LuaType.Table) ? "table" : LuaLib.lua_typename(luaState, type);
string strrep = LuaDLL.lua_tostring(luaState, i); string strrep = LuaLib.lua_tostring(luaState, i);
if (type == LuaTypes.LUA_TUSERDATA) if (type == LuaType.UserData)
{ {
object obj = translator.getRawNetObject(luaState, i); object obj = translator.getRawNetObject(luaState, i);
strrep = obj.ToString(); strrep = obj.ToString();
...@@ -137,108 +137,67 @@ namespace LuaInterface ...@@ -137,108 +137,67 @@ namespace LuaInterface
if (obj == null) if (obj == null)
{ {
translator.throwError(luaState, "trying to index an invalid object reference"); translator.throwError(luaState, "trying to index an invalid object reference");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
object index = translator.getObject(luaState, 2); object index = translator.getObject(luaState, 2);
Type indexType = index.GetType(); //Type indexType = index.GetType();
string methodName = index as string; // will be null if not a string arg string methodName = index as string; // will be null if not a string arg
Type objType = obj.GetType(); Type objType = obj.GetType();
// Handle the most common case, looking up the method by name. // Handle the most common case, looking up the method by name
if (methodName != null && isMemberPresent(objType, methodName))
// CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object, return getMember(luaState, objType, obj, methodName, BindingFlags.Instance);
// ie: xmlelement['item'] <- item is a property of xmlelement
try
{
if (methodName != null && isMemberPresent(objType, methodName))
return getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase);
}
catch { }
// Try to access by array if the type is right and index is an int (lua numbers always come across as double) // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
if (objType.IsArray && index is double) if (objType.IsArray && index is double)
{ {
int intIndex = (int)((double)index); object[] arr = (object[])obj;
if (objType.UnderlyingSystemType == typeof(float[])) translator.push(luaState, arr[(int)((double)index)]);
{ }
float[] arr = ((float[])obj);
translator.push(luaState, arr[intIndex]);
}
else if (objType.UnderlyingSystemType == typeof(double[]))
{
double[] arr = ((double[])obj);
translator.push(luaState, arr[intIndex]);
}
else if (objType.UnderlyingSystemType == typeof(int[]))
{
int[] arr = ((int[])obj);
translator.push(luaState, arr[intIndex]);
}
else
{
object[] arr = (object[])obj;
translator.push(luaState, arr[intIndex]);
}
}
else else
{ {
// Try to use get_Item to index into this .net object // Try to use get_Item to index into this .net object
//MethodInfo getter = objType.GetMethod("get_Item"); MethodInfo getter = objType.GetMethod("get_Item");
MethodInfo[] methods = objType.GetMethods(); ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;
foreach (MethodInfo mInfo in methods) if (actualParms == null || actualParms.Length != 1)
{ {
if (mInfo.Name == "get_Item") translator.throwError(luaState, "method not found (or no indexer): " + index);
{
//check if the signature matches the input LuaLib.lua_pushnil(luaState);
if (mInfo.GetParameters().Length == 1)
{
MethodInfo getter = mInfo;
ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;
if (actualParms == null || actualParms.Length != 1)
{
translator.throwError(luaState, "method not found (or no indexer): " + index);
LuaDLL.lua_pushnil(luaState);
}
else
{
// Get the index in a form acceptable to the getter
index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
object[] args = new object[1];
// Just call the indexer - if out of bounds an exception will happen
args[0] = index;
try
{
object result = getter.Invoke(obj, args);
translator.push(luaState, result);
}
catch (TargetInvocationException e)
{
// Provide a more readable description for the common case of key not found
if (e.InnerException is KeyNotFoundException)
translator.throwError(luaState, "key '" + index + "' not found ");
else
translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
LuaDLL.lua_pushnil(luaState);
}
}
}
}
} }
else
{
// Get the index in a form acceptable to the getter
index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
object[] args = new object[1];
// Just call the indexer - if out of bounds an exception will happen
args[0] = index;
try
{
object result = getter.Invoke(obj, args);
translator.push(luaState, result);
}
catch (TargetInvocationException e)
{
// Provide a more readable description for the common case of key not found
if(e.InnerException is KeyNotFoundException)
translator.throwError(luaState, "key '" + index + "' not found ");
else
translator.throwError(luaState, "exception indexing '" + index + "' " + e.Message);
LuaLib.lua_pushnil(luaState);
}
}
} }
LuaDLL.lua_pushboolean(luaState, false); LuaLib.lua_pushboolean(luaState, false);
return 2; return 2;
} }
...@@ -253,25 +212,25 @@ namespace LuaInterface ...@@ -253,25 +212,25 @@ namespace LuaInterface
if (obj == null) if (obj == null)
{ {
translator.throwError(luaState, "trying to index an invalid object reference"); translator.throwError(luaState, "trying to index an invalid object reference");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
LuaDLL.lua_pushboolean(luaState, false); LuaLib.lua_pushboolean(luaState, false);
return 2; return 2;
} }
string methodName = LuaDLL.lua_tostring(luaState, 2); string methodName = LuaLib.lua_tostring(luaState, 2);
if (methodName == null) if (methodName == null)
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
LuaDLL.lua_pushboolean(luaState, false); LuaLib.lua_pushboolean(luaState, false);
return 2; return 2;
} }
getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance);
LuaDLL.lua_settop(luaState, -2); LuaLib.lua_settop(luaState, -2);
if (LuaDLL.lua_type(luaState, -1) == LuaTypes.LUA_TNIL) if (LuaLib.lua_type(luaState, -1) == LuaType.Nil)
{ {
LuaDLL.lua_settop(luaState, -2); LuaLib.lua_settop(luaState, -2);
return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance);
} }
LuaDLL.lua_pushboolean(luaState, false); LuaLib.lua_pushboolean(luaState, false);
return 2; return 2;
} }
...@@ -289,8 +248,7 @@ namespace LuaInterface ...@@ -289,8 +248,7 @@ namespace LuaInterface
if (cachedMember != null) if (cachedMember != null)
return true; return true;
//CP: Removed NonPublic binding search MemberInfo[] members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MemberInfo[] members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase/* | BindingFlags.NonPublic*/);
return (members.Length > 0); return (members.Length > 0);
} }
...@@ -306,9 +264,9 @@ namespace LuaInterface ...@@ -306,9 +264,9 @@ namespace LuaInterface
MemberInfo member = null; MemberInfo member = null;
object cachedMember = checkMemberCache(memberCache, objType, methodName); object cachedMember = checkMemberCache(memberCache, objType, methodName);
//object cachedMember=null; //object cachedMember=null;
if (cachedMember is LuaCSFunction) if (cachedMember is CallbackFunction)
{ {
translator.pushFunction(luaState, (LuaCSFunction)cachedMember); translator.pushFunction(luaState, (CallbackFunction)cachedMember);
translator.push(luaState, true); translator.push(luaState, true);
return 2; return 2;
} }
...@@ -318,16 +276,14 @@ namespace LuaInterface ...@@ -318,16 +276,14 @@ namespace LuaInterface
} }
else else
{ {
//CP: Removed NonPublic binding search MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.NonPublic);
MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if (members.Length > 0) if (members.Length > 0)
member = members[0]; member = members[0];
else else
{ {
// If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static // If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static
// lookups for fields/properties/events -kevinh // lookups for fields/properties/events -kevinh
//CP: Removed NonPublic binding search and made case insensitive members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if (members.Length > 0) if (members.Length > 0)
{ {
...@@ -348,7 +304,7 @@ namespace LuaInterface ...@@ -348,7 +304,7 @@ namespace LuaInterface
} }
catch catch
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
} }
else if (member.MemberType == MemberTypes.Property) else if (member.MemberType == MemberTypes.Property)
...@@ -369,12 +325,12 @@ namespace LuaInterface ...@@ -369,12 +325,12 @@ namespace LuaInterface
if (objType is Type && !(((Type)objType) == typeof(object))) if (objType is Type && !(((Type)objType) == typeof(object)))
return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType); return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType);
else else
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
catch (TargetInvocationException e) // Convert this exception into a Lua error catch(TargetInvocationException e) // Convert this exception into a Lua error
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
} }
else if (member.MemberType == MemberTypes.Event) else if (member.MemberType == MemberTypes.Event)
...@@ -383,7 +339,7 @@ namespace LuaInterface ...@@ -383,7 +339,7 @@ namespace LuaInterface
if (cachedMember == null) setMemberCache(memberCache, objType, methodName, member); if (cachedMember == null) setMemberCache(memberCache, objType, methodName, member);
translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo)); translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo));
} }
else if (!implicitStatic) else if(!implicitStatic)
{ {
if (member.MemberType == MemberTypes.NestedType) if (member.MemberType == MemberTypes.NestedType)
{ {
...@@ -405,8 +361,7 @@ namespace LuaInterface ...@@ -405,8 +361,7 @@ namespace LuaInterface
else else
{ {
// Member type must be 'method' // Member type must be 'method'
LuaCSFunction wrapper = new LuaCSFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); CallbackFunction wrapper = new CallbackFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call);
if (cachedMember == null) setMemberCache(memberCache, objType, methodName, wrapper); if (cachedMember == null) setMemberCache(memberCache, objType, methodName, wrapper);
translator.pushFunction(luaState, wrapper); translator.pushFunction(luaState, wrapper);
translator.push(luaState, true); translator.push(luaState, true);
...@@ -418,7 +373,7 @@ namespace LuaInterface ...@@ -418,7 +373,7 @@ namespace 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 // 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); translator.throwError(luaState, "can't pass instance to static method " + methodName);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
} }
else else
...@@ -429,7 +384,7 @@ namespace LuaInterface ...@@ -429,7 +384,7 @@ namespace LuaInterface
translator.throwError(luaState, "unknown member name " + methodName); translator.throwError(luaState, "unknown member name " + methodName);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
// push false because we are NOT returning a function (see luaIndexFunction) // push false because we are NOT returning a function (see luaIndexFunction)
...@@ -477,7 +432,7 @@ namespace LuaInterface ...@@ -477,7 +432,7 @@ namespace LuaInterface
// First try to look up the parameter as a property name // First try to look up the parameter as a property name
string detailMessage; string detailMessage;
bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance | BindingFlags.IgnoreCase, out detailMessage); bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance, out detailMessage);
if (didMember) if (didMember)
return 0; // Must have found the property name return 0; // Must have found the property name
...@@ -485,9 +440,9 @@ namespace LuaInterface ...@@ -485,9 +440,9 @@ namespace LuaInterface
// We didn't find a property name, now see if we can use a [] style this accessor to set array contents // We didn't find a property name, now see if we can use a [] style this accessor to set array contents
try try
{ {
if (type.IsArray && LuaDLL.lua_isnumber(luaState, 2)) if (type.IsArray && LuaLib.lua_isnumber(luaState, 2))
{ {
int index = (int)LuaDLL.lua_tonumber(luaState, 2); int index = (int)LuaLib.lua_tonumber(luaState, 2);
Array arr = (Array)target; Array arr = (Array)target;
object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType()); object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType());
...@@ -550,14 +505,14 @@ namespace LuaInterface ...@@ -550,14 +505,14 @@ namespace LuaInterface
// changing the lua typecode to string // changing the lua typecode to string
// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to // Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
// be true for isstring. // be true for isstring.
if (LuaDLL.lua_type(luaState, 2) != LuaTypes.LUA_TSTRING) if (LuaLib.lua_type(luaState, 2) != LuaType.String)
{ {
detailMessage = "property names must be strings"; detailMessage = "property names must be strings";
return false; return false;
} }
// We only look up property names by string // We only look up property names by string
string fieldName = LuaDLL.lua_tostring(luaState, 2); string fieldName = LuaLib.lua_tostring(luaState, 2);
if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter(fieldName[0]) || fieldName[0] == '_')) if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter(fieldName[0]) || fieldName[0] == '_'))
{ {
detailMessage = "invalid property name"; detailMessage = "invalid property name";
...@@ -568,8 +523,7 @@ namespace LuaInterface ...@@ -568,8 +523,7 @@ namespace LuaInterface
MemberInfo member = (MemberInfo)checkMemberCache(memberCache, targetType, fieldName); MemberInfo member = (MemberInfo)checkMemberCache(memberCache, targetType, fieldName);
if (member == null) if (member == null)
{ {
//CP: Removed NonPublic binding search and made case insensitive MemberInfo[] members = targetType.GetMember(fieldName, bindingType | BindingFlags.Public | BindingFlags.NonPublic);
MemberInfo[] members = targetType.GetMember(fieldName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/);
if (members.Length > 0) if (members.Length > 0)
{ {
member = members[0]; member = members[0];
...@@ -627,7 +581,7 @@ namespace LuaInterface ...@@ -627,7 +581,7 @@ namespace LuaInterface
string detail; string detail;
bool success = trySetMember(luaState, targetType, target, bindingType, out detail); bool success = trySetMember(luaState, targetType, target, bindingType, out detail);
if (!success) if(!success)
translator.throwError(luaState, detail); translator.throwError(luaState, detail);
return 0; return 0;
...@@ -659,25 +613,25 @@ namespace LuaInterface ...@@ -659,25 +613,25 @@ namespace LuaInterface
if (obj == null || !(obj is IReflect)) if (obj == null || !(obj is IReflect))
{ {
translator.throwError(luaState, "trying to index an invalid type reference"); translator.throwError(luaState, "trying to index an invalid type reference");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
else klass = (IReflect)obj; else klass = (IReflect)obj;
if (LuaDLL.lua_isnumber(luaState, 2)) if (LuaLib.lua_isnumber(luaState, 2))
{ {
int size = (int)LuaDLL.lua_tonumber(luaState, 2); int size = (int)LuaLib.lua_tonumber(luaState, 2);
translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size)); translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size));
return 1; return 1;
} }
else else
{ {
string methodName = LuaDLL.lua_tostring(luaState, 2); string methodName = LuaLib.lua_tostring(luaState, 2);
if (methodName == null) if (methodName == null)
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} //CP: Ignore case }
else return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); else return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static);
} }
} }
/* /*
...@@ -693,7 +647,7 @@ namespace LuaInterface ...@@ -693,7 +647,7 @@ namespace LuaInterface
return 0; return 0;
} }
else target = (IReflect)obj; else target = (IReflect)obj;
return setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); return setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static);
} }
/* /*
* __call metafunction of type references. Searches for and calls * __call metafunction of type references. Searches for and calls
...@@ -709,11 +663,11 @@ namespace LuaInterface ...@@ -709,11 +663,11 @@ namespace LuaInterface
if (obj == null || !(obj is IReflect)) if (obj == null || !(obj is IReflect))
{ {
translator.throwError(luaState, "trying to call constructor on an invalid type reference"); translator.throwError(luaState, "trying to call constructor on an invalid type reference");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
else klass = (IReflect)obj; else klass = (IReflect)obj;
LuaDLL.lua_remove(luaState, 1); LuaLib.lua_remove(luaState, 1);
ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors(); ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
foreach (ConstructorInfo constructor in constructors) foreach (ConstructorInfo constructor in constructors)
{ {
...@@ -727,11 +681,11 @@ namespace LuaInterface ...@@ -727,11 +681,11 @@ namespace LuaInterface
catch (TargetInvocationException e) catch (TargetInvocationException e)
{ {
ThrowError(luaState, e); ThrowError(luaState, e);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
catch catch
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
return 1; return 1;
} }
...@@ -742,7 +696,7 @@ namespace LuaInterface ...@@ -742,7 +696,7 @@ namespace LuaInterface
translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match", translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
klass.UnderlyingSystemType, klass.UnderlyingSystemType,
constructorName)); constructorName));
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
/* /*
...@@ -756,7 +710,7 @@ namespace LuaInterface ...@@ -756,7 +710,7 @@ namespace LuaInterface
bool isMethod = true; bool isMethod = true;
ParameterInfo[] paramInfo = method.GetParameters(); ParameterInfo[] paramInfo = method.GetParameters();
int currentLuaParam = 1; int currentLuaParam = 1;
int nLuaParams = LuaDLL.lua_gettop(luaState); int nLuaParams = LuaLib.lua_gettop(luaState);
ArrayList paramList = new ArrayList(); ArrayList paramList = new ArrayList();
List<int> outList = new List<int>(); List<int> outList = new List<int>();
List<MethodArgs> argTypes = new List<MethodArgs>(); List<MethodArgs> argTypes = new List<MethodArgs>();
...@@ -778,61 +732,17 @@ namespace LuaInterface ...@@ -778,61 +732,17 @@ namespace LuaInterface
break; break;
} }
} }
else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // Type checking else if ((extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null) // Type checking
{ {
int index = paramList.Add(extractValue(luaState, currentLuaParam)); int index = paramList.Add(extractValue(luaState, currentLuaParam));
MethodArgs methodArg = new MethodArgs(); MethodArgs methodArg = new MethodArgs();
methodArg.index = index; methodArg.index = index;
methodArg.extractValue = extractValue; methodArg.extractValue = extractValue;
argTypes.Add(methodArg); argTypes.Add(methodArg);
if (currentNetParam.ParameterType.IsByRef) if (currentNetParam.ParameterType.IsByRef)
outList.Add(index); outList.Add(index);
currentLuaParam++; currentLuaParam++;
} // Type does not match, ignore if the parameter is optional } // Type does not match, ignore if the parameter is optional
else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
{
object luaParamValue = extractValue(luaState, currentLuaParam);
Type paramArrayType = currentNetParam.ParameterType.GetElementType();
Array paramArray;
if (luaParamValue is LuaTable)
{
LuaTable table = (LuaTable)luaParamValue;
IDictionaryEnumerator tableEnumerator = table.GetEnumerator();
paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);
tableEnumerator.Reset();
int paramArrayIndex = 0;
while(tableEnumerator.MoveNext())
{
paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex);
paramArrayIndex++;
}
}
else
{
paramArray = Array.CreateInstance(paramArrayType, 1);
paramArray.SetValue(luaParamValue, 0);
}
int index = paramList.Add(paramArray);
MethodArgs methodArg = new MethodArgs();
methodArg.index = index;
methodArg.extractValue = extractValue;
methodArg.isParamsArray = true;
methodArg.paramsArrayType = paramArrayType;
argTypes.Add(methodArg);
currentLuaParam++;
}
else if (currentNetParam.IsOptional) else if (currentNetParam.IsOptional)
{ {
paramList.Add(currentNetParam.DefaultValue); paramList.Add(currentNetParam.DefaultValue);
...@@ -854,89 +764,5 @@ namespace LuaInterface ...@@ -854,89 +764,5 @@ namespace LuaInterface
} }
return isMethod; return isMethod;
} }
/// <summary>
/// CP: Fix for operator overloading failure
/// Returns true if the type is set and assigns the extract value
/// </summary>
/// <param name="luaState"></param>
/// <param name="currentLuaParam"></param>
/// <param name="currentNetParam"></param>
/// <param name="extractValue"></param>
/// <returns></returns>
private bool _IsTypeCorrect(IntPtr luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{
try
{
return (extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null;
}
catch
{
extractValue = null;
Debug.WriteLine("Type wasn't correct");
return false;
}
}
private bool _IsParamsArray(IntPtr luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{
extractValue = null;
if (currentNetParam.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
{
LuaTypes luaType;
try
{
luaType = LuaDLL.lua_type(luaState, currentLuaParam);
}
catch (Exception ex)
{
Debug.WriteLine("Could not retrieve lua type while attempting to determine params Array Status.");
Debug.WriteLine(ex.Message);
extractValue = null;
return false;
}
if (luaType == LuaTypes.LUA_TTABLE)
{
try
{
extractValue = translator.typeChecker.getExtractor(typeof(LuaTable));
}
catch (Exception ex)
{
Debug.WriteLine("An error occurred during an attempt to retrieve a LuaTable extractor while checking for params array status.");
}
if (extractValue != null)
{
return true;
}
}
else
{
Type paramElementType = currentNetParam.ParameterType.GetElementType();
try
{
extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, paramElementType);
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("An error occurred during an attempt to retrieve an extractor ({0}) while checking for params array status.", paramElementType.FullName));
}
if (extractValue != null)
{
return true;
}
}
}
Debug.WriteLine("Type wasn't Params object.");
return false;
}
} }
} }
\ No newline at end of file
namespace LuaInterface namespace LuaInterface
{ {
using System; using System;
using System.IO; using System.IO;
using System.Collections; using System.Collections;
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Lua511; using LuaWrap;
/* /*
* Cached method * Cached method
*/ */
struct MethodCache struct MethodCache
{ {
private MethodBase _cachedMethod; public MethodBase cachedMethod;
// List or arguments
public MethodBase cachedMethod public object[] args;
{ // Positions of out parameters
get public int[] outList;
{ // Types of parameters
return _cachedMethod; public MethodArgs[] argTypes;
} }
set
{ /*
_cachedMethod = value; * Parameter information
MethodInfo mi = value as MethodInfo; */
if (mi != null) struct MethodArgs
{ {
IsReturnVoid = string.Compare(mi.ReturnType.Name, "System.Void", true) == 0; // Position of parameter
} public int index;
} // Type-conversion function
} public ExtractValue extractValue;
}
public bool IsReturnVoid;
/*
// List or arguments * Argument extraction with type-conversion function
public object[] args; */
// Positions of out parameters delegate object ExtractValue(IntPtr luaState, int stackPos);
public int[] outList;
// Types of parameters /*
public MethodArgs[] argTypes; * Wrapper class for methods/constructors accessed from Lua.
} *
* Author: Fabio Mascarenhas
/* * Version: 1.0
* Parameter information */
*/ class LuaMethodWrapper
struct MethodArgs {
{ ObjectTranslator translator;
// Position of parameter MethodBase method;
public int index; MethodCache lastCalledMethod=new MethodCache();
// Type-conversion function string methodName;
public ExtractValue extractValue; MemberInfo[] members;
IReflect targetType;
public bool isParamsArray; ExtractValue extractTarget;
object target;
public Type paramsArrayType; BindingFlags bindingType;
} /*
* Constructs the wrapper for a known MethodBase instance
/* */
* Argument extraction with type-conversion function public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method)
*/ {
delegate object ExtractValue(IntPtr luaState, int stackPos); this.translator=translator;
this.target=target;
/* this.targetType=targetType;
* Wrapper class for methods/constructors accessed from Lua. if(targetType!=null)
* extractTarget=translator.typeChecker.getExtractor(targetType);
* Author: Fabio Mascarenhas this.method=method;
* Version: 1.0 this.methodName=method.Name;
*/ if(method.IsStatic) { bindingType=BindingFlags.Static; }
class LuaMethodWrapper else { bindingType=BindingFlags.Instance; }
{ }
private ObjectTranslator _Translator; /*
private MethodBase _Method; * Constructs the wrapper for a known method name
private MethodCache _LastCalledMethod = new MethodCache(); */
private string _MethodName; public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType)
private MemberInfo[] _Members; {
private IReflect _TargetType; this.translator=translator;
private ExtractValue _ExtractTarget; this.methodName=methodName;
private object _Target; this.targetType=targetType;
private BindingFlags _BindingType; if(targetType!=null)
extractTarget=translator.typeChecker.getExtractor(targetType);
/* this.bindingType=bindingType;
* Constructs the wrapper for a known MethodBase instance members=targetType.UnderlyingSystemType.GetMember(methodName,MemberTypes.Method,bindingType|BindingFlags.Public|BindingFlags.NonPublic);
*/ }
public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method)
{
_Translator = translator; /// <summary>
_Target = target;
_TargetType = targetType;
if (targetType != null)
_ExtractTarget = translator.typeChecker.getExtractor(targetType);
_Method = method;
_MethodName = method.Name;
if (method.IsStatic)
{ _BindingType = BindingFlags.Static; }
else
{ _BindingType = BindingFlags.Instance; }
}
/*
* Constructs the wrapper for a known method name
*/
public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType)
{
_Translator = translator;
_MethodName = methodName;
_TargetType = targetType;
if (targetType != null)
_ExtractTarget = translator.typeChecker.getExtractor(targetType);
_BindingType = bindingType;
//CP: Removed NonPublic binding search and added IgnoreCase
_Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/);
}
/// <summary>
/// Convert C# exceptions into Lua errors /// Convert C# exceptions into Lua errors
/// </summary> /// </summary>
/// <returns>num of things on stack</returns> /// <returns>num of things on stack</returns>
/// <param name="e">null for no pending exception</param> /// <param name="e">null for no pending exception</param>
int SetPendingException(Exception e) int SetPendingException(Exception e)
{ {
return _Translator.interpreter.SetPendingException(e); return translator.interpreter.SetPendingException(e);
} }
/* /*
* Calls the method. Receives the arguments from the Lua stack * Calls the method. Receives the arguments from the Lua stack
* and returns values in it. * and returns values in it.
*/ */
public int call(IntPtr luaState) public int call(IntPtr luaState)
{ {
MethodBase methodToCall = _Method; MethodBase methodToCall=method;
object targetObject = _Target; object targetObject=target;
bool failedCall = true; bool failedCall=true;
int nReturnValues = 0; int nReturnValues=0;
if(!LuaLib.lua_checkstack(luaState,5))
throw new LuaException("Lua stack overflow");
if (!LuaDLL.lua_checkstack(luaState, 5)) bool isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
throw new LuaException("Lua stack overflow");
bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static;
SetPendingException(null); SetPendingException(null);
if (methodToCall == null) // Method from name if(methodToCall==null) // Method from name
{ {
if (isStatic) if (isStatic)
targetObject = null; targetObject=null;
else else
targetObject = _ExtractTarget(luaState, 1); targetObject=extractTarget(luaState,1);
//LuaLib.lua_remove(luaState,1); // Pops the receiver
//LuaDLL.lua_remove(luaState,1); // Pops the receiver if(lastCalledMethod.cachedMethod!=null) // Cached?
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 numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject
int numArgsPassed = LuaDLL.lua_gettop(luaState) - numStackToSkip; int numArgsPassed = LuaLib.lua_gettop(luaState) - numStackToSkip;
if (numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? if(numArgsPassed == lastCalledMethod.argTypes.Length) // No. of args match?
{ {
if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6)) if(!LuaLib.lua_checkstack(luaState,lastCalledMethod.outList.Length+6))
throw new LuaException("Lua stack overflow"); throw new LuaException("Lua stack overflow");
try
try {
{ for(int i=0;i<lastCalledMethod.argTypes.Length;i++)
for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) {
{ lastCalledMethod.args[lastCalledMethod.argTypes[i].index]=
if (_LastCalledMethod.argTypes[i].isParamsArray) lastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip);
{
object luaParamValue = _LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip); if(lastCalledMethod.args[lastCalledMethod.argTypes[i].index]==null &&
!LuaLib.lua_isnil(luaState, i + 1 + numStackToSkip))
Type paramArrayType = _LastCalledMethod.argTypes[i].paramsArrayType; {
throw new LuaException("argument number "+(i+1)+" is invalid");
Array paramArray; }
}
if (luaParamValue is LuaTable) if((bindingType & BindingFlags.Static)==BindingFlags.Static)
{ {
LuaTable table = (LuaTable)luaParamValue; translator.push(luaState,lastCalledMethod.cachedMethod.Invoke(null,lastCalledMethod.args));
}
paramArray = Array.CreateInstance(paramArrayType, table.Values.Count); else
{
for (int x = 1; x <= table.Values.Count; x++) if(lastCalledMethod.cachedMethod.IsConstructor)
{ translator.push(luaState,((ConstructorInfo)lastCalledMethod.cachedMethod).Invoke(lastCalledMethod.args));
paramArray.SetValue(Convert.ChangeType(table[x], paramArrayType), x - 1); else
} translator.push(luaState,lastCalledMethod.cachedMethod.Invoke(targetObject,lastCalledMethod.args));
} }
else failedCall=false;
{ }
paramArray = Array.CreateInstance(paramArrayType, 1); catch(TargetInvocationException e)
paramArray.SetValue(luaParamValue, 0); {
} // Failure of method invocation
return SetPendingException(e.GetBaseException());
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = paramArray; }
} catch(Exception e)
else {
{ if(members.Length==1) // Is the method overloaded?
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = // No, throw error
_LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip); return SetPendingException(e);
} }
}
if (_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] == null && }
!LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip))
{ // Cache miss
throw new LuaException("argument number " + (i + 1) + " is invalid"); if(failedCall)
} {
}
if ((_BindingType & BindingFlags.Static) == BindingFlags.Static)
{
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args));
}
else
{
if (_LastCalledMethod.cachedMethod.IsConstructor)
_Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args));
else
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args));
}
failedCall = false;
}
catch (TargetInvocationException e)
{
// Failure of method invocation
return SetPendingException(e.GetBaseException());
}
catch (Exception e)
{
if (_Members.Length == 1) // Is the method overloaded?
// No, throw error
return SetPendingException(e);
}
}
}
// 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 we are running an instance variable, we can now pop the targetObject from the stack
if (!isStatic) if (!isStatic)
{ {
if (targetObject == null) if (targetObject == null)
{ {
_Translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", _MethodName)); translator.throwError(luaState, String.Format("instance method '{0}' requires a non null target object", methodName));
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
LuaDLL.lua_remove(luaState, 1); // Pops the receiver LuaLib.lua_remove(luaState, 1); // Pops the receiver
} }
bool hasMatch = false; bool hasMatch=false;
string candidateName = null; string candidateName = null;
foreach (MemberInfo member in _Members) foreach(MemberInfo member in members)
{ {
candidateName = member.ReflectedType.Name + "." + member.Name; candidateName = member.ReflectedType.Name + "." + member.Name;
MethodBase m = (MethodInfo)member; MethodBase m=(MethodInfo)member;
bool isMethod = _Translator.matchParameters(luaState, m, ref _LastCalledMethod); bool isMethod=translator.matchParameters(luaState,m,ref lastCalledMethod);
if (isMethod) if(isMethod)
{ {
hasMatch = true; hasMatch=true;
break; break;
} }
} }
if (!hasMatch) if(!hasMatch)
{ {
string msg = (candidateName == null) string msg = (candidateName == null)
? "invalid arguments to method call" ? "invalid arguments to method call"
: ("invalid arguments to method: " + candidateName); : ("invalid arguments to method: " + candidateName);
_Translator.throwError(luaState, msg); translator.throwError(luaState, msg);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
} }
} }
else // Method from MethodBase instance else // Method from MethodBase instance
{ {
if (methodToCall.ContainsGenericParameters) if(!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject==null)
{ {
bool isMethod = _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); targetObject=extractTarget(luaState,1);
LuaLib.lua_remove(luaState,1); // Pops the receiver
if (methodToCall.IsGenericMethodDefinition) }
{ if(!translator.matchParameters(luaState,methodToCall,ref lastCalledMethod))
//need to make a concrete type of the generic method definition {
List<Type> typeArgs = new List<Type>(); translator.throwError(luaState,"invalid arguments to method call");
LuaLib.lua_pushnil(luaState);
foreach (object arg in _LastCalledMethod.args) return 1;
typeArgs.Add(arg.GetType()); }
}
MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray());
if(failedCall)
_Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); {
failedCall = false; if(!LuaLib.lua_checkstack(luaState,lastCalledMethod.outList.Length+6))
} throw new LuaException("Lua stack overflow");
else if (methodToCall.ContainsGenericParameters) try
{ {
_Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); if (isStatic)
LuaDLL.lua_pushnil(luaState); {
return 1; translator.push(luaState,lastCalledMethod.cachedMethod.Invoke(null,lastCalledMethod.args));
} }
} else
else {
{ if(lastCalledMethod.cachedMethod.IsConstructor)
if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) translator.push(luaState,((ConstructorInfo)lastCalledMethod.cachedMethod).Invoke(lastCalledMethod.args));
{ else
targetObject = _ExtractTarget(luaState, 1); translator.push(luaState,lastCalledMethod.cachedMethod.Invoke(targetObject,lastCalledMethod.args));
LuaDLL.lua_remove(luaState, 1); // Pops the receiver }
} }
catch(TargetInvocationException e)
if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) {
{ return SetPendingException(e.GetBaseException());
_Translator.throwError(luaState, "invalid arguments to method call"); }
LuaDLL.lua_pushnil(luaState); catch(Exception e)
return 1; {
}
}
}
if (failedCall)
{
if (!LuaDLL.lua_checkstack(luaState, _LastCalledMethod.outList.Length + 6))
throw new LuaException("Lua stack overflow");
try
{
if (isStatic)
{
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args));
}
else
{
if (_LastCalledMethod.cachedMethod.IsConstructor)
_Translator.push(luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke(_LastCalledMethod.args));
else
_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(targetObject, _LastCalledMethod.args));
}
}
catch (TargetInvocationException e)
{
return SetPendingException(e.GetBaseException());
}
catch (Exception e)
{
return SetPendingException(e); return SetPendingException(e);
} }
} }
// Pushes out and ref return values
for (int index = 0; index < _LastCalledMethod.outList.Length; index++)
{
nReturnValues++;
//for(int i=0;i<lastCalledMethod.outList.Length;i++)
_Translator.push(luaState, _LastCalledMethod.args[_LastCalledMethod.outList[index]]);
}
//by isSingle 2010-09-10 11:26:31 // Pushes out and ref return values
//Desc: for(int index=0;index<lastCalledMethod.outList.Length;index++)
// if not return void,we need add 1, {
// or we will lost the function's return value nReturnValues++;
// when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code //for(int i=0;i<lastCalledMethod.outList.Length;i++)
if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0) translator.push(luaState,lastCalledMethod.args[lastCalledMethod.outList[index]]);
{ }
nReturnValues++; return nReturnValues < 1 ? 1 : nReturnValues;
} }
}
return nReturnValues < 1 ? 1 : nReturnValues;
}
}
...@@ -379,7 +275,7 @@ namespace LuaInterface ...@@ -379,7 +275,7 @@ namespace LuaInterface
/// <summary> /// <summary>
/// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session /// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session
/// </summary> /// </summary>
class EventHandlerContainer : IDisposable class EventHandlerContainer : IDisposable
{ {
Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>(); Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler>();
...@@ -409,60 +305,51 @@ namespace LuaInterface ...@@ -409,60 +305,51 @@ namespace LuaInterface
} }
/* /*
* Wrapper class for events that does registration/deregistration * Wrapper class for events that does registration/deregistration
* of event handlers. * of event handlers.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
class RegisterEventHandler class RegisterEventHandler
{ {
object target; object target;
EventInfo eventInfo; EventInfo eventInfo;
EventHandlerContainer pendingEvents; EventHandlerContainer pendingEvents;
public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo) public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo)
{ {
this.target = target; this.target=target;
this.eventInfo = eventInfo; this.eventInfo=eventInfo;
this.pendingEvents = pendingEvents; this.pendingEvents = pendingEvents;
} }
/* /*
* Adds a new event handler * Adds a new event handler
*/ */
public Delegate Add(LuaFunction function) public Delegate Add(LuaFunction function)
{ {
//CP: Fix by Ben Bryant for event handling with one parameter MethodInfo mi = eventInfo.EventHandlerType.GetMethod("Invoke");
//link: http://luaforge.net/forum/message.php?msg_id=9266 ParameterInfo[] pi = mi.GetParameters();
Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(eventInfo.EventHandlerType, function); LuaEventHandler handler=CodeGeneration.Instance.GetEvent(pi[1].ParameterType,function);
eventInfo.AddEventHandler(target, handlerDelegate);
pendingEvents.Add(handlerDelegate, this);
return handlerDelegate; Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent");
eventInfo.AddEventHandler(target,handlerDelegate);
pendingEvents.Add(handlerDelegate, this);
//MethodInfo mi = eventInfo.EventHandlerType.GetMethod("Invoke");
//ParameterInfo[] pi = mi.GetParameters();
//LuaEventHandler handler=CodeGeneration.Instance.GetEvent(pi[1].ParameterType,function);
//Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent");
//eventInfo.AddEventHandler(target,handlerDelegate);
//pendingEvents.Add(handlerDelegate, this);
//return handlerDelegate; return handlerDelegate;
} }
/* /*
* Removes an existing event handler * Removes an existing event handler
*/ */
public void Remove(Delegate handlerDelegate) public void Remove(Delegate handlerDelegate)
{ {
RemovePending(handlerDelegate); RemovePending(handlerDelegate);
pendingEvents.Remove(handlerDelegate); pendingEvents.Remove(handlerDelegate);
} }
/* /*
* Removes an existing event handler (without updating the pending handlers list) * Removes an existing event handler (without updating the pending handlers list)
...@@ -471,125 +358,119 @@ namespace LuaInterface ...@@ -471,125 +358,119 @@ namespace LuaInterface
{ {
eventInfo.RemoveEventHandler(target, handlerDelegate); eventInfo.RemoveEventHandler(target, handlerDelegate);
} }
} }
/* /*
* Base wrapper class for Lua function event handlers. * Base wrapper class for Lua function event handlers.
* Subclasses that do actual event handling are created * Subclasses that do actual event handling are created
* at runtime. * at runtime.
* *
* Author: Fabio Mascarenhas * Author: Fabio Mascarenhas
* Version: 1.0 * Version: 1.0
*/ */
public class LuaEventHandler public class LuaEventHandler
{ {
public LuaFunction handler = null; public LuaFunction handler = null;
// CP: Fix provided by Ben Bryant for delegates with one param public void handleEvent(object sender,object data)
// link: http://luaforge.net/forum/message.php?msg_id=9318 {
public void handleEvent(object[] args) handler.call(new object[] { sender,data },new Type[0]);
{ }
handler.Call(args); }
}
//public void handleEvent(object sender,object data) /*
//{ * Wrapper class for Lua functions as delegates
// handler.call(new object[] { sender,data },new Type[0]); * Subclasses with correct signatures are created
//} * at runtime.
} *
* Author: Fabio Mascarenhas
/* * Version: 1.0
* Wrapper class for Lua functions as delegates */
* Subclasses with correct signatures are created public class LuaDelegate
* at runtime. {
* public Type[] returnTypes;
* Author: Fabio Mascarenhas public LuaFunction function;
* Version: 1.0 public LuaDelegate()
*/ {
public class LuaDelegate function=null;
{ returnTypes=null;
public Type[] returnTypes; }
public LuaFunction function; public object callFunction(object[] args,object[] inArgs,int[] outArgs)
public LuaDelegate() {
{ // args is the return array of arguments, inArgs is the actual array
function = null; // of arguments passed to the function (with in parameters only), outArgs
returnTypes = null; // has the positions of out parameters
} object returnValue;
public object callFunction(object[] args, object[] inArgs, int[] outArgs) int iRefArgs;
{ object[] returnValues=function.call(inArgs,returnTypes);
// args is the return array of arguments, inArgs is the actual array if(returnTypes[0] == typeof(void))
// of arguments passed to the function (with in parameters only), outArgs {
// has the positions of out parameters returnValue=null;
object returnValue; iRefArgs=0;
int iRefArgs; }
object[] returnValues = function.call(inArgs, returnTypes); else
if (returnTypes[0] == typeof(void)) {
{ returnValue=returnValues[0];
returnValue = null; iRefArgs=1;
iRefArgs = 0; }
} // Sets the value of out and ref parameters (from
// the values returned by the Lua function).
for(int i=0;i<outArgs.Length;i++)
{
args[outArgs[i]]=returnValues[iRefArgs];
iRefArgs++;
}
return returnValue;
}
}
/*
* Static helper methods for Lua tables acting as CLR objects.
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaClassHelper
{
/*
* Gets the function called name from the provided table,
* returning null if it does not exist
*/
public static LuaFunction getTableFunction(LuaTable luaTable,string name)
{
object funcObj=luaTable.rawget(name);
if(funcObj is LuaFunction)
return (LuaFunction)funcObj;
else else
{ return null;
returnValue = returnValues[0]; }
iRefArgs = 1; /*
} * Calls the provided function with the provided parameters
// Sets the value of out and ref parameters (from */
// the values returned by the Lua function). public static object callFunction(LuaFunction function,object[] args,Type[] returnTypes,object[] inArgs,int[] outArgs)
for (int i = 0; i < outArgs.Length; i++) {
{ // args is the return array of arguments, inArgs is the actual array
args[outArgs[i]] = returnValues[iRefArgs]; // of arguments passed to the function (with in parameters only), outArgs
iRefArgs++; // has the positions of out parameters
} object returnValue;
return returnValue; int iRefArgs;
} object[] returnValues=function.call(inArgs,returnTypes);
} if(returnTypes[0] == typeof(void))
{
/* returnValue=null;
* Static helper methods for Lua tables acting as CLR objects. iRefArgs=0;
* }
* Author: Fabio Mascarenhas else
* Version: 1.0 {
*/ returnValue=returnValues[0];
public class LuaClassHelper iRefArgs=1;
{ }
/* for(int i=0;i<outArgs.Length;i++)
* Gets the function called name from the provided table, {
* returning null if it does not exist args[outArgs[i]]=returnValues[iRefArgs];
*/ iRefArgs++;
public static LuaFunction getTableFunction(LuaTable luaTable, string name) }
{ return returnValue;
object funcObj = luaTable.rawget(name); }
if (funcObj is LuaFunction) }
return (LuaFunction)funcObj;
else
return null;
}
/*
* Calls the provided function with the provided parameters
*/
public static object callFunction(LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs)
{
// args is the return array of arguments, inArgs is the actual array
// of arguments passed to the function (with in parameters only), outArgs
// has the positions of out parameters
object returnValue;
int iRefArgs;
object[] returnValues = function.call(inArgs, returnTypes);
if (returnTypes[0] == typeof(void))
{
returnValue = null;
iRefArgs = 0;
}
else
{
returnValue = returnValues[0];
iRefArgs = 1;
}
for (int i = 0; i < outArgs.Length; i++)
{
args[outArgs[i]] = returnValues[iRefArgs];
iRefArgs++;
}
return returnValue;
}
}
} }
...@@ -6,7 +6,7 @@ namespace LuaInterface ...@@ -6,7 +6,7 @@ namespace LuaInterface
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Lua511; using LuaWrap;
/* /*
* Passes objects from the CLR to Lua and vice-versa * Passes objects from the CLR to Lua and vice-versa
...@@ -25,7 +25,7 @@ namespace LuaInterface ...@@ -25,7 +25,7 @@ namespace LuaInterface
internal Lua interpreter; internal Lua interpreter;
private MetaFunctions metaFunctions; private MetaFunctions metaFunctions;
private List<Assembly> assemblies; private List<Assembly> assemblies;
private LuaCSFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction, private CallbackFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction,
getConstructorSigFunction,importTypeFunction,loadAssemblyFunction; getConstructorSigFunction,importTypeFunction,loadAssemblyFunction;
internal EventHandlerContainer pendingEvents = new EventHandlerContainer(); internal EventHandlerContainer pendingEvents = new EventHandlerContainer();
...@@ -37,12 +37,12 @@ namespace LuaInterface ...@@ -37,12 +37,12 @@ namespace LuaInterface
metaFunctions=new MetaFunctions(this); metaFunctions=new MetaFunctions(this);
assemblies=new List<Assembly>(); assemblies=new List<Assembly>();
importTypeFunction=new LuaCSFunction(this.importType); importTypeFunction=new CallbackFunction(this.importType);
loadAssemblyFunction=new LuaCSFunction(this.loadAssembly); loadAssemblyFunction=new CallbackFunction(this.loadAssembly);
registerTableFunction=new LuaCSFunction(this.registerTable); registerTableFunction=new CallbackFunction(this.registerTable);
unregisterTableFunction=new LuaCSFunction(this.unregisterTable); unregisterTableFunction=new CallbackFunction(this.unregisterTable);
getMethodSigFunction=new LuaCSFunction(this.getMethodSignature); getMethodSigFunction=new CallbackFunction(this.getMethodSignature);
getConstructorSigFunction=new LuaCSFunction(this.getConstructorSignature); getConstructorSigFunction=new CallbackFunction(this.getConstructorSignature);
createLuaObjectList(luaState); createLuaObjectList(luaState);
createIndexingMetaFunction(luaState); createIndexingMetaFunction(luaState);
...@@ -57,14 +57,14 @@ namespace LuaInterface ...@@ -57,14 +57,14 @@ namespace LuaInterface
*/ */
private void createLuaObjectList(IntPtr luaState) private void createLuaObjectList(IntPtr luaState)
{ {
LuaDLL.lua_pushstring(luaState,"luaNet_objects"); LuaLib.lua_pushstring(luaState,"luaNet_objects");
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_pushstring(luaState,"__mode"); LuaLib.lua_pushstring(luaState,"__mode");
LuaDLL.lua_pushstring(luaState,"v"); LuaLib.lua_pushstring(luaState,"v");
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_setmetatable(luaState,-2); LuaLib.lua_setmetatable(luaState,-2);
LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_settable(luaState, (int) PseudoIndex.Registry);
} }
/* /*
* Registers the indexing function of CLR objects * Registers the indexing function of CLR objects
...@@ -72,10 +72,10 @@ namespace LuaInterface ...@@ -72,10 +72,10 @@ namespace LuaInterface
*/ */
private void createIndexingMetaFunction(IntPtr luaState) private void createIndexingMetaFunction(IntPtr luaState)
{ {
LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction"); LuaLib.lua_pushstring(luaState,"luaNet_indexfunction");
LuaDLL.luaL_dostring(luaState,MetaFunctions.luaIndexFunction); // steffenj: lua_dostring renamed to luaL_dostring LuaLib.luaL_dostring(luaState,MetaFunctions.luaIndexFunction); // steffenj: lua_dostring renamed to luaL_dostring
//LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction); //LuaLib.lua_pushstdcallcfunction(luaState,indexFunction);
LuaDLL.lua_rawset(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_rawset(luaState, (int) PseudoIndex.Registry);
} }
/* /*
* Creates the metatable for superclasses (the base * Creates the metatable for superclasses (the base
...@@ -83,151 +83,131 @@ namespace LuaInterface ...@@ -83,151 +83,131 @@ namespace LuaInterface
*/ */
private void createBaseClassMetatable(IntPtr luaState) private void createBaseClassMetatable(IntPtr luaState)
{ {
LuaDLL.luaL_newmetatable(luaState,"luaNet_searchbase"); LuaLib.luaL_newmetatable(luaState,"luaNet_searchbase");
LuaDLL.lua_pushstring(luaState,"__gc"); LuaLib.lua_pushstring(luaState,"__gc");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__tostring"); LuaLib.lua_pushstring(luaState,"__tostring");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__index"); LuaLib.lua_pushstring(luaState,"__index");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__newindex"); LuaLib.lua_pushstring(luaState,"__newindex");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
} }
/* /*
* Creates the metatable for type references * Creates the metatable for type references
*/ */
private void createClassMetatable(IntPtr luaState) private void createClassMetatable(IntPtr luaState)
{ {
LuaDLL.luaL_newmetatable(luaState,"luaNet_class"); LuaLib.luaL_newmetatable(luaState,"luaNet_class");
LuaDLL.lua_pushstring(luaState,"__gc"); LuaLib.lua_pushstring(luaState,"__gc");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__tostring"); LuaLib.lua_pushstring(luaState,"__tostring");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__index"); LuaLib.lua_pushstring(luaState,"__index");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__newindex"); LuaLib.lua_pushstring(luaState,"__newindex");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__call"); LuaLib.lua_pushstring(luaState,"__call");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
} }
/* /*
* Registers the global functions used by LuaInterface * Registers the global functions used by LuaInterface
*/ */
private void setGlobalFunctions(IntPtr luaState) private void setGlobalFunctions(IntPtr luaState)
{ {
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction);
LuaDLL.lua_setglobal(luaState,"get_object_member"); LuaLib.lua_setglobal(luaState,"get_object_member");
LuaDLL.lua_pushstdcallcfunction(luaState,importTypeFunction); LuaLib.lua_pushstdcallcfunction(luaState,importTypeFunction);
LuaDLL.lua_setglobal(luaState,"import_type"); LuaLib.lua_setglobal(luaState,"import_type");
LuaDLL.lua_pushstdcallcfunction(luaState,loadAssemblyFunction); LuaLib.lua_pushstdcallcfunction(luaState,loadAssemblyFunction);
LuaDLL.lua_setglobal(luaState,"load_assembly"); LuaLib.lua_setglobal(luaState,"load_assembly");
LuaDLL.lua_pushstdcallcfunction(luaState,registerTableFunction); LuaLib.lua_pushstdcallcfunction(luaState,registerTableFunction);
LuaDLL.lua_setglobal(luaState,"make_object"); LuaLib.lua_setglobal(luaState,"make_object");
LuaDLL.lua_pushstdcallcfunction(luaState,unregisterTableFunction); LuaLib.lua_pushstdcallcfunction(luaState,unregisterTableFunction);
LuaDLL.lua_setglobal(luaState,"free_object"); LuaLib.lua_setglobal(luaState,"free_object");
LuaDLL.lua_pushstdcallcfunction(luaState,getMethodSigFunction); LuaLib.lua_pushstdcallcfunction(luaState,getMethodSigFunction);
LuaDLL.lua_setglobal(luaState,"get_method_bysig"); LuaLib.lua_setglobal(luaState,"get_method_bysig");
LuaDLL.lua_pushstdcallcfunction(luaState,getConstructorSigFunction); LuaLib.lua_pushstdcallcfunction(luaState,getConstructorSigFunction);
LuaDLL.lua_setglobal(luaState,"get_constructor_bysig"); LuaLib.lua_setglobal(luaState,"get_constructor_bysig");
} }
/* /*
* Creates the metatable for delegates * Creates the metatable for delegates
*/ */
private void createFunctionMetatable(IntPtr luaState) private void createFunctionMetatable(IntPtr luaState)
{ {
LuaDLL.luaL_newmetatable(luaState,"luaNet_function"); LuaLib.luaL_newmetatable(luaState,"luaNet_function");
LuaDLL.lua_pushstring(luaState,"__gc"); LuaLib.lua_pushstring(luaState,"__gc");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__call"); LuaLib.lua_pushstring(luaState,"__call");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction);
LuaDLL.lua_settable(luaState,-3); LuaLib.lua_settable(luaState,-3);
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
} }
/* /*
* Passes errors (argument e) to the Lua interpreter * Passes errors (argument e) to the Lua interpreter
*/ */
internal void throwError(IntPtr luaState, object e) internal void throwError(IntPtr luaState,object e)
{ {
// We use this to remove anything pushed by luaL_where // 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)
int oldTop = LuaDLL.lua_gettop(luaState); if (e is string)
{
// Stack frame #1 is our C# wrapper, so not very interesting to the user // We use this to remove anything pushed by luaL_where
// Stack frame #2 must be the lua code that called us, so that's what we want to use int oldTop = LuaLib.lua_gettop(luaState);
LuaDLL.luaL_where(luaState, 1);
object[] curlev = popValues(luaState, oldTop);
// Determine the position in the script where the exception was triggered // Stack frame #1 is our C# wrapper, so not very interesting to the user
string errLocation = ""; // Stack frame #2 must be the lua code that called us, so that's what we want to use
if (curlev.Length > 0) LuaLib.luaL_where(luaState, 2);
errLocation = curlev[0].ToString(); object[] curlev = popValues(luaState, oldTop);
// Debug.WriteLine(curlev);
string message = e as string; if (curlev.Length > 0)
if (message != null) e = curlev[0].ToString() + e;
{
// Wrap Lua error (just a string) and store the error location
e = new LuaScriptException(message, errLocation);
}
else
{
Exception ex = e as Exception;
if (ex != null)
{
// Wrap generic .NET exception as an InnerException and store the error location
e = new LuaScriptException(ex, errLocation);
}
} }
push(luaState, e); push(luaState,e);
LuaDLL.lua_error(luaState); LuaLib.lua_error(luaState);
} }
/* /*
* Implementation of load_assembly. Throws an error * Implementation of load_assembly. Throws an error
* if the assembly is not found. * if the assembly is not found.
*/ */
private int loadAssembly(IntPtr luaState) private int loadAssembly(IntPtr luaState)
{ {
try string assemblyName=LuaLib.lua_tostring(luaState,1);
{ try
string assemblyName=LuaDLL.lua_tostring(luaState,1); {
Assembly assembly=Assembly.LoadWithPartialName(assemblyName);
Assembly assembly = null;
try try
{ {
assembly = Assembly.LoadWithPartialName(assemblyName); // 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)
catch (BadImageFormatException) assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
{
// The assemblyName was invalid. It is most likely a path.
} }
catch (Exception)
if (assembly == null)
{ {
assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName)); // ignore - it might not even be a filename
} }
if (assembly != null && !assemblies.Contains(assembly)) if(assembly!=null && !assemblies.Contains(assembly))
{ assemblies.Add(assembly);
assemblies.Add(assembly); }
}
}
catch(Exception e) catch(Exception e)
{ {
throwError(luaState,e); throwError(luaState,e);
} }
return 0; return 0;
} }
...@@ -250,12 +230,12 @@ namespace LuaInterface ...@@ -250,12 +230,12 @@ namespace LuaInterface
*/ */
private int importType(IntPtr luaState) private int importType(IntPtr luaState)
{ {
string className=LuaDLL.lua_tostring(luaState,1); string className=LuaLib.lua_tostring(luaState,1);
Type klass=FindType(className); Type klass=FindType(className);
if(klass!=null) if(klass!=null)
pushType(luaState,klass); pushType(luaState,klass);
else else
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
/* /*
...@@ -265,10 +245,10 @@ namespace LuaInterface ...@@ -265,10 +245,10 @@ namespace LuaInterface
*/ */
private int registerTable(IntPtr luaState) private int registerTable(IntPtr luaState)
{ {
if(LuaDLL.lua_type(luaState,1)==LuaTypes.LUA_TTABLE) if(LuaLib.lua_type(luaState,1)==LuaType.Table)
{ {
LuaTable luaTable=getTable(luaState,1); LuaTable luaTable=getTable(luaState,1);
string superclassName = LuaDLL.lua_tostring(luaState, 2); string superclassName = LuaLib.lua_tostring(luaState, 2);
if (superclassName != null) if (superclassName != null)
{ {
Type klass = FindType(superclassName); Type klass = FindType(superclassName);
...@@ -278,20 +258,20 @@ namespace LuaInterface ...@@ -278,20 +258,20 @@ namespace LuaInterface
// it as the metatable of the first argument // it as the metatable of the first argument
object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable); object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
pushObject(luaState, obj, "luaNet_metatable"); pushObject(luaState, obj, "luaNet_metatable");
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_pushstring(luaState, "__index"); LuaLib.lua_pushstring(luaState, "__index");
LuaDLL.lua_pushvalue(luaState, -3); LuaLib.lua_pushvalue(luaState, -3);
LuaDLL.lua_settable(luaState, -3); LuaLib.lua_settable(luaState, -3);
LuaDLL.lua_pushstring(luaState, "__newindex"); LuaLib.lua_pushstring(luaState, "__newindex");
LuaDLL.lua_pushvalue(luaState, -3); LuaLib.lua_pushvalue(luaState, -3);
LuaDLL.lua_settable(luaState, -3); LuaLib.lua_settable(luaState, -3);
LuaDLL.lua_setmetatable(luaState, 1); LuaLib.lua_setmetatable(luaState, 1);
// Pushes the object again, this time as the base field // Pushes the object again, this time as the base field
// of the table and with the luaNet_searchbase metatable // of the table and with the luaNet_searchbase metatable
LuaDLL.lua_pushstring(luaState, "base"); LuaLib.lua_pushstring(luaState, "base");
int index = addObject(obj); int index = addObject(obj);
pushNewObject(luaState, obj, index, "luaNet_searchbase"); pushNewObject(luaState, obj, index, "luaNet_searchbase");
LuaDLL.lua_rawset(luaState, 1); LuaLib.lua_rawset(luaState, 1);
} }
else else
throwError(luaState, "register_table: can not find superclass '" + superclassName + "'"); throwError(luaState, "register_table: can not find superclass '" + superclassName + "'");
...@@ -310,20 +290,20 @@ namespace LuaInterface ...@@ -310,20 +290,20 @@ namespace LuaInterface
{ {
try try
{ {
if(LuaDLL.lua_getmetatable(luaState,1)!=0) if(LuaLib.lua_getmetatable(luaState,1)!=0)
{ {
LuaDLL.lua_pushstring(luaState,"__index"); LuaLib.lua_pushstring(luaState,"__index");
LuaDLL.lua_gettable(luaState,-2); LuaLib.lua_gettable(luaState,-2);
object obj=getRawNetObject(luaState,-1); object obj=getRawNetObject(luaState,-1);
if(obj==null) throwError(luaState,"unregister_table: arg is not valid table"); if(obj==null) throwError(luaState,"unregister_table: arg is not valid table");
FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable"); FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable");
if(luaTableField==null) throwError(luaState,"unregister_table: arg is not valid table"); if(luaTableField==null) throwError(luaState,"unregister_table: arg is not valid table");
luaTableField.SetValue(obj,null); luaTableField.SetValue(obj,null);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
LuaDLL.lua_setmetatable(luaState,1); LuaLib.lua_setmetatable(luaState,1);
LuaDLL.lua_pushstring(luaState,"base"); LuaLib.lua_pushstring(luaState,"base");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
LuaDLL.lua_settable(luaState,1); LuaLib.lua_settable(luaState,1);
} }
else throwError(luaState,"unregister_table: arg is not valid table"); else throwError(luaState,"unregister_table: arg is not valid table");
} }
...@@ -340,7 +320,7 @@ namespace LuaInterface ...@@ -340,7 +320,7 @@ namespace LuaInterface
private int getMethodSignature(IntPtr luaState) private int getMethodSignature(IntPtr luaState)
{ {
IReflect klass; object target; IReflect klass; object target;
int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class"); int udata=LuaLib.luanet_checkudata(luaState,1,"luaNet_class");
if(udata!=-1) if(udata!=-1)
{ {
klass=(IReflect)objects[udata]; klass=(IReflect)objects[udata];
...@@ -352,26 +332,25 @@ namespace LuaInterface ...@@ -352,26 +332,25 @@ namespace LuaInterface
if(target==null) if(target==null)
{ {
throwError(luaState,"get_method_bysig: first arg is not type or object reference"); throwError(luaState,"get_method_bysig: first arg is not type or object reference");
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return 1; return 1;
} }
klass=target.GetType(); klass=target.GetType();
} }
string methodName=LuaDLL.lua_tostring(luaState,2); string methodName=LuaLib.lua_tostring(luaState,2);
Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-2]; Type[] signature=new Type[LuaLib.lua_gettop(luaState)-2];
for(int i=0;i<signature.Length;i++) for(int i=0;i<signature.Length;i++)
signature[i]=FindType(LuaDLL.lua_tostring(luaState,i+3)); signature[i]=FindType(LuaLib.lua_tostring(luaState,i+3));
try try
{ {
//CP: Added ignore case
MethodInfo method=klass.GetMethod(methodName,BindingFlags.Public | BindingFlags.Static | MethodInfo method=klass.GetMethod(methodName,BindingFlags.Public | BindingFlags.Static |
BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase, null, signature, null); BindingFlags.Instance | BindingFlags.FlattenHierarchy,null,signature,null);
pushFunction(luaState,new LuaCSFunction((new LuaMethodWrapper(this,target,klass,method)).call)); pushFunction(luaState,new CallbackFunction((new LuaMethodWrapper(this,target,klass,method)).call));
} }
catch(Exception e) catch(Exception e)
{ {
throwError(luaState,e); throwError(luaState,e);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
return 1; return 1;
} }
...@@ -382,7 +361,7 @@ namespace LuaInterface ...@@ -382,7 +361,7 @@ namespace LuaInterface
private int getConstructorSignature(IntPtr luaState) private int getConstructorSignature(IntPtr luaState)
{ {
IReflect klass=null; IReflect klass=null;
int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class"); int udata=LuaLib.luanet_checkudata(luaState,1,"luaNet_class");
if(udata!=-1) if(udata!=-1)
{ {
klass=(IReflect)objects[udata]; klass=(IReflect)objects[udata];
...@@ -391,18 +370,18 @@ namespace LuaInterface ...@@ -391,18 +370,18 @@ namespace LuaInterface
{ {
throwError(luaState,"get_constructor_bysig: first arg is invalid type reference"); throwError(luaState,"get_constructor_bysig: first arg is invalid type reference");
} }
Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-1]; Type[] signature=new Type[LuaLib.lua_gettop(luaState)-1];
for(int i=0;i<signature.Length;i++) for(int i=0;i<signature.Length;i++)
signature[i]=FindType(LuaDLL.lua_tostring(luaState,i+2)); signature[i]=FindType(LuaLib.lua_tostring(luaState,i+2));
try try
{ {
ConstructorInfo constructor=klass.UnderlyingSystemType.GetConstructor(signature); ConstructorInfo constructor=klass.UnderlyingSystemType.GetConstructor(signature);
pushFunction(luaState,new LuaCSFunction((new LuaMethodWrapper(this,null,klass,constructor)).call)); pushFunction(luaState,new CallbackFunction((new LuaMethodWrapper(this,null,klass,constructor)).call));
} }
catch(Exception e) catch(Exception e)
{ {
throwError(luaState,e); throwError(luaState,e);
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
return 1; return 1;
} }
...@@ -416,7 +395,7 @@ namespace LuaInterface ...@@ -416,7 +395,7 @@ namespace LuaInterface
/* /*
* Pushes a delegate into the stack * Pushes a delegate into the stack
*/ */
internal void pushFunction(IntPtr luaState, LuaCSFunction func) internal void pushFunction(IntPtr luaState, CallbackFunction func)
{ {
pushObject(luaState,func,"luaNet_function"); pushObject(luaState,func,"luaNet_function");
} }
...@@ -430,7 +409,7 @@ namespace LuaInterface ...@@ -430,7 +409,7 @@ namespace LuaInterface
// Pushes nil // Pushes nil
if(o==null) if(o==null)
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
return; return;
} }
...@@ -438,25 +417,25 @@ namespace LuaInterface ...@@ -438,25 +417,25 @@ namespace LuaInterface
bool found = objectsBackMap.TryGetValue(o, out index); bool found = objectsBackMap.TryGetValue(o, out index);
if(found) if(found)
{ {
LuaDLL.luaL_getmetatable(luaState,"luaNet_objects"); LuaLib.luaL_getmetatable(luaState,"luaNet_objects");
LuaDLL.lua_rawgeti(luaState,-1,index); LuaLib.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 // 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 // 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 // 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 // object here
// did we find a non nil object in our table? if not, we need to call collect object // did we find a non nil object in our table? if not, we need to call collect object
LuaTypes type = LuaDLL.lua_type(luaState, -1); LuaType type = LuaLib.lua_type(luaState, -1);
if (type != LuaTypes.LUA_TNIL) if (type != LuaType.Nil)
{ {
LuaDLL.lua_remove(luaState, -2); // drop the metatable - we're going to leave our object on the stack LuaLib.lua_remove(luaState, -2); // drop the metatable - we're going to leave our object on the stack
return; return;
} }
// MetaFunctions.dumpStack(this, luaState); // MetaFunctions.dumpStack(this, luaState);
LuaDLL.lua_remove(luaState, -1); // remove the nil object value LuaLib.lua_remove(luaState, -1); // remove the nil object value
LuaDLL.lua_remove(luaState, -1); // remove the metatable LuaLib.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
} }
...@@ -475,48 +454,48 @@ namespace LuaInterface ...@@ -475,48 +454,48 @@ namespace LuaInterface
if(metatable=="luaNet_metatable") if(metatable=="luaNet_metatable")
{ {
// Gets or creates the metatable for the object's type // Gets or creates the metatable for the object's type
LuaDLL.luaL_getmetatable(luaState,o.GetType().AssemblyQualifiedName); LuaLib.luaL_getmetatable(luaState,o.GetType().AssemblyQualifiedName);
if(LuaDLL.lua_isnil(luaState,-1)) if(LuaLib.lua_isnil(luaState,-1))
{ {
LuaDLL.lua_settop(luaState,-2); LuaLib.lua_settop(luaState,-2);
LuaDLL.luaL_newmetatable(luaState,o.GetType().AssemblyQualifiedName); LuaLib.luaL_newmetatable(luaState,o.GetType().AssemblyQualifiedName);
LuaDLL.lua_pushstring(luaState,"cache"); LuaLib.lua_pushstring(luaState,"cache");
LuaDLL.lua_newtable(luaState); LuaLib.lua_newtable(luaState);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
LuaDLL.lua_pushlightuserdata(luaState,LuaDLL.luanet_gettag()); LuaLib.lua_pushlightuserdata(luaState,LuaLib.luanet_gettag());
LuaDLL.lua_pushnumber(luaState,1); LuaLib.lua_pushnumber(luaState,1);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__index"); LuaLib.lua_pushstring(luaState,"__index");
LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction"); LuaLib.lua_pushstring(luaState,"luaNet_indexfunction");
LuaDLL.lua_rawget(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); LuaLib.lua_rawget(luaState, (int) PseudoIndex.Registry);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__gc"); LuaLib.lua_pushstring(luaState,"__gc");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__tostring"); LuaLib.lua_pushstring(luaState,"__tostring");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
LuaDLL.lua_pushstring(luaState,"__newindex"); LuaLib.lua_pushstring(luaState,"__newindex");
LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction); LuaLib.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
LuaDLL.lua_rawset(luaState,-3); LuaLib.lua_rawset(luaState,-3);
} }
} }
else else
{ {
LuaDLL.luaL_getmetatable(luaState,metatable); LuaLib.luaL_getmetatable(luaState,metatable);
} }
// Stores the object index in the Lua list and pushes the // Stores the object index in the Lua list and pushes the
// index into the Lua stack // index into the Lua stack
LuaDLL.luaL_getmetatable(luaState,"luaNet_objects"); LuaLib.luaL_getmetatable(luaState,"luaNet_objects");
LuaDLL.luanet_newudata(luaState,index); LuaLib.luanet_newudata(luaState,index);
LuaDLL.lua_pushvalue(luaState,-3); LuaLib.lua_pushvalue(luaState,-3);
LuaDLL.lua_remove(luaState,-4); LuaLib.lua_remove(luaState,-4);
LuaDLL.lua_setmetatable(luaState,-2); LuaLib.lua_setmetatable(luaState,-2);
LuaDLL.lua_pushvalue(luaState,-1); LuaLib.lua_pushvalue(luaState,-1);
LuaDLL.lua_rawseti(luaState,-3,index); LuaLib.lua_rawseti(luaState,-3,index);
LuaDLL.lua_remove(luaState,-2); LuaLib.lua_remove(luaState,-2);
} }
/* /*
* Gets an object from the Lua stack with the desired type, if it matches, otherwise * Gets an object from the Lua stack with the desired type, if it matches, otherwise
...@@ -588,32 +567,32 @@ namespace LuaInterface ...@@ -588,32 +567,32 @@ namespace LuaInterface
*/ */
internal object getObject(IntPtr luaState,int index) internal object getObject(IntPtr luaState,int index)
{ {
LuaTypes type=LuaDLL.lua_type(luaState,index); LuaType type=LuaLib.lua_type(luaState,index);
switch(type) switch(type)
{ {
case LuaTypes.LUA_TNUMBER: case LuaType.Number:
{ {
return LuaDLL.lua_tonumber(luaState,index); return LuaLib.lua_tonumber(luaState,index);
} }
case LuaTypes.LUA_TSTRING: case LuaType.String:
{ {
return LuaDLL.lua_tostring(luaState,index); return LuaLib.lua_tostring(luaState,index);
} }
case LuaTypes.LUA_TBOOLEAN: case LuaType.Boolean:
{ {
return LuaDLL.lua_toboolean(luaState,index); return LuaLib.lua_toboolean(luaState,index);
} }
case LuaTypes.LUA_TTABLE: case LuaType.Table:
{ {
return getTable(luaState,index); return getTable(luaState,index);
} }
case LuaTypes.LUA_TFUNCTION: case LuaType.Function:
{ {
return getFunction(luaState,index); return getFunction(luaState,index);
} }
case LuaTypes.LUA_TUSERDATA: case LuaType.UserData:
{ {
int udata=LuaDLL.luanet_tonetobject(luaState,index); int udata=LuaLib.luanet_tonetobject(luaState,index);
if(udata!=-1) if(udata!=-1)
return objects[udata]; return objects[udata];
else else
...@@ -628,24 +607,24 @@ namespace LuaInterface ...@@ -628,24 +607,24 @@ namespace LuaInterface
*/ */
internal LuaTable getTable(IntPtr luaState,int index) internal LuaTable getTable(IntPtr luaState,int index)
{ {
LuaDLL.lua_pushvalue(luaState,index); LuaLib.lua_pushvalue(luaState,index);
return new LuaTable(LuaDLL.lua_ref(luaState,1),interpreter); return new LuaTable(LuaLib.lua_ref(luaState,1),interpreter);
} }
/* /*
* Gets the userdata in the index positon of the Lua stack. * Gets the userdata in the index positon of the Lua stack.
*/ */
internal LuaUserData getUserData(IntPtr luaState,int index) internal LuaUserData getUserData(IntPtr luaState,int index)
{ {
LuaDLL.lua_pushvalue(luaState,index); LuaLib.lua_pushvalue(luaState,index);
return new LuaUserData(LuaDLL.lua_ref(luaState,1),interpreter); return new LuaUserData(LuaLib.lua_ref(luaState,1),interpreter);
} }
/* /*
* Gets the function in the index positon of the Lua stack. * Gets the function in the index positon of the Lua stack.
*/ */
internal LuaFunction getFunction(IntPtr luaState,int index) internal LuaFunction getFunction(IntPtr luaState,int index)
{ {
LuaDLL.lua_pushvalue(luaState,index); LuaLib.lua_pushvalue(luaState,index);
return new LuaFunction(LuaDLL.lua_ref(luaState,1),interpreter); return new LuaFunction(LuaLib.lua_ref(luaState,1),interpreter);
} }
/* /*
* Gets the CLR object in the index positon of the Lua stack. Returns * Gets the CLR object in the index positon of the Lua stack. Returns
...@@ -653,7 +632,7 @@ namespace LuaInterface ...@@ -653,7 +632,7 @@ namespace LuaInterface
*/ */
internal object getNetObject(IntPtr luaState,int index) internal object getNetObject(IntPtr luaState,int index)
{ {
int idx=LuaDLL.luanet_tonetobject(luaState,index); int idx=LuaLib.luanet_tonetobject(luaState,index);
if(idx!=-1) if(idx!=-1)
return objects[idx]; return objects[idx];
else else
...@@ -665,7 +644,7 @@ namespace LuaInterface ...@@ -665,7 +644,7 @@ namespace LuaInterface
*/ */
internal object getRawNetObject(IntPtr luaState,int index) internal object getRawNetObject(IntPtr luaState,int index)
{ {
int udata=LuaDLL.luanet_rawnetobj(luaState,index); int udata=LuaLib.luanet_rawnetobj(luaState,index);
if(udata!=-1) if(udata!=-1)
{ {
return objects[udata]; return objects[udata];
...@@ -678,7 +657,7 @@ namespace LuaInterface ...@@ -678,7 +657,7 @@ namespace LuaInterface
*/ */
internal int returnValues(IntPtr luaState, object[] returnValues) internal int returnValues(IntPtr luaState, object[] returnValues)
{ {
if(LuaDLL.lua_checkstack(luaState,returnValues.Length+5)) if(LuaLib.lua_checkstack(luaState,returnValues.Length+5))
{ {
for(int i=0;i<returnValues.Length;i++) for(int i=0;i<returnValues.Length;i++)
{ {
...@@ -694,7 +673,7 @@ namespace LuaInterface ...@@ -694,7 +673,7 @@ namespace LuaInterface
*/ */
internal object[] popValues(IntPtr luaState,int oldTop) internal object[] popValues(IntPtr luaState,int oldTop)
{ {
int newTop=LuaDLL.lua_gettop(luaState); int newTop=LuaLib.lua_gettop(luaState);
if(oldTop==newTop) if(oldTop==newTop)
{ {
return null; return null;
...@@ -706,7 +685,7 @@ namespace LuaInterface ...@@ -706,7 +685,7 @@ namespace LuaInterface
{ {
returnValues.Add(getObject(luaState,i)); returnValues.Add(getObject(luaState,i));
} }
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return returnValues.ToArray(); return returnValues.ToArray();
} }
} }
...@@ -717,7 +696,7 @@ namespace LuaInterface ...@@ -717,7 +696,7 @@ namespace LuaInterface
*/ */
internal object[] popValues(IntPtr luaState,int oldTop,Type[] popTypes) internal object[] popValues(IntPtr luaState,int oldTop,Type[] popTypes)
{ {
int newTop=LuaDLL.lua_gettop(luaState); int newTop=LuaLib.lua_gettop(luaState);
if(oldTop==newTop) if(oldTop==newTop)
{ {
return null; return null;
...@@ -735,7 +714,7 @@ namespace LuaInterface ...@@ -735,7 +714,7 @@ namespace LuaInterface
returnValues.Add(getAsType(luaState,i,popTypes[iTypes])); returnValues.Add(getAsType(luaState,i,popTypes[iTypes]));
iTypes++; iTypes++;
} }
LuaDLL.lua_settop(luaState,oldTop); LuaLib.lua_settop(luaState,oldTop);
return returnValues.ToArray(); return returnValues.ToArray();
} }
} }
...@@ -762,29 +741,29 @@ namespace LuaInterface ...@@ -762,29 +741,29 @@ namespace LuaInterface
{ {
if(o==null) if(o==null)
{ {
LuaDLL.lua_pushnil(luaState); LuaLib.lua_pushnil(luaState);
} }
else if(o is sbyte || o is byte || o is short || o is ushort || 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 int || o is uint || o is long || o is float ||
o is ulong || o is decimal || o is double) o is ulong || o is decimal || o is double)
{ {
double d=Convert.ToDouble(o); double d=Convert.ToDouble(o);
LuaDLL.lua_pushnumber(luaState,d); LuaLib.lua_pushnumber(luaState,d);
} }
else if(o is char) else if(o is char)
{ {
double d = (char)o; double d = (char)o;
LuaDLL.lua_pushnumber(luaState,d); LuaLib.lua_pushnumber(luaState,d);
} }
else if(o is string) else if(o is string)
{ {
string str=(string)o; string str=(string)o;
LuaDLL.lua_pushstring(luaState,str); LuaLib.lua_pushstring(luaState,str);
} }
else if(o is bool) else if(o is bool)
{ {
bool b=(bool)o; bool b=(bool)o;
LuaDLL.lua_pushboolean(luaState,b); LuaLib.lua_pushboolean(luaState,b);
} }
else if(IsILua(o)) else if(IsILua(o))
{ {
...@@ -794,9 +773,9 @@ namespace LuaInterface ...@@ -794,9 +773,9 @@ namespace LuaInterface
{ {
((LuaTable)o).push(luaState); ((LuaTable)o).push(luaState);
} }
else if(o is LuaCSFunction) else if(o is CallbackFunction)
{ {
pushFunction(luaState,(LuaCSFunction)o); pushFunction(luaState,(CallbackFunction)o);
} }
else if(o is LuaFunction) else if(o is LuaFunction)
{ {
......
//
// AssemblyInfo.cs
//
// Author:
// Joshua Simmons <simmons.44@gmail.com>
//
// Copyright (c) 2009 Joshua Simmons
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("LuaWrap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
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