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
}
else if(typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.Function)
return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated);
#if !MONOTOUCH
else if(paramType.IsInterface && luatype == LuaTypes.Table)
return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated);
#endif
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
......
......@@ -308,6 +308,30 @@ namespace LuaInterface
#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
* a subclass of klass that delegates its virtual methods to a Lua table.
......@@ -387,6 +411,37 @@ namespace LuaInterface
newType = myType.CreateType(); // Creates the type
#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
/*
......@@ -398,31 +453,30 @@ namespace LuaInterface
private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex,
FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, 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();
......@@ -661,6 +715,13 @@ namespace LuaInterface
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
* Caches the generated type.
......@@ -702,9 +763,6 @@ namespace LuaInterface
*/
public object GetClassInstance(Type klass, LuaTable luaTable)
{
#if MONOTOUCH
throw new NotImplementedException (" Emit not available on MonoTouch ");
#else
LuaClassType luaClassType;
if(classCollection.ContainsKey(klass))
......@@ -717,7 +775,6 @@ namespace LuaInterface
}
return Activator.CreateInstance(luaClassType.klass, new object[] {luaTable, luaClassType.returnTypes});
#endif
}
}
}
\ No newline at end of file
......@@ -643,6 +643,11 @@ namespace LuaInterface
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
* type delegateType
......
......@@ -1099,7 +1099,7 @@ namespace LuaInterfaceTest
//Console.WriteLine("new val(from array to Lua)="+val);
}
}
/*
/*G
* Tests setting item of a CLR array
*/
[Test]
......@@ -1266,14 +1266,17 @@ namespace LuaInterfaceTest
//Console.WriteLine("delegate returned: "+a);
}
}
/*
* Tests passing a Lua table as an interface and
* calling one of its methods with value-type params
*/
[Test]
public void LuaInterfaceValueTypes ()
public void LuaInterfaceAAValueTypes ()
{
using (Lua lua = new Lua ()) {
lua.RegisterLuaClassType (typeof(ITest), typeof (LuaGeneratedClassX));
lua.DoString ("luanet.load_assembly('LuaInterfaceTest')");
lua.DoString ("TestClass=luanet.import_type('LuaInterfaceTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
......@@ -1410,6 +1413,91 @@ namespace LuaInterfaceTest
//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
* 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