Exemple #1
0
        /*
         * Constructs the wrapper for a known MethodBase instance
         */
        public LuaMethodWrapper(ObjectTranslator translator, object target, ProxyType targetType, MethodBase method)
        {
            InvokeFunction    = Call;
            _translator       = translator;
            _target           = target;
            _extractTarget    = translator.typeChecker.GetExtractor(targetType);
            _lastCalledMethod = new MethodCache();

            _method     = method;
            _methodName = method.Name;
            _isStatic   = method.IsStatic;
        }
        /*
         * Constructs the wrapper for a known method name
         */
        public LuaMethodWrapper(ObjectTranslator translator, ProxyType targetType, string methodName, BindingFlags bindingType)
        {
            InvokeFunction = Call;

            _translator       = translator;
            _methodName       = methodName;
            _extractTarget    = translator.typeChecker.GetExtractor(targetType);
            _lastCalledMethod = new MethodCache();

            _isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
            _members  = GetMethodsRecursively(targetType.UnderlyingSystemType,
                                              methodName,
                                              bindingType | BindingFlags.Public);
        }
Exemple #3
0
		/*
		 * Checks if the method matches the arguments in the Lua stack, getting
		 * the arguments if it does.
		 */
		internal bool MatchParameters (LuaState luaState, MethodBase method, ref MethodCache methodCache)
		{
			return metaFunctions.MatchParameters (luaState, method, ref methodCache);
		}
Exemple #4
0
		private int CallConstructorInternal (LuaState luaState)
		{
			var validConstructor = new MethodCache ();
			IReflect klass;
			object obj = translator.GetRawNetObject (luaState, 1);

			if (obj == null || !(obj is IReflect)) {
				translator.ThrowError (luaState, "trying to call constructor on an invalid type reference");
				LuaLib.LuaPushNil (luaState);
				return 1;
			} else
				klass = (IReflect)obj;

			LuaLib.LuaRemove (luaState, 1);
			var constructors = klass.UnderlyingSystemType.GetConstructors ();

			foreach (var constructor in constructors) {
				bool isConstructor = MatchParameters (luaState, constructor, ref validConstructor);

				if (isConstructor) {
					try {
						translator.Push (luaState, constructor.Invoke (validConstructor.args));
					} catch (TargetInvocationException e) {
						ThrowError (luaState, e);
						LuaLib.LuaPushNil (luaState);
					} catch {
						LuaLib.LuaPushNil (luaState);
					}

					return 1;
				}
			}

			string constructorName = (constructors.Length == 0) ? "unknown" : constructors [0].Name;
			translator.ThrowError (luaState, String.Format ("{0} does not contain constructor({1}) argument match",
				klass.UnderlyingSystemType, constructorName));
			LuaLib.LuaPushNil (luaState);
			return 1;
		}
Exemple #5
0
		/*
		 * Matches a method against its arguments in the Lua stack. Returns
		 * if the match was successful. It it was also returns the information
		 * necessary to invoke the method.
		 */
		internal bool MatchParameters (LuaState luaState, MethodBase method, ref MethodCache methodCache)
		{
			ExtractValue extractValue;
			bool isMethod = true;
			var paramInfo = method.GetParameters ();
			int currentLuaParam = 1;
			int nLuaParams = LuaLib.LuaGetTop (luaState);
			var paramList = new List<object> ();
			var outList = new List<int> ();
			var argTypes = new List<MethodArgs> ();

			foreach (var currentNetParam in paramInfo) {
#if !SILVERLIGHT
				if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params 
#else
				if (currentNetParam.IsOut)  // Skips out params
#endif
				{					
					paramList.Add (null);
					outList.Add (paramList.LastIndexOf (null));
				}  else if (IsTypeCorrect (luaState, currentLuaParam, currentNetParam, out extractValue)) {  // Type checking
					var value = extractValue (luaState, currentLuaParam);
					paramList.Add (value);
					int index = paramList.LastIndexOf (value);
					var 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)) {

					var paramArrayType = currentNetParam.ParameterType.GetElementType ();

					Func<int, object> extractDelegate = (currentParam) => {
						currentLuaParam ++;
						return extractValue (luaState, currentParam);
					};
					int count = (nLuaParams - currentLuaParam) + 1;
					Array paramArray = TableToArray (extractDelegate, paramArrayType, currentLuaParam, count);

					paramList.Add (paramArray);
					int index = paramList.LastIndexOf (paramArray);
					var methodArg = new MethodArgs ();
					methodArg.index = index;
					methodArg.extractValue = extractValue;
					methodArg.isParamsArray = true;
					methodArg.paramsArrayType = paramArrayType;
					argTypes.Add (methodArg);

				} else if (currentLuaParam > nLuaParams) { // Adds optional parameters
					if (currentNetParam.IsOptional)
						paramList.Add (currentNetParam.DefaultValue);
					else {
						isMethod = false;
						break;
					}
				} 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;
		}
Exemple #6
0
		static int MatchOperator (LuaState luaState, string operation, ObjectTranslator translator)
		{
			var validOperator = new MethodCache ();

			object target = GetTargetObject (luaState, operation, translator);

			if (target == null) {
				translator.ThrowError (luaState, "Cannot call " + operation + " on a nil object");
				LuaLib.LuaPushNil (luaState);
				return 1;
			}

			Type type = target.GetType ();
			var operators = type.GetMethods (operation, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

			foreach (var op in operators) {
				bool isOk = translator.MatchParameters (luaState, op, ref validOperator);

				if (!isOk)
					continue;

				object result;
				if (op.IsStatic)
					result = op.Invoke (null, validOperator.args);
				else
					result = op.Invoke (target, validOperator.args);
				translator.Push (luaState, result);
				return 1;
			}

			translator.ThrowError (luaState, "Cannot call (" + operation + ") on object type " + type.Name);
			LuaLib.LuaPushNil (luaState);
			return 1;
		}
Exemple #7
0
		private int CallConstructorInternal (LuaState luaState)
		{
			var validConstructor = new MethodCache ();
			ProxyType klass;
			object obj = translator.GetRawNetObject (luaState, 1);

			if (obj == null || !(obj is ProxyType)) {
				translator.ThrowError (luaState, "trying to call constructor on an invalid type reference");
				LuaLib.LuaPushNil (luaState);
				return 1;
			} else
				klass = (ProxyType)obj;

			LuaLib.LuaRemove (luaState, 1);
			var constructors = klass.UnderlyingSystemType.GetConstructors ();

			foreach (var constructor in constructors) {
				bool isConstructor = MatchParameters (luaState, constructor, ref validConstructor);

				if (isConstructor) {
					try {
						translator.Push (luaState, constructor.Invoke (validConstructor.args));
					} catch (TargetInvocationException e) {
						ThrowError (luaState, e);
						LuaLib.LuaPushNil (luaState);
					} catch {
						LuaLib.LuaPushNil (luaState);
					}

					return 1;
				}
			}

#if NETFX_CORE
			if (klass.UnderlyingSystemType.GetTypeInfo ().IsValueType) {
#else
			if (klass.UnderlyingSystemType.IsValueType) {
#endif
				int numLuaParams = LuaLib.LuaGetTop (luaState);
				if (numLuaParams == 0) {
					translator.Push (luaState, Activator.CreateInstance (klass.UnderlyingSystemType));
					return 1;
				}
			}

			string constructorName = (constructors.Length == 0) ? "unknown" : constructors [0].Name;
			translator.ThrowError (luaState, String.Format ("{0} does not contain constructor({1}) argument match",
				klass.UnderlyingSystemType, constructorName));
			LuaLib.LuaPushNil (luaState);
			return 1;
		}
		static bool IsInteger(double x) {
			return Math.Ceiling(x) == x;	
		}
Exemple #8
0
		int CallDelegateInternal (LuaState luaState)
		{
			object objDelegate = translator.GetRawNetObject (luaState, 1);

			if (objDelegate == null || !(objDelegate is Delegate)) {
				translator.ThrowError (luaState, "trying to invoke a not delegate or callable value");
				LuaLib.LuaPushNil (luaState);
				return 1;
			}

			LuaLib.LuaRemove (luaState, 1);

			var validDelegate = new MethodCache ();
			Delegate del = (Delegate)objDelegate;
#if NETFX_CORE || WP80 || NET45 || PCL
			MethodBase methodDelegate = del.GetMethodInfo ();
#else
            MethodBase methodDelegate = del.Method;
#endif
			bool isOk = MatchParameters (luaState, methodDelegate, ref validDelegate);

			if (isOk) {
				object result;

				if (methodDelegate.IsStatic)
					result = methodDelegate.Invoke (null, validDelegate.args);
				else
					result = methodDelegate.Invoke (del.Target, validDelegate.args);

				translator.Push (luaState, result);
				return 1;
			}

			translator.ThrowError (luaState, "Cannot invoke delegate (invalid arguments for  " + methodDelegate.Name + ")");
			LuaLib.LuaPushNil (luaState);
			return 1;
		}
Exemple #9
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 (LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache)
		{
			ExtractValue extractValue;
			bool isMethod = true;
			var paramInfo = method.GetParameters ();
			int currentLuaParam = 1;
			int nLuaParams = LuaLib.lua_gettop (luaState);
			var paramList = new ArrayList ();
			var outList = new List<int> ();
			var argTypes = new List<MethodArgs> ();

			foreach (var 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));
					var 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);
					var paramArrayType = currentNetParam.ParameterType.GetElementType ();
					Array paramArray;

					if (luaParamValue is LuaTable) {
						var table = (LuaTable)luaParamValue;
						var 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);
					var 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;
		}