public void Add(Delegate handler, RegisterEventHandler eventInfo) { dict.Add(handler, eventInfo); }
/// <summary>[-0, +2, e] /// Returns to Lua 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 <paramref name="objType"/> and <paramref name="methodName"/>). /// </summary> /// <exception cref="ArgumentNullException"><paramref name="objType"/> and <paramref name="methodName"/> are required</exception> int getMember(lua.State L, IReflect objType, object obj, string methodName, BindingFlags bindingType) { Debug.Assert(interpreter.IsSameLua(L)); Debug.Assert(objType != null && methodName != null); Debug.Assert((obj == null) == (objType is ProxyType)); Debug.Assert((obj == null) != (objType is Type)); Debug.Assert((obj == null) == ((bindingType & BindingFlags.Static) == BindingFlags.Static)); Debug.Assert((obj == null) != ((bindingType & BindingFlags.Instance) == BindingFlags.Instance)); MemberInfo member = null; object cachedMember = checkMemberCache(objType, methodName); if (cachedMember != null) { var cachedMethod = cachedMember as lua.CFunction; if (cachedMethod != null) { luaclr.pushcfunction(L, cachedMethod); lua.pushboolean(L, true); return(2); } Debug.Assert(cachedMember is MemberInfo); member = (MemberInfo)cachedMember; } else { MemberInfo[] members = objType.GetMember(methodName, bindingType | luanet.LuaBindingFlags); if (members.Length != 0) { member = members[0]; #if DEBUG if (!(members.Length == 1 || member is MethodBase)) // todo { return(luaL.error(L, "Overloads for members other than methods are not implemented.")); } #endif } } object value = null; switch (member == null ? MemberTypes.All : member.MemberType) { default: // not found or found a constructor // kevinh - we want to throw an error because merely 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. return(luaL.error(L, string.Format("'{0}' does not contain a definition for '{1}'", objType.UnderlyingSystemType.FullName, methodName))); case MemberTypes.Method: var wrapper = new lua.CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(objType, methodName, wrapper); } luaclr.pushcfunction(L, wrapper); lua.pushboolean(L, true); return(2); case MemberTypes.Field: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "field read failed (access denied)")); } try { value = ((FieldInfo)member).GetValue(obj); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Property: // todo: support indexed properties if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "property call failed (access denied)")); } try { value = ((PropertyInfo)member).GetValue(obj, null); } catch (TargetInvocationException ex) { return(translator.throwError(L, luaclr.verifyex(ex.InnerException))); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Event: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "event read failed (access denied)")); } value = new RegisterEventHandler(translator.pendingEvents, obj, (EventInfo)member); translator.push(L, value); break; case MemberTypes.NestedType: var nestedType = (Type)member; if (translator.FindType(nestedType)) // don't hand out class references unless loaded/whitelisted { ObjectTranslator.pushType(L, nestedType); } else { lua.pushnil(L); } break; } if (cachedMember == null) { setMemberCache(objType, methodName, member); } // push false because we are NOT returning a function (see luaIndexFunction) lua.pushboolean(L, false); return(2); }