예제 #1
0
        private Type TypeOf(LuaState luaState, int idx)
        {
            int udata = LuaLib.LuaNetCheckUData(luaState, 1, "luaNet_class");

            if (udata == -1)
            {
                return(null);
            }

            ProxyType pt = (ProxyType)objects [udata];

            return(pt.UnderlyingSystemType);
        }
예제 #2
0
        private int GetMethodSignatureInternal(LuaState luaState)
        {
            ProxyType klass;
            object    target;
            int       udata = luaState.CheckUObject(1, "luaNet_class");

            if (udata != -1)
            {
                klass  = (ProxyType)_objects[udata];
                target = null;
            }
            else
            {
                target = GetRawNetObject(luaState, 1);

                if (target == null)
                {
                    ThrowError(luaState, "get_method_bysig: first arg is not type or object reference");
                    luaState.PushNil();
                    return(1);
                }

                klass = new ProxyType(target.GetType());
            }

            string methodName = luaState.ToString(2, false);
            var    signature  = new Type[luaState.GetTop() - 2];

            for (int i = 0; i < signature.Length; i++)
            {
                signature[i] = FindType(luaState.ToString(i + 3, false));
            }

            try
            {
                var method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static |
                                             BindingFlags.Instance, signature);
                var wrapper = new LuaMethodWrapper(this, target, klass, method);
                LuaNativeFunction invokeDelegate = wrapper.InvokeFunction;
                PushFunction(luaState, invokeDelegate);
            }
            catch (Exception e)
            {
                ThrowError(luaState, e);
                luaState.PushNil();
            }

            return(1);
        }
예제 #3
0
        private int GetMethodSignatureInternal(LuaState luaState)
        {
            ProxyType klass;
            object    target;
            int       udata = LuaLib.LuaNetCheckUData(luaState, 1, "luaNet_class");

            if (udata != -1)
            {
                klass  = (ProxyType)objects [udata];
                target = null;
            }
            else
            {
                target = GetRawNetObject(luaState, 1);

                if (target == null)
                {
                    ThrowError(luaState, "get_method_bysig: first arg is not type or object reference");
                    LuaLib.LuaPushNil(luaState);
                    return(1);
                }

                klass = new ProxyType(target.GetType());
            }

            string methodName = LuaLib.LuaToString(luaState, 2).ToString();
            var    signature  = new Type[LuaLib.LuaGetTop(luaState) - 2];

            for (int i = 0; i < signature.Length; i++)
            {
                signature [i] = FindType(LuaLib.LuaToString(luaState, i + 3).ToString());
            }

            try {
                var method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static |
                                             BindingFlags.Instance, signature);
                PushFunction(luaState, new LuaNativeFunction((new LuaMethodWrapper(this, target, klass, method)).invokeFunction));
            } catch (Exception e) {
                ThrowError(luaState, e);
                LuaLib.LuaPushNil(luaState);
            }

            return(1);
        }
예제 #4
0
        private int GetConstructorSignatureInternal(LuaState luaState)
        {
            ProxyType klass = null;
            int       udata = luaState.CheckUObject(1, "luaNet_class");

            if (udata != -1)
            {
                klass = (ProxyType)_objects[udata];
            }

            if (klass == null)
            {
                ThrowError(luaState, "get_constructor_bysig: first arg is invalid type reference");
            }

            var signature = new Type[luaState.GetTop() - 1];

            for (int i = 0; i < signature.Length; i++)
            {
                signature[i] = FindType(luaState.ToString(i + 2, false));
            }

            try
            {
                ConstructorInfo constructor    = klass.UnderlyingSystemType.GetConstructor(signature);
                var             wrapper        = new LuaMethodWrapper(this, null, klass, constructor);
                var             invokeDelegate = wrapper.InvokeFunction;
                PushFunction(luaState, invokeDelegate);
            }
            catch (Exception e)
            {
                ThrowError(luaState, e);
                luaState.PushNil();
            }
            return(1);
        }
예제 #5
0
		/*
		 * Checks if the value at Lua stack index stackPos matches paramType, 
		 * returning a conversion function if it does and null otherwise.
		 */
		internal ExtractValue GetExtractor (ProxyType paramType)
		{
			return GetExtractor (paramType.UnderlyingSystemType);
		}
예제 #6
0
파일: CheckType.cs 프로젝트: zwwl0801/NLua
 /*
  * Checks if the value at Lua stack index stackPos matches paramType,
  * returning a conversion function if it does and null otherwise.
  */
 internal ExtractValue GetExtractor(ProxyType paramType)
 {
     return(GetExtractor(paramType.UnderlyingSystemType));
 }
예제 #7
0
		private int GetMethodSignatureInternal (LuaState luaState)
		{
			ProxyType klass;
			object target;
			int udata = LuaLib.LuaNetCheckUData (luaState, 1, "luaNet_class");

			if (udata != -1) {
				klass = (ProxyType)objects [udata];
				target = null;
			} else {
				target = GetRawNetObject (luaState, 1);

				if (target == null) {
					ThrowError (luaState, "get_method_bysig: first arg is not type or object reference");
					LuaLib.LuaPushNil (luaState);
					return 1;
				}

				klass = new ProxyType(target.GetType ());
			}

			string methodName = LuaLib.LuaToString (luaState, 2).ToString ();
			var signature = new Type[LuaLib.LuaGetTop (luaState) - 2];

			for (int i = 0; i < signature.Length; i++)
				signature [i] = FindType (LuaLib.LuaToString (luaState, i + 3).ToString ());

			try {
				var method = klass.GetMethod (methodName, BindingFlags.Public | BindingFlags.Static |
					BindingFlags.Instance, signature);
				PushFunction (luaState, new LuaNativeFunction ((new LuaMethodWrapper (this, target, klass, method)).invokeFunction));
			} catch (Exception e) {
				ThrowError (luaState, e);
				LuaLib.LuaPushNil (luaState);
			}

			return 1;
		}
예제 #8
0
		/// <summary>
		/// Tries to set a named property or field
		/// </summary>
		/// <param name="luaState"></param>
		/// <param name="targetType"></param>
		/// <param name="target"></param>
		/// <param name="bindingType"></param>
		/// <returns>false if unable to find the named member, true for success</returns>
		bool TrySetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType, out string detailMessage)
		{
			detailMessage = null;   // No error yet

			// If not already a string just return - we don't want to call tostring - which has the side effect of 
			// changing the lua typecode to string
			// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
			// be true for isstring.
			if (LuaLib.LuaType (luaState, 2) != LuaTypes.String) {
				detailMessage = "property names must be strings";
				return false;
			}

			// We only look up property names by string
			string fieldName = LuaLib.LuaToString (luaState, 2).ToString ();
			if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter (fieldName [0]) || fieldName [0] == '_')) {
				detailMessage = "invalid property name";
				return false;
			}

			// Find our member via reflection or the cache
			var member = (MemberInfo)CheckMemberCache (memberCache, targetType, fieldName);
			if (member == null) {
				var members = targetType.GetMember (fieldName, bindingType | BindingFlags.Public);

				if (members.Length > 0) {
					member = members [0];
					SetMemberCache (memberCache, targetType, fieldName, member);
				} else {
					detailMessage = "field or property '" + fieldName + "' does not exist";
					return false;
				}
			}
#if NETFX_CORE
			if (member is FieldInfo) {
#else
			if (member.MemberType == MemberTypes.Field) {
#endif

				var field = (FieldInfo)member;
				object val = translator.GetAsType (luaState, 3, field.FieldType);

				try {
					field.SetValue (target, val);
				} catch (Exception e) {
					ThrowError (luaState, e);
				}

				// We did a call
				return true;
#if NETFX_CORE
			} else if (member is PropertyInfo) {
#else
			} else if (member.MemberType == MemberTypes.Property) {
#endif
				var property = (PropertyInfo)member;
				object val = translator.GetAsType (luaState, 3, property.PropertyType);

				try {
					property.SetValue (target, val, null);
				} catch (Exception e) {
					ThrowError (luaState, e);
				}

				// We did a call
				return true;
			}

			detailMessage = "'" + fieldName + "' is not a .net field or property";
			return false;
		}

		/*
		 * Writes to fields or properties, either static or instance. Throws an error
		 * if the operation is invalid.
		 */
		private int SetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType)
		{
			string detail;
			bool success = TrySetMember (luaState, targetType, target, bindingType, out detail);

			if (!success)
				translator.ThrowError (luaState, detail);

			return 0;
		}

		/// <summary>
		/// Convert a C# exception into a Lua error
		/// </summary>
		/// <param name="e"></param>
		/// We try to look into the exception to give the most meaningful description
		void ThrowError (LuaState luaState, Exception e)
		{
			// If we got inside a reflection show what really happened
			var te = e as TargetInvocationException;

			if (te != null)
				e = te.InnerException;

			translator.ThrowError (luaState, e);
		}
예제 #9
0
파일: API.cs 프로젝트: fankidark/ME_NLua
 public static UnityEngine.Component AddMissComponent(GameObject obj, ProxyType t)
 {
     Type _t = t.UnderlyingSystemType;
     string classname = _t.ToString();
     int idx = classname.LastIndexOf(".");
     classname = classname.Substring(idx + 1, classname.Length - idx - 1);
     UnityEngine.Component _out = obj.GetComponent(classname);
     if (null == _out)
     {
         _out = obj.AddComponent(_t);
     }
     return _out;
 }
예제 #10
0
		object CheckMemberCache (Dictionary<object, object> memberCache, ProxyType objType, string memberName)
		{
			object members = null;

			if (memberCache.TryGetValue(objType, out members))
			{
				var membersDict = members as Dictionary<object, object>;

				object memberValue = null;

				if (members != null && membersDict.TryGetValue(memberName, out memberValue))
				{
					return memberValue;
				}
			}

			return null;
		}
예제 #11
0
		/*
		 * Pushes the value of a member or a delegate to call it, depending on the type of
		 * the member. Works with static or instance members.
		 * Uses reflection to find members, and stores the reflected MemberInfo object in
		 * a cache (indexed by the type of the object and the name of the member).
		 */
		int GetMember (LuaState luaState, ProxyType objType, object obj, string methodName, BindingFlags bindingType)
		{
			bool implicitStatic = false;
			MemberInfo member = null;
			object cachedMember = CheckMemberCache (memberCache, objType, methodName);

			if (cachedMember is LuaNativeFunction) {
				translator.PushFunction (luaState, (LuaNativeFunction)cachedMember);
				translator.Push (luaState, true);
				return 2;
			} else if (cachedMember != null)
				member = (MemberInfo)cachedMember;
			else {
				var members = objType.GetMember (methodName, bindingType | BindingFlags.Public);

				if (members.Length > 0)
					member = members [0];
				else {
					// If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static
					members = objType.GetMember (methodName, bindingType | BindingFlags.Static | BindingFlags.Public);

					if (members.Length > 0) {
						member = members [0];
						implicitStatic = true;
					}
				}
			}

			if (member != null) {
#if NETFX_CORE
				if (member is FieldInfo) {
#else
				if (member.MemberType == MemberTypes.Field) {
#endif
					var field = (FieldInfo)member;

					if (cachedMember == null)
						SetMemberCache (memberCache, objType, methodName, member);

					try {
						var value = field.GetValue (obj);
						translator.Push (luaState, value);							
					} catch {
						LuaLib.LuaPushNil (luaState);
					}
#if NETFX_CORE
				} else if (member is PropertyInfo) {
#else
				} else if (member.MemberType == MemberTypes.Property) {
#endif
					var property = (PropertyInfo)member;
					if (cachedMember == null)
						SetMemberCache (memberCache, objType, methodName, member);

					try {
						object value = property.GetValue (obj, null);
						translator.Push (luaState, value);
							
					} catch (ArgumentException) {
						// If we can't find the getter in our class, recurse up to the base class and see
						// if they can help.
						if (objType.UnderlyingSystemType != typeof(object))
#if NETFX_CORE
							return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.GetTypeInfo().BaseType), obj, methodName, bindingType);
#else
							return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.BaseType), obj, methodName, bindingType);
#endif
						else
							LuaLib.LuaPushNil (luaState);
					} catch (TargetInvocationException e) {  // Convert this exception into a Lua error
						ThrowError (luaState, e);
						LuaLib.LuaPushNil (luaState);
					}
#if NETFX_CORE
				} else if (member is EventInfo) {
#else
				} else if (member.MemberType == MemberTypes.Event) {
#endif
					var eventInfo = (EventInfo)member;
					if (cachedMember == null)
						SetMemberCache (memberCache, objType, methodName, member);

					translator.Push (luaState, new RegisterEventHandler (translator.pendingEvents, obj, eventInfo));
				} else if (!implicitStatic) {
#if NETFX_CORE
					var typeInfo = member as TypeInfo;
					if (typeInfo != null && !typeInfo.IsPublic && !typeInfo.IsNotPublic) {
#else
					if (member.MemberType == MemberTypes.NestedType) {
#endif

						// kevinh - added support for finding nested types-
						// cache us
						if (cachedMember == null)
							SetMemberCache (memberCache, objType, methodName, member);

						// Find the name of our class
						string name = member.Name;
						var dectype = member.DeclaringType;

						// Build a new long name and try to find the type by name
						string longname = dectype.FullName + "+" + name;
						var nestedType = translator.FindType (longname);
						translator.PushType (luaState, nestedType);
					} else {
						// Member type must be 'method'
						var wrapper = new LuaNativeFunction ((new LuaMethodWrapper (translator, objType, methodName, bindingType)).invokeFunction);

						if (cachedMember == null)
							SetMemberCache (memberCache, objType, methodName, wrapper);

						translator.PushFunction (luaState, wrapper);
						translator.Push (luaState, true);
						return 2;
					}
				} else {
					// If we reach this point we found a static method, but can't use it in this context because the user passed in an instance
					translator.ThrowError (luaState, "can't pass instance to static method " + methodName);
					LuaLib.LuaPushNil (luaState);
				}
			} else {

				if (objType.UnderlyingSystemType != typeof(object)) {
					#if NETFX_CORE
					return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.GetTypeInfo().BaseType), obj, methodName, bindingType);
					#else
					return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.BaseType), obj, methodName, bindingType);
					#endif
				}
				// kevinh - we want to throw an exception because meerly returning 'nil' in this case
				// is not sufficient.  valid data members may return nil and therefore there must be some
				// way to know the member just doesn't exist.
				translator.ThrowError (luaState, "unknown member name " + methodName);
				LuaLib.LuaPushNil (luaState);
			}

			// push false because we are NOT returning a function (see luaIndexFunction)
			translator.Push (luaState, false);
			return 2;
		}
예제 #12
0
		/// <summary>
		/// Does this method exist as either an instance or static?
		/// </summary>
		/// <param name="objType"></param>
		/// <param name="methodName"></param>
		/// <returns></returns>
		bool IsMemberPresent (ProxyType objType, string methodName)
		{
			object cachedMember = CheckMemberCache (memberCache, objType, methodName);

			if (cachedMember != null)
				return true;

			var members = objType.GetMember (methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
			return (members.Length > 0);
		}
예제 #13
0
		private int GetMethodInternal (LuaState luaState)
		{
			object obj = translator.GetRawNetObject (luaState, 1);

			if (obj == null) {
				translator.ThrowError (luaState, "trying to index an invalid object reference");
				LuaLib.LuaPushNil (luaState);
				return 1;
			}

			object index = translator.GetObject (luaState, 2);
			//var indexType = index.GetType();
			string methodName = index as string;		// will be null if not a string arg
			var objType = obj.GetType ();
			var proxyType = new ProxyType (objType);
			// 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, 
			// ie: xmlelement['item'] <- item is a property of xmlelement
			try {
				if (!string.IsNullOrEmpty(methodName) && IsMemberPresent (proxyType, methodName))
					return GetMember (luaState, proxyType, obj, methodName, BindingFlags.Instance);
			} catch {
			}
			
			// Try to access by array if the type is right and index is an int (lua numbers always come across as double)
			if (objType.IsArray && index is double) {
				int intIndex = (int)((double)index);
#if NETFX_CORE
				Type type = objType;
#else
				Type type = objType.UnderlyingSystemType;
#endif

				if (type == typeof(float[])) {
					float[] arr = ((float[])obj);
					translator.Push (luaState, arr [intIndex]);
				} else if (type == typeof(double[])) {
					double[] arr = ((double[])obj);
					translator.Push (luaState, arr [intIndex]);
				} else if (type == typeof(int[])) {
					int[] arr = ((int[])obj);
					translator.Push (luaState, arr [intIndex]);
				} else {
					object[] arr = (object[])obj;
					translator.Push (luaState, arr [intIndex]);
				}
			} else {

				if (!string.IsNullOrEmpty (methodName) && IsExtensionMethodPresent (objType, methodName)) {
					return GetExtensionMethod (luaState, objType, obj, methodName);
				}
				// Try to use get_Item to index into this .net object
				var methods = objType.GetMethods ();

				foreach (var mInfo in methods) {
					if (mInfo.Name == "get_Item") {
						//check if the signature matches the input
						if (mInfo.GetParameters ().Length == 1) {
							var getter = mInfo;
							var actualParms = (getter != null) ? getter.GetParameters () : null;

							if (actualParms == null || actualParms.Length != 1) {
								translator.ThrowError (luaState, "method not found (or no indexer): " + index);
								LuaLib.LuaPushNil (luaState);
							} else {
								// Get the index in a form acceptable to the getter
								index = translator.GetAsType (luaState, 2, actualParms [0].ParameterType);
								object[] args = new object[1];

								// Just call the indexer - if out of bounds an exception will happen
								args [0] = index;

								try {
									object result = getter.Invoke (obj, args);
									translator.Push (luaState, result);
								} catch (TargetInvocationException e) {
									// Provide a more readable description for the common case of key not found
									if (e.InnerException is KeyNotFoundException)
										translator.ThrowError (luaState, "key '" + index + "' not found ");
									else
										translator.ThrowError (luaState, "exception indexing '" + index + "' " + e.Message);

									LuaLib.LuaPushNil (luaState);
								}
							}
						}
					}
				}
			}

			LuaLib.LuaPushBoolean (luaState, false);
			return 2;
		}
예제 #14
0
		/*
		 * Writes to fields or properties, either static or instance. Throws an error
		 * if the operation is invalid.
		 */
		private int SetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType)
		{
			string detail;
			bool success = TrySetMember (luaState, targetType, target, bindingType, out detail);

			if (!success)
				translator.ThrowError (luaState, detail);

			return 0;
		}
예제 #15
0
		/// <summary>
		/// Tries to set a named property or field
		/// </summary>
		/// <param name="luaState"></param>
		/// <param name="targetType"></param>
		/// <param name="target"></param>
		/// <param name="bindingType"></param>
		/// <returns>false if unable to find the named member, true for success</returns>
		bool TrySetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType, out string detailMessage)
		{
			detailMessage = null;   // No error yet

			// If not already a string just return - we don't want to call tostring - which has the side effect of 
			// changing the lua typecode to string
			// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
			// be true for isstring.
			if (LuaLib.LuaType (luaState, 2) != LuaTypes.String) {
				detailMessage = "property names must be strings";
				return false;
			}

			// We only look up property names by string
			string fieldName = LuaLib.LuaToString (luaState, 2).ToString ();
			if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter (fieldName [0]) || fieldName [0] == '_')) {
				detailMessage = "invalid property name";
				return false;
			}

			// Find our member via reflection or the cache
			var member = (MemberInfo)CheckMemberCache (memberCache, targetType, fieldName);
			if (member == null) {
				var members = targetType.GetMember (fieldName, bindingType | BindingFlags.Public);

				if (members.Length > 0) {
					member = members [0];
					SetMemberCache (memberCache, targetType, fieldName, member);
				} else {
					detailMessage = "field or property '" + fieldName + "' does not exist";
					return false;
				}
			}

			if (member.MemberType == MemberTypes.Field) {
				var field = (FieldInfo)member;
				object val = translator.GetAsType (luaState, 3, field.FieldType);

				try {
					field.SetValue (target, val);
				} catch (Exception e) {
					ThrowError (luaState, e);
				}

				// We did a call
				return true;
			} else if (member.MemberType == MemberTypes.Property) {
				var property = (PropertyInfo)member;
				object val = translator.GetAsType (luaState, 3, property.PropertyType);

				try {
					property.SetValue (target, val, null);
				} catch (Exception e) {
					ThrowError (luaState, e);
				}

				// We did a call
				return true;
			}

			detailMessage = "'" + fieldName + "' is not a .net field or property";
			return false;
		}
예제 #16
0
		void SetMemberCache (Dictionary<object, object> memberCache, ProxyType objType, string memberName, object member)
		{
			Dictionary<object, object> members = null;
			object memberCacheValue = null;

			if (memberCache.TryGetValue(objType, out memberCacheValue)) {
				members = (Dictionary<object, object>)memberCacheValue;
			} else {
				members = new Dictionary<object, object>();
				memberCache[objType] = members;
			}

			members [memberName] = member;
		}
예제 #17
0
파일: API.cs 프로젝트: fankidark/ME_NLua
 //    --lua中添加个照相机例子:
 // local carm=GameObject("carm")
 // API.AddComponent(carm,Camera)
 public static UnityEngine.Component AddComponent(GameObject obj, ProxyType t)
 {
     return obj.AddComponent(t.UnderlyingSystemType);
 }