Commit 1a9eb0af authored by Eonstorm's avatar Eonstorm
Browse files

Added a case to matchParameters to handle the possibility for arguments with the param attribute.

Reference: Issue 22.


git-svn-id: http://luainterface.googlecode.com/svn/trunk@17 63eb109e-e254-0410-a61e-ed0b8f8614f5
parent be5ea9b0
...@@ -81,7 +81,7 @@ namespace LuaInterface ...@@ -81,7 +81,7 @@ namespace LuaInterface
} }
public System.Collections.IEnumerator GetEnumerator() public System.Collections.IDictionaryEnumerator GetEnumerator()
{ {
return _Interpreter.GetTableDict(this).GetEnumerator(); return _Interpreter.GetTableDict(this).GetEnumerator();
} }
......
...@@ -148,7 +148,7 @@ namespace LuaInterface ...@@ -148,7 +148,7 @@ namespace LuaInterface
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.
// CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object, // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
// ie: xmlelement['item'] <- item is a property of xmlelement // ie: xmlelement['item'] <- item is a property of xmlelement
try try
...@@ -183,13 +183,13 @@ namespace LuaInterface ...@@ -183,13 +183,13 @@ namespace LuaInterface
object[] arr = (object[])obj; object[] arr = (object[])obj;
translator.push(luaState, arr[intIndex]); 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(); MethodInfo[] methods = objType.GetMethods();
foreach (MethodInfo mInfo in methods) foreach (MethodInfo mInfo in methods)
{ {
if (mInfo.Name == "get_Item") if (mInfo.Name == "get_Item")
...@@ -235,7 +235,7 @@ namespace LuaInterface ...@@ -235,7 +235,7 @@ namespace LuaInterface
} }
} }
} }
LuaDLL.lua_pushboolean(luaState, false); LuaDLL.lua_pushboolean(luaState, false);
...@@ -288,7 +288,7 @@ namespace LuaInterface ...@@ -288,7 +288,7 @@ namespace LuaInterface
if (cachedMember != null) if (cachedMember != null)
return true; return true;
//CP: Removed NonPublic binding search //CP: Removed NonPublic binding search
MemberInfo[] members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase/* | 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);
...@@ -371,7 +371,7 @@ namespace LuaInterface ...@@ -371,7 +371,7 @@ namespace LuaInterface
else else
LuaDLL.lua_pushnil(luaState); LuaDLL.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); LuaDLL.lua_pushnil(luaState);
...@@ -383,7 +383,7 @@ namespace LuaInterface ...@@ -383,7 +383,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)
{ {
...@@ -406,7 +406,7 @@ namespace LuaInterface ...@@ -406,7 +406,7 @@ namespace LuaInterface
{ {
// Member type must be 'method' // Member type must be 'method'
LuaCSFunction wrapper = new LuaCSFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); LuaCSFunction wrapper = new LuaCSFunction((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);
...@@ -627,7 +627,7 @@ namespace LuaInterface ...@@ -627,7 +627,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;
...@@ -781,14 +781,58 @@ namespace LuaInterface ...@@ -781,14 +781,58 @@ namespace LuaInterface
else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // Type checking else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // 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);
...@@ -833,5 +877,66 @@ namespace LuaInterface ...@@ -833,5 +877,66 @@ namespace LuaInterface
return false; 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
...@@ -31,6 +31,10 @@ namespace LuaInterface ...@@ -31,6 +31,10 @@ namespace LuaInterface
public int index; public int index;
// Type-conversion function // Type-conversion function
public ExtractValue extractValue; public ExtractValue extractValue;
public bool isParamsArray;
public Type paramsArrayType;
} }
/* /*
...@@ -82,12 +86,12 @@ namespace LuaInterface ...@@ -82,12 +86,12 @@ namespace LuaInterface
_Translator = translator; _Translator = translator;
_MethodName = methodName; _MethodName = methodName;
_TargetType = targetType; _TargetType = targetType;
if (targetType != null) if (targetType != null)
_ExtractTarget = translator.typeChecker.getExtractor(targetType); _ExtractTarget = translator.typeChecker.getExtractor(targetType);
_BindingType = bindingType; _BindingType = bindingType;
//CP: Removed NonPublic binding search and added IgnoreCase //CP: Removed NonPublic binding search and added IgnoreCase
_Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/); _Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/);
} }
...@@ -144,8 +148,38 @@ namespace LuaInterface ...@@ -144,8 +148,38 @@ namespace LuaInterface
{ {
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);
Type paramArrayType = _LastCalledMethod.argTypes[i].paramsArrayType;
Array paramArray;
if (luaParamValue is LuaTable)
{
LuaTable table = (LuaTable)luaParamValue;
paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);
for (int x = 1; x <= table.Values.Count; x++)
{
paramArray.SetValue(Convert.ChangeType(table[x], paramArrayType), x - 1);
}
}
else
{
paramArray = Array.CreateInstance(paramArrayType, 1);
paramArray.SetValue(luaParamValue, 0);
}
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] = paramArray;
}
else
{
_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] =
_LastCalledMethod.argTypes[i].extractValue(luaState, i + 1 + numStackToSkip);
}
if (_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] == null && if (_LastCalledMethod.args[_LastCalledMethod.argTypes[i].index] == null &&
!LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip))
...@@ -239,13 +273,13 @@ namespace LuaInterface ...@@ -239,13 +273,13 @@ namespace LuaInterface
foreach (object arg in _LastCalledMethod.args) foreach (object arg in _LastCalledMethod.args)
typeArgs.Add(arg.GetType()); typeArgs.Add(arg.GetType());
MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray()); MethodInfo concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod(typeArgs.ToArray());
_Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args)); _Translator.push(luaState, concreteMethod.Invoke(targetObject, _LastCalledMethod.args));
failedCall = false; failedCall = false;
} }
else if(methodToCall.ContainsGenericParameters) else if (methodToCall.ContainsGenericParameters)
{ {
_Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method"); _Translator.throwError(luaState, "unable to invoke method on generic class as the current method is an open generic method");
LuaDLL.lua_pushnil(luaState); LuaDLL.lua_pushnil(luaState);
......
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