Пример #1
0
		/*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
		internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
		{
			ExtractValue extractValue;
			bool isMethod = true;
			ParameterInfo[] paramInfo = method.GetParameters();
			int currentLuaParam = 1;
			int nLuaParams = LuaDLL.lua_gettop(luaState);
			ArrayList paramList = new ArrayList();
			List<int> outList = new List<int>();
			List<MethodArgs> argTypes = new List<MethodArgs>();
			foreach (ParameterInfo currentNetParam in paramInfo)
			{
				if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
				{
					outList.Add(paramList.Add(null));
				}
				else if (currentLuaParam > nLuaParams) // Adds optional parameters
				{
					if (currentNetParam.IsOptional)
					{
						paramList.Add(currentNetParam.DefaultValue);
					}
					else
					{
						isMethod = false;
						break;
					}
				}
				else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
				{
					int index = paramList.Add(extractValue(luaState, currentLuaParam));
					
					MethodArgs methodArg = new MethodArgs();
					methodArg.index = index;
					methodArg.extractValue = extractValue;
					argTypes.Add(methodArg);
					
					if (currentNetParam.ParameterType.IsByRef)
						outList.Add(index);
					currentLuaParam++;
				}  // 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 = TableToArray(luaParamValue, paramArrayType);					
					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)
				{
					paramList.Add(currentNetParam.DefaultValue);
				}
				else  // No match
				{
					isMethod = false;
					break;
				}
			}
			if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
				isMethod = false;
			if (isMethod)
			{
				methodCache.args = paramList.ToArray();
				methodCache.cachedMethod = method;
				methodCache.outList = outList.ToArray();
				methodCache.argTypes = argTypes.ToArray();
			}
			return isMethod;
		}
Пример #2
0
		public static int callConstructor(IntPtr luaState)
		{
			ObjectTranslator translator = ObjectTranslator.FromState(luaState);
			MethodCache validConstructor = new MethodCache();
			IReflect klass;
			object obj = translator.getRawNetObject(luaState, 1);
			if (obj == null || !(obj is IReflect))
			{				
                LuaDLL.luaL_error(luaState, "trying to call constructor on an invalid type reference");
				LuaDLL.lua_pushnil(luaState);
				return 1;
			}
			else klass = (IReflect)obj;
			LuaDLL.lua_remove(luaState, 1);
			ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
			foreach (ConstructorInfo constructor in constructors)
			{
				bool isConstructor = translator.metaFunctions.matchParameters(luaState, constructor, ref validConstructor);
				if (isConstructor)
				{
					try
					{
						translator.push(luaState, constructor.Invoke(validConstructor.args));
					}
					catch (TargetInvocationException e)
					{
						translator.metaFunctions.ThrowError(luaState, e);
						LuaDLL.lua_pushnil(luaState);
					}
					catch
					{
						LuaDLL.lua_pushnil(luaState);
					}
					return 1;
				}
			}
			
			string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;
            LuaDLL.luaL_error(luaState, String.Format("{0} does not contain constructor({1}) argument match",
                                                          klass.UnderlyingSystemType,
                                                          constructorName));
			LuaDLL.lua_pushnil(luaState);
			return 1;
		}