private void _Invoke(ref object RetObject, params object[] args) { if (args.Length < ArgumentTypes.Length) //check if a argument is using "params x[] args" { throw new Exception("missing arguments"); } List <int> usedDelegates = new List <int>(); PayloadWriter pw = new PayloadWriter(); pw.WriteInteger(sharedClass.SharedId); pw.WriteInteger(MethodId); pw.WriteByte(isDelegate ? (byte)1 : (byte)0); if (isDelegate) { pw.WriteInteger(this.DelegateId); pw.WriteInteger(this.sharedClass.SharedId); } SmartSerializer serializer = new SmartSerializer(); for (int i = 0; i < args.Length; i++) { object obj = ArgumentTypes[i].IsByRef ? null : args[i]; if (DelegateIndex.ContainsKey(i)) { obj = null; } byte[] SerializedObj = serializer.Serialize(obj); pw.WriteInteger(SerializedObj.Length); pw.WriteBytes(SerializedObj); } for (int i = 0; i < DelegateIndex.Count; i++) { Delegate del = args[DelegateIndex.Keys[i]] as Delegate; if (del != null) { if (del.Method == null) { throw new Exception("Target delegate is NULL"); } int id = rnd.Next(); while (Delegates.ContainsKey(id)) { id = rnd.Next(); } pw.WriteByte(1); SharedDelegate sharedDel = new SharedDelegate(del.Method, sharedClass, del.GetType(), id, del, this.MethodId); sharedDel.sharedMethod.Unchecked = DelegateIndex.Values[i].isUnchecked; sharedDel.sharedMethod.usePacketQueue = DelegateIndex.Values[i].UsePacketQueue; sharedDel.sharedMethod.useUdp = DelegateIndex.Values[i].UseUDP; sharedDel.sharedMethod.NoWaitingTime = DelegateIndex.Values[i].NoWaitingTime; pw.WriteObject(sharedDel); if (!isDelegate) { Delegates.Add(id, sharedDel); } continue; } pw.WriteByte(0); } if (Unchecked || useUdp) { //just execute the method and don't wait for response sharedClass.connection.Connection.SendMessage(new MsgExecuteMethod(0, pw.ToByteArray(), false)); } else { SyncObject syncObject = null; Random rnd = new Random(); int RequestId = rnd.Next(); lock (sharedClass.connection.MethodRequests) { while (sharedClass.connection.MethodRequests.ContainsKey(RequestId)) { RequestId = rnd.Next(); } syncObject = new SyncObject(sharedClass.connection.Connection.Connection); sharedClass.connection.MethodRequests.Add(RequestId, syncObject); sharedClass.connection.Connection.SendMessage(new MsgExecuteMethod(RequestId, pw.ToByteArray(), true)); } RetObject = syncObject.Wait <ReturnResult>(null, 0); } /*if (callback != null) * { * sharedClass.connection.BeginSendRequest(pw, callback, true, this.usePacketQueue); * } * else * { * if (Unchecked || useUdp) * { * //just don't wait till we received something back since it's a VOID anyway * sharedClass.connection.BeginSendRequest(pw, (object obj) => { }, false, this.usePacketQueue); * } * else * { * RetObject = sharedClass.connection.SendRequest(pw, this.usePacketQueue); * } * }*/ serializer = null; }
private void _Invoke(ref object RetObject, params object[] args) { if (args.Length < ArgumentTypes.Length) //check if a argument is using "params x[] args" { throw new Exception("missing arguments"); } List <int> usedDelegates = new List <int>(); PayloadWriter pw = new PayloadWriter(); SmartSerializer serializer = new SmartSerializer(); for (int i = 0; i < args.Length; i++) { object obj = ArgumentTypes[i].IsByRef ? null : args[i]; if (DelegateIndex.ContainsKey(i)) { obj = null; } byte[] SerializedObj = serializer.Serialize(obj); pw.WriteInteger(SerializedObj.Length); pw.WriteBytes(SerializedObj); } for (int i = 0; i < DelegateIndex.Count; i++) { Delegate del = args[DelegateIndex.Keys[i]] as Delegate; if (del != null) { if (del.Method == null) { throw new Exception("Target delegate is NULL"); } int id = rnd.Next(); while (Delegates.ContainsKey(id)) { id = rnd.Next(); } pw.WriteBool(true); SharedDelegate sharedDel = new SharedDelegate(del.Method, sharedClass, del.GetType(), id, del, this.MethodId); sharedDel.sharedMethod.Unchecked = this.Unchecked; //DelegateIndex.Values[i].isUnchecked; sharedDel.sharedMethod.usePacketQueue = this.usePacketQueue; //DelegateIndex.Values[i].UsePacketQueue; sharedDel.sharedMethod.useUdp = this.useUdp; //DelegateIndex.Values[i].UseUDP; pw.WriteObject(sharedDel); if (!isDelegate) { Delegates.Add(id, sharedDel); } continue; } pw.WriteBool(false); } try { if (Unchecked || useUdp) { //just execute the method and don't wait for response sharedClass.Client.Send(new MsgExecuteMethod(0, pw.ToByteArray(), false, sharedClass.SharedId, MethodId, this.DelegateId, this.sharedClass.SharedId)); } else { SyncObject syncObject = null; Random rnd = new Random(); int RequestId = rnd.Next(); lock (sharedClass.Client.Requests) { while (sharedClass.Client.Requests.ContainsKey(RequestId)) { RequestId = rnd.Next(); } syncObject = new SyncObject(sharedClass.Client); sharedClass.Client.Requests.Add(RequestId, syncObject); sharedClass.Client.Send(new MsgExecuteMethod(RequestId, pw.ToByteArray(), true, sharedClass.SharedId, MethodId, this.DelegateId, this.sharedClass.SharedId)); } RetObject = syncObject.Wait <ReturnResult>(null, TimeOutLength); if (syncObject.TimedOut) { //copying the object in memory, maybe a strange way todo it but it works RetObject = new ReturnResult(serializer.Deserialize(serializer.Serialize(this.TimeOutValue)), false); } } } catch { //client most likely disconnected and was unable to send the message RetObject = null; } /*if (callback != null) * { * sharedClass.connection.BeginSendRequest(pw, callback, true, this.usePacketQueue); * } * else * { * if (Unchecked || useUdp) * { * //just don't wait till we received something back since it's a VOID anyway * sharedClass.connection.BeginSendRequest(pw, (object obj) => { }, false, this.usePacketQueue); * } * else * { * RetObject = sharedClass.connection.SendRequest(pw, this.usePacketQueue); * } * }*/ serializer = null; }
public static Delegate CreateDelegate(SharedDelegate sharedDel) { lock (IncrementalName) { int SharedId = sharedDel.sharedMethod.sharedClass.SharedId; if (!cache.ContainsKey(SharedId)) { cache.Add(SharedId, new SortedList <int, Delegate>()); } if (cache[SharedId].ContainsKey(sharedDel.sharedMethod.DelegateId)) { return(cache[SharedId][sharedDel.sharedMethod.DelegateId]); } TypeBuilder typeBuilder = modBuilder.DefineType("_Del" + IncrementName(), TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout | TypeAttributes.Sealed, typeof(object)); FieldBuilder fb = typeBuilder.DefineField("$haredDelegate", typeof(SharedDelegate), FieldAttributes.Private); ConstructorBuilder constructor = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { typeof(SharedDelegate) }); ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0]); ILGenerator il = constructor.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, conObj); //set sharedClass variable il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, fb); il.Emit(OpCodes.Ret); string MethodName = IncrementName(); MethodBuilder builder = typeBuilder.DefineMethod(MethodName, MethodAttributes.Public, CallingConventions.HasThis, sharedDel.sharedMethod.ReturnType, sharedDel.sharedMethod.ArgumentTypes); builder.CreateMethodBody(null, 0); ILGenerator gen = builder.GetILGenerator(); MethodInfo SharedCall = typeof(SharedDelegate).GetMethod("Invoke"); LocalBuilder lb = gen.DeclareLocal(typeof(object[])); //init local array gen.Emit(OpCodes.Ldc_I4, sharedDel.sharedMethod.ArgumentTypes.Length); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Stloc_0); for (int i = 0; i < sharedDel.sharedMethod.ArgumentTypes.Length; i++) { gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (sharedDel.sharedMethod.ArgumentTypes[i].IsByRef) { //remove & at the end since ref/out adds & at the end of the argument sharedDel.sharedMethod.ArgumentTypes[i] = Type.GetType(sharedDel.sharedMethod.ArgumentTypes[i].FullName.Substring(0, sharedDel.sharedMethod.ArgumentTypes[i].FullName.Length - 1)); } gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ArgumentTypes[i]); gen.Emit(OpCodes.Stelem_Ref); } //load $haredDelegate gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fb); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Callvirt, SharedCall); bool isInt = sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int32)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt32)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Boolean)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int64)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt64)); if (sharedDel.sharedMethod.ReturnType.FullName != "System.Void" && !isInt) { gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ReturnType); } else if (sharedDel.sharedMethod.ReturnType.FullName == "System.Void") //no return { gen.Emit(OpCodes.Pop); } else if (isInt) { gen.Emit(OpCodes.Unbox, sharedDel.sharedMethod.ReturnType); gen.Emit(OpCodes.Ldobj, sharedDel.sharedMethod.ReturnType); } gen.Emit(OpCodes.Ret); Type InitType = typeBuilder.CreateType(); object InitObject = InitType.GetConstructor(new Type[] { typeof(SharedDelegate) }).Invoke(new object[] { sharedDel }); MethodInfo info = InitObject.GetType().GetMethod(MethodName); return(Delegate.CreateDelegate(sharedDel.DelegateType, InitObject, info)); } }
private void _Invoke(ref object RetObject, params object[] args) { if (args.Length < ArgumentTypes.Length) //check if a argument is using "params x[] args" throw new Exception("missing arguments"); List<int> usedDelegates = new List<int>(); PayloadWriter pw = new PayloadWriter(); pw.WriteInteger(sharedClass.SharedId); pw.WriteInteger(MethodId); pw.WriteByte(isDelegate ? (byte)1 : (byte)0); if (isDelegate) { pw.WriteInteger(this.DelegateId); pw.WriteInteger(this.sharedClass.SharedId); } SmartSerializer serializer = new SmartSerializer(); for (int i = 0; i < args.Length; i++) { object obj = ArgumentTypes[i].IsByRef ? null : args[i]; if (DelegateIndex.ContainsKey(i)) obj = null; byte[] SerializedObj = serializer.Serialize(obj); pw.WriteInteger(SerializedObj.Length); pw.WriteBytes(SerializedObj); } for (int i = 0; i < DelegateIndex.Count; i++) { Delegate del = args[DelegateIndex.Keys[i]] as Delegate; if (del != null) { if (del.Method == null) throw new Exception("Target delegate is NULL"); int id = rnd.Next(); while(Delegates.ContainsKey(id)) id = rnd.Next(); pw.WriteByte(1); SharedDelegate sharedDel = new SharedDelegate(del.Method, sharedClass, del.GetType(), id, del, this.MethodId); sharedDel.sharedMethod.Unchecked = DelegateIndex.Values[i].isUnchecked; sharedDel.sharedMethod.usePacketQueue = DelegateIndex.Values[i].UsePacketQueue; sharedDel.sharedMethod.useUdp = DelegateIndex.Values[i].UseUDP; sharedDel.sharedMethod.NoWaitingTime = DelegateIndex.Values[i].NoWaitingTime; pw.WriteObject(sharedDel); if (!isDelegate) { Delegates.Add(id, sharedDel); } continue; } pw.WriteByte(0); } if (Unchecked || useUdp) { //just execute the method and don't wait for response sharedClass.connection.Connection.SendMessage(new MsgExecuteMethod(0, pw.ToByteArray(), false)); } else { SyncObject syncObject = null; Random rnd = new Random(); int RequestId = rnd.Next(); lock (sharedClass.connection.MethodRequests) { while(sharedClass.connection.MethodRequests.ContainsKey(RequestId)) RequestId = rnd.Next(); syncObject = new SyncObject(sharedClass.connection.Connection.Connection); sharedClass.connection.MethodRequests.Add(RequestId, syncObject); sharedClass.connection.Connection.SendMessage(new MsgExecuteMethod(RequestId, pw.ToByteArray(), true)); } RetObject = syncObject.Wait<ReturnResult>(null, 0); } /*if (callback != null) { sharedClass.connection.BeginSendRequest(pw, callback, true, this.usePacketQueue); } else { if (Unchecked || useUdp) { //just don't wait till we received something back since it's a VOID anyway sharedClass.connection.BeginSendRequest(pw, (object obj) => { }, false, this.usePacketQueue); } else { RetObject = sharedClass.connection.SendRequest(pw, this.usePacketQueue); } }*/ serializer = null; }
public static Delegate CreateDelegate(SharedDelegate sharedDel) { lock (IncrementalName) { int SharedId = sharedDel.sharedMethod.sharedClass.SharedId; if (!cache.ContainsKey(SharedId)) cache.Add(SharedId, new SortedList<int, Delegate>()); if (cache[SharedId].ContainsKey(sharedDel.sharedMethod.DelegateId)) return cache[SharedId][sharedDel.sharedMethod.DelegateId]; TypeBuilder typeBuilder = modBuilder.DefineType("_Del" + IncrementName(), TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout | TypeAttributes.Sealed, typeof(object)); FieldBuilder fb = typeBuilder.DefineField("$haredDelegate", typeof(SharedDelegate), FieldAttributes.Private); ConstructorBuilder constructor = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[] { typeof(SharedDelegate) }); ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0]); ILGenerator il = constructor.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, conObj); //set sharedClass variable il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, fb); il.Emit(OpCodes.Ret); string MethodName = IncrementName(); MethodBuilder builder = typeBuilder.DefineMethod(MethodName, MethodAttributes.Public, CallingConventions.HasThis, sharedDel.sharedMethod.ReturnType, sharedDel.sharedMethod.ArgumentTypes); builder.CreateMethodBody(null, 0); ILGenerator gen = builder.GetILGenerator(); MethodInfo SharedCall = typeof(SharedDelegate).GetMethod("Invoke"); LocalBuilder lb = gen.DeclareLocal(typeof(object[])); //init local array gen.Emit(OpCodes.Ldc_I4, sharedDel.sharedMethod.ArgumentTypes.Length); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Stloc_0); for (int i = 0; i < sharedDel.sharedMethod.ArgumentTypes.Length; i++) { gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (sharedDel.sharedMethod.ArgumentTypes[i].IsByRef) { //remove & at the end since ref/out adds & at the end of the argument sharedDel.sharedMethod.ArgumentTypes[i] = Type.GetType(sharedDel.sharedMethod.ArgumentTypes[i].FullName.Substring(0, sharedDel.sharedMethod.ArgumentTypes[i].FullName.Length - 1)); } gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ArgumentTypes[i]); gen.Emit(OpCodes.Stelem_Ref); } //load $haredDelegate gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fb); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Callvirt, SharedCall); bool isInt = sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int32)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt32)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Boolean)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int64)) || sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt64)); if (sharedDel.sharedMethod.ReturnType.FullName != "System.Void" && !isInt) { gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ReturnType); } else if (sharedDel.sharedMethod.ReturnType.FullName == "System.Void") //no return { gen.Emit(OpCodes.Pop); } else if (isInt) { gen.Emit(OpCodes.Unbox, sharedDel.sharedMethod.ReturnType); gen.Emit(OpCodes.Ldobj, sharedDel.sharedMethod.ReturnType); } gen.Emit(OpCodes.Ret); Type InitType = typeBuilder.CreateType(); object InitObject = InitType.GetConstructor(new Type[] { typeof(SharedDelegate) }).Invoke(new object[] { sharedDel }); MethodInfo info = InitObject.GetType().GetMethod(MethodName); return Delegate.CreateDelegate(sharedDel.DelegateType, InitObject, info); } }