/// <summary> /// Subscribe TAttr marked methods on obj to the provider /// </summary> /// <typeparam name="TAttr">Attribute type</typeparam> /// <param name="provider"></param> /// <param name="obj"></param> /// <param name="serializer"></param> /// <param name="logger"></param> public static void SubscribeObject <TAttr>(IRpcProvider 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>), obj, method, false) as Action <NetMessage>; 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 <BadInfoType>(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 <BadInfoType>(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"); } }); }
/// <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 SubscribeComponent <TAttr>(IComponentRpcProvider 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); byte compId; if (!objType.GetNetId(out compId)) { throw new Exception("Cannot subscribe type " + objType + " as it lacks the NetComponentAttribute"); } ForEachRpc <TAttr>(objType, (method, parms, parmTypes, tokens) => { var msgDel = Delegate.CreateDelegate(typeof(Action <NetMessage>), obj, method, false) as Action <NetMessage>; if (msgDel != null) { SubscribeTokens(provider, compId, tokens, msgDel); return; } var fncDel = Delegate.CreateDelegate(typeof(Func <NetMessage, object>), obj, method, false) as Func <NetMessage, object>; if (fncDel != null) { SubscribeTokens(provider, compId, tokens, fncDel); return; } if (method.ReturnType == typeof(void)) { //the function isn't a deserializer function, so attempt to make our own from INetSerializable/default serializers if (!CheckParameterSerialization <BadInfoType>(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 <BadInfoType>(method, obj, serializer, parmTypes, @delegate: pre); msgDel = deser.Message; SubscribeTokens(provider, compId, tokens, msgDel); } else { //method returns something, so it's a func processor if (!CheckParameterSerialization <BadInfoType>(serializer, method, parms, logger)) { return; } if (!serializer.CanSerialize(method.ReturnType)) { logger.Error($"Tried to subscribe method {method} for rpc functions, but return type {method.ReturnType} cannot be serialized"); return; } DynamicMethodDelegate pre; RpcCallers.TryGetValue(method.MethodHandle, out pre); var deser = new RpcDeserializer <object>(method, obj, serializer, parmTypes, @delegate: pre); fncDel = deser.ReturnMessage; SubscribeTokens(provider, compId, tokens, fncDel); } }); }