private static void SubscribeTokens <T, TAttr>(IInfoRpcProvider <T> provider, IEnumerable <KeyValuePair <byte?, TAttr> > tokens, Action <NetMessage, T> del) where TAttr : Attribute, IRpcAttribute { foreach (var token in tokens) { if (token.Value == null) { continue; } provider.SubscribeToRpc(token.Value.RpcId, del, defaultContinueForwarding: token.Value.DefaultContinueForwarding); } }
/// <summary> /// Subscribe TAttr marked methods on obj to the provider /// </summary> /// <typeparam name="TInfo"></typeparam> /// <typeparam name="TAttr"></typeparam> /// <param name="provider"></param> /// <param name="obj"></param> /// <param name="serializer"></param> /// <param name="logger"></param> public static void SubscribeObject <TInfo, TAttr>(IInfoRpcProvider <TInfo> provider, object obj, SerializationManager serializer, ILogger logger) where TAttr : Attribute, IRpcAttribute { if (obj == null) { return; } if (provider == obj) { return; } var objType = obj.GetType(); //logger.Info("Subscribing " + obj); ForEachRpc <TAttr>(objType, (method, parms, parmTypes, tokens) => { var msgDel = Delegate.CreateDelegate(typeof(Action <NetMessage, TInfo>), obj, method, false) as Action <NetMessage, TInfo>; if (msgDel != null) { SubscribeTokens(provider, tokens, msgDel); } else if (method.ReturnType == typeof(void)) { //the function isn't a deserializer function, so attempt to make our own from INetSerializable/default serializers if (!CheckParameterSerialization <TInfo>(serializer, method, parms, logger)) { return; } DynamicMethodDelegate pre; RpcCallers.TryGetValue(method.MethodHandle, out pre); //prevent the open delegate from needing a reference to this networkview? var deser = new RpcDeserializer <TInfo>(method, obj, serializer, parmTypes, @delegate: pre); msgDel = deser.Message; SubscribeTokens(provider, tokens, msgDel); } else { //method returns something, so it's a func processor logger.Error("Cannot subscribe method with a return type other than void"); } }); }