Commit 279f84a8 authored by Vinicius Jarina's avatar Vinicius Jarina
Browse files

Add support to Interface on iOS

parent ead94f06
...@@ -155,10 +155,8 @@ namespace LuaInterface ...@@ -155,10 +155,8 @@ namespace LuaInterface
} }
else if(typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.Function) else if(typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.Function)
return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated);
#if !MONOTOUCH
else if(paramType.IsInterface && luatype == LuaTypes.Table) else if(paramType.IsInterface && luatype == LuaTypes.Table)
return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated);
#endif
else if((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.Nil) else if((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.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
......
...@@ -308,6 +308,30 @@ namespace LuaInterface ...@@ -308,6 +308,30 @@ namespace LuaInterface
#endif #endif
} }
void GetReturnTypesFromClass (Type klass, out Type[][] returnTypes)
{
var classMethods = klass.GetMethods();
returnTypes = new Type[classMethods.Length][];
int i = 0;
foreach(var method in classMethods)
{
if(klass.IsInterface)
{
GetReturnTypesFromMethod (method, out returnTypes[i]);
i++;
}
else
{
if(!method.IsPrivate && !method.IsFinal && method.IsVirtual) {
GetReturnTypesFromMethod (method, out returnTypes[i]);
i++;
}
}
}
}
/* /*
* Generates an implementation of klass, if it is an interface, or * Generates an implementation of klass, if it is an interface, or
* a subclass of klass that delegates its virtual methods to a Lua table. * a subclass of klass that delegates its virtual methods to a Lua table.
...@@ -387,6 +411,37 @@ namespace LuaInterface ...@@ -387,6 +411,37 @@ namespace LuaInterface
newType = myType.CreateType(); // Creates the type newType = myType.CreateType(); // Creates the type
#endif #endif
} }
void GetReturnTypesFromMethod (MethodInfo method, out Type[] returnTypes)
{
var paramInfo = method.GetParameters();
var paramTypes = new Type[paramInfo.Length];
var returnTypesList = new List<Type>();
// Counts out and ref parameters, for later use,
// and creates the list of return types
int nOutParams = 0;
int nOutAndRefParams = 0;
var returnType = method.ReturnType;
returnTypesList.Add(returnType);
for(int i = 0; i < paramTypes.Length; i++)
{
paramTypes[i] = paramInfo[i].ParameterType;
if((!paramInfo[i].IsIn) && paramInfo[i].IsOut)
nOutParams++;
if(paramTypes[i].IsByRef)
{
returnTypesList.Add(paramTypes[i].GetElementType());
nOutAndRefParams++;
}
}
int[] refArgs = new int[nOutAndRefParams];
returnTypes = returnTypesList.ToArray();
}
#if !MONOTOUCH #if !MONOTOUCH
/* /*
...@@ -398,31 +453,30 @@ namespace LuaInterface ...@@ -398,31 +453,30 @@ namespace LuaInterface
private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex, private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex,
FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes) FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes)
{ {
var paramInfo = method.GetParameters(); var paramInfo = method.GetParameters();
var paramTypes = new Type[paramInfo.Length]; var paramTypes = new Type[paramInfo.Length];
var returnTypesList = new List<Type>(); var returnTypesList = new List<Type>();
// Counts out and ref parameters, for later use, // Counts out and ref parameters, for later use,
// and creates the list of return types // and creates the list of return types
int nOutParams = 0; int nOutParams = 0;
int nOutAndRefParams = 0; int nOutAndRefParams = 0;
var returnType = method.ReturnType; var returnType = method.ReturnType;
returnTypesList.Add(returnType); returnTypesList.Add(returnType);
for(int i = 0; i < paramTypes.Length; i++) for(int i = 0; i < paramTypes.Length; i++)
{ {
paramTypes[i] = paramInfo[i].ParameterType; paramTypes[i] = paramInfo[i].ParameterType;
if((!paramInfo[i].IsIn) && paramInfo[i].IsOut) if((!paramInfo[i].IsIn) && paramInfo[i].IsOut)
nOutParams++; nOutParams++;
if(paramTypes[i].IsByRef) if(paramTypes[i].IsByRef)
{ {
returnTypesList.Add(paramTypes[i].GetElementType()); returnTypesList.Add(paramTypes[i].GetElementType());
nOutAndRefParams++; nOutAndRefParams++;
} }
} }
int[] refArgs = new int[nOutAndRefParams]; int[] refArgs = new int[nOutAndRefParams];
returnTypes = returnTypesList.ToArray(); returnTypes = returnTypesList.ToArray();
...@@ -661,6 +715,13 @@ namespace LuaInterface ...@@ -661,6 +715,13 @@ namespace LuaInterface
delegateCollection[delegateType] = luaDelegateType; delegateCollection[delegateType] = luaDelegateType;
} }
public void RegisterLuaClassType (Type klass, Type luaClass)
{
LuaClassType luaClassType = new LuaClassType();
luaClassType.klass = luaClass;
GetReturnTypesFromClass (klass, out luaClassType.returnTypes);
classCollection[klass] = luaClassType;
}
/* /*
* Gets a delegate with delegateType that calls the luaFunc Lua function * Gets a delegate with delegateType that calls the luaFunc Lua function
* Caches the generated type. * Caches the generated type.
...@@ -702,9 +763,6 @@ namespace LuaInterface ...@@ -702,9 +763,6 @@ namespace LuaInterface
*/ */
public object GetClassInstance(Type klass, LuaTable luaTable) public object GetClassInstance(Type klass, LuaTable luaTable)
{ {
#if MONOTOUCH
throw new NotImplementedException (" Emit not available on MonoTouch ");
#else
LuaClassType luaClassType; LuaClassType luaClassType;
if(classCollection.ContainsKey(klass)) if(classCollection.ContainsKey(klass))
...@@ -717,7 +775,6 @@ namespace LuaInterface ...@@ -717,7 +775,6 @@ namespace LuaInterface
} }
return Activator.CreateInstance(luaClassType.klass, new object[] {luaTable, luaClassType.returnTypes}); return Activator.CreateInstance(luaClassType.klass, new object[] {luaTable, luaClassType.returnTypes});
#endif
} }
} }
} }
\ No newline at end of file
...@@ -643,6 +643,11 @@ namespace LuaInterface ...@@ -643,6 +643,11 @@ namespace LuaInterface
CodeGeneration.Instance.RegisterLuaDelegateType (delegateType, luaDelegateType); CodeGeneration.Instance.RegisterLuaDelegateType (delegateType, luaDelegateType);
} }
public void RegisterLuaClassType (Type klass, Type luaClass)
{
CodeGeneration.Instance.RegisterLuaClassType (klass, luaClass);
}
/* /*
* Gets a function global variable as a delegate of * Gets a function global variable as a delegate of
* type delegateType * type delegateType
......
...@@ -1099,7 +1099,7 @@ namespace LuaInterfaceTest ...@@ -1099,7 +1099,7 @@ namespace LuaInterfaceTest
//Console.WriteLine("new val(from array to Lua)="+val); //Console.WriteLine("new val(from array to Lua)="+val);
} }
} }
/* /*G
* Tests setting item of a CLR array * Tests setting item of a CLR array
*/ */
[Test] [Test]
...@@ -1266,14 +1266,17 @@ namespace LuaInterfaceTest ...@@ -1266,14 +1266,17 @@ namespace LuaInterfaceTest
//Console.WriteLine("delegate returned: "+a); //Console.WriteLine("delegate returned: "+a);
} }
} }
/* /*
* Tests passing a Lua table as an interface and * Tests passing a Lua table as an interface and
* calling one of its methods with value-type params * calling one of its methods with value-type params
*/ */
[Test] [Test]
public void LuaInterfaceValueTypes () public void LuaInterfaceAAValueTypes ()
{ {
using (Lua lua = new Lua ()) { using (Lua lua = new Lua ()) {
lua.RegisterLuaClassType (typeof(ITest), typeof (LuaGeneratedClassX));
lua.DoString ("luanet.load_assembly('LuaInterfaceTest')"); lua.DoString ("luanet.load_assembly('LuaInterfaceTest')");
lua.DoString ("TestClass=luanet.import_type('LuaInterfaceTest.Mock.TestClass')"); lua.DoString ("TestClass=luanet.import_type('LuaInterfaceTest.Mock.TestClass')");
lua.DoString ("test=TestClass()"); lua.DoString ("test=TestClass()");
...@@ -1410,6 +1413,91 @@ namespace LuaInterfaceTest ...@@ -1410,6 +1413,91 @@ namespace LuaInterfaceTest
//Console.WriteLine("interface returned: "+a); //Console.WriteLine("interface returned: "+a);
} }
} }
/*** "Dynamic generated class X***/
class LuaGeneratedClassX : ILuaGeneratedType, ITest
{
public LuaTable __luaInterface_luaTable;
public Type[][] __luaInterface_returnTypes;
public LuaGeneratedClassX (LuaTable luaTable, Type [][] returnTypes)
{
__luaInterface_luaTable = luaTable;
__luaInterface_returnTypes = returnTypes;
}
public LuaTable __luaInterface_getLuaTable ()
{
return __luaInterface_luaTable;
}
public int intProp
{
get {
return 0;
}
set {
}
}
public TestClass refProp
{
get {
return null;
}
set {
}
}
public int test1(int a, int b)
{
object [] args = new object [] { __luaInterface_luaTable, a, b };
object [] inArgs = new object [] { __luaInterface_luaTable, a, b };
int [] outArgs = new int [] { };
Type [] returnTypes = __luaInterface_returnTypes [4];
LuaFunction function = LuaInterface.Method.LuaClassHelper.getTableFunction (__luaInterface_luaTable, "test1");
object ret = LuaInterface.Method.LuaClassHelper.callFunction (function, args, returnTypes, inArgs, outArgs);
return (int) ret;
}
public int test2(int a, out int b)
{
b = 0;
return 0;
}
public void test3(int a, ref int b)
{
}
public TestClass test4(int a, int b)
{
return null;
}
public int test5(TestClass a, TestClass b)
{
return 0;
}
public int test6(int a, out TestClass b)
{
b = null;
return 0;
}
public void test7(int a, ref TestClass b)
{
}
}
/* /*
* Tests passing a Lua table as an interface and * Tests passing a Lua table as an interface and
* accessing one of its value-type properties * accessing one of its value-type properties
......
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