Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Linq.Expressions;
- using System.Reflection.Emit;
- using System.Threading;
- namespace MirrorNet
- {
- // Base class for packets
- // This will be derived by users and should only contain basic type fields
- public class UserPacket
- {
- }
- public class MirrorNetManager
- {
- private static MirrorNetManager instance = new MirrorNetManager();
- public static MirrorNetManager Instance
- {
- get { return instance; }
- }
- // Dictionary: packetType -> field -> getter | setter
- private class PropertyDictionary : Dictionary<Type, Dictionary<FieldInfo, Delegate>>
- {
- }
- private Dictionary<int, PacketConstructor> m_packetConstructors = new Dictionary<int, PacketConstructor>();
- private PropertyDictionary m_packetFieldGetters = new PropertyDictionary();
- private PropertyDictionary m_packetFieldSetters = new PropertyDictionary();
- public void SetValue(UserPacket packet, FieldInfo field, object value)
- {
- var setDelegate = m_packetFieldSetters[packet.GetType()][field];
- dynamic setAction = setDelegate; //Convert.ChangeType(setDelegate, setDelegate.GetType());
- dynamic setObject = packet; //Convert.ChangeType(packet, packet.GetType());
- dynamic setValue = value; //Convert.ChangeType(value, value.GetType());
- setAction.Invoke(setObject, setValue);
- //setDelegate.DynamicInvoke(packet, value);
- }
- public object GetValue(UserPacket packet, FieldInfo field)
- {
- var getDelegate = m_packetFieldGetters[packet.GetType()][field];
- dynamic getFunction = getDelegate; //Convert.ChangeType(getDelegate, getDelegate.GetType());
- dynamic getObject = packet; //Convert.ChangeType(packet, packet.GetType());
- return getFunction.Invoke(getObject);
- //return getDelegate.DynamicInvoke(packet);
- }
- public void InitializePackets(Assembly packetsAssembly)
- {
- var typesArray = packetsAssembly.GetTypes();
- foreach (Type type in typesArray)
- {
- if (type.BaseType == typeof(UserPacket))
- {
- InsertPacketConstructor(type);
- InsertSettersAndGetters(type);
- }
- }
- }
- private void InsertSettersAndGetters(Type type)
- {
- Dictionary<FieldInfo, Delegate> getters = new Dictionary<FieldInfo, Delegate>();
- Dictionary<FieldInfo, Delegate> setters = new Dictionary<FieldInfo, Delegate>();
- foreach (FieldInfo field in type.GetFields())
- {
- Delegate getDelegate = CreateGetter(type, field.FieldType, field);
- Delegate setDelegate = CreateSetter(type, field.FieldType, field);
- getters.Add(field, getDelegate);
- setters.Add(field, setDelegate);
- }
- m_packetFieldGetters.Add(type, getters);
- m_packetFieldSetters.Add(type, setters);
- }
- private Delegate CreateGetter(Type classType, Type getReturnType, FieldInfo field)
- {
- string methodName = field.ReflectedType.FullName + ".get_" + field.Name;
- Type[] parameterTypes = new Type[1] { classType };
- DynamicMethod getterMethod = new DynamicMethod(methodName, getReturnType, parameterTypes, true);
- ILGenerator gen = getterMethod.GetILGenerator();
- if (field.IsStatic)
- {
- gen.Emit(OpCodes.Ldsfld, field);
- }
- else
- {
- gen.Emit(OpCodes.Ldarg_0);
- gen.Emit(OpCodes.Ldfld, field);
- }
- gen.Emit(OpCodes.Ret);
- // Create the specific Func<,> instance
- Type[] typeArgs = new Type[] { classType, getReturnType };
- Type generic = typeof(Func<,>);
- Type genInstance = generic.MakeGenericType(typeArgs);
- Delegate getterDelegate = getterMethod.CreateDelegate(genInstance);
- return getterDelegate;
- }
- private Delegate CreateSetter(Type classType, Type setValueType, FieldInfo field)
- {
- string methodName = field.ReflectedType.FullName + ".set_" + field.Name;
- Type[] parameters = new Type[2]
- {
- classType,
- setValueType
- };
- DynamicMethod setterMethod = new DynamicMethod(methodName, null, parameters);
- ILGenerator gen = setterMethod.GetILGenerator();
- if (field.IsStatic)
- {
- gen.Emit(OpCodes.Ldarg_1);
- gen.Emit(OpCodes.Stsfld, field);
- }
- else
- {
- gen.Emit(OpCodes.Ldarg_0);
- gen.Emit(OpCodes.Ldarg_1);
- gen.Emit(OpCodes.Stfld, field);
- }
- gen.Emit(OpCodes.Ret);
- // Create the specific Action<,> instance
- Type[] typeArgs = new Type[] { classType, setValueType };
- Type generic = typeof(Action<,>);
- Type genInstance = generic.MakeGenericType(typeArgs);
- Delegate ret = setterMethod.CreateDelegate(genInstance);
- return ret;
- }
- private void InsertPacketConstructor(Type packetType)
- {
- foreach (var member in packetType.GetFields())
- {
- Console.WriteLine(member);
- // TODO: Implement
- }
- }
- }
- }
- // THIS IS IN A DIFERENT ASSEMBLY
- namespace MirrorNetTesting
- {
- // This is just an example packet
- public class StudentPacket : UserPacket
- {
- public int age;
- public int height;
- public double grades;
- public string firstName;
- public string lastName;
- }
- class Program
- {
- static void Main(string[] args)
- {
- Assembly asm = Assembly.GetAssembly(typeof(StudentPacket));
- MirrorNetManager.Instance.InitializePackets(asm);
- PerformanceTesting();
- Console.ReadLine();
- }
- public static void PerformanceTesting()
- {
- int studentsCount = 1000 * 100;
- StudentPacket[] studentsArray = new StudentPacket[studentsCount];
- //////////////////////////////////////////////////////////////////////////
- Random rnd = new Random();
- for (int i = 0; i < studentsArray.Length; i++)
- {
- StudentPacket student = new StudentPacket();
- student.age = rnd.Next();
- student.height = rnd.Next();
- student.grades = rnd.NextDouble();
- student.firstName = "First " + rnd.Next().ToString();
- student.lastName = "Last " + rnd.Next().ToString();
- studentsArray[i] = student;
- }
- var fieldsArray = typeof(StudentPacket).GetFields().ToArray();
- //////////////////////////////////////////////////////////////////////////
- // Begin normal getter test
- Console.WriteLine("Testing normal getters");
- Stopwatch normalGetterSw = new Stopwatch();
- normalGetterSw.Start();
- foreach (var student in studentsArray)
- {
- //object getValue;
- var getAge = student.age;
- var getHeight = student.height;
- var getGrades = student.grades;
- var getFirstName = student.firstName;
- var getLastName = student.lastName;
- }
- normalGetterSw.Stop();
- //////////////////////////////////////////////////////////////////////////
- // Begin reflection getter test
- Console.WriteLine("Testing reflection getters");
- Stopwatch reflectionGetterSw = new Stopwatch();
- reflectionGetterSw.Start();
- foreach (var student in studentsArray)
- {
- object getValue;
- for (int i = 0; i < fieldsArray.Length; i++ )
- {
- FieldInfo field = fieldsArray[i];
- getValue = MirrorNetManager.Instance.GetValue(student, field);
- }
- }
- reflectionGetterSw.Stop();
- //////////////////////////////////////////////////////////////////////////
- // Begin normal setter test
- Console.WriteLine("Testing normal setters");
- Stopwatch normalSetterSw = new Stopwatch();
- int age = 10;
- int height = 12;
- double grades = 1432.523d;
- string firstName = "first name";
- string lastName = "last name";
- normalSetterSw.Start();
- foreach (var student in studentsArray)
- {
- student.age = age;
- student.height = height;
- student.grades = grades;
- student.firstName = firstName;
- student.lastName = lastName;
- }
- normalSetterSw.Stop();
- //////////////////////////////////////////////////////////////////////////
- // Begin reflection setter test
- Console.WriteLine("Testing reflection setters ");
- Stopwatch reflectionSetterSw = new Stopwatch();
- object[] setValues = new object[]
- {
- age,
- height,
- grades,
- firstName,
- lastName
- };
- reflectionSetterSw.Start();
- foreach (var student in studentsArray)
- {
- for (int i = 0; i < fieldsArray.Length; i++ )
- {
- FieldInfo field = fieldsArray[i];
- MirrorNetManager.Instance.SetValue(student, field, setValues[i]);
- }
- }
- reflectionSetterSw.Stop();
- //////////////////////////////////////////////////////////////////////////
- Console.WriteLine("Normal getter: \t {0}", normalGetterSw.ElapsedMilliseconds);
- Console.WriteLine("Normal setter: \t {0}", normalSetterSw.ElapsedMilliseconds);
- Console.WriteLine("Reflection getter: \t {0}", reflectionGetterSw.ElapsedMilliseconds);
- Console.WriteLine("Reflection setter: \t {0}", reflectionSetterSw.ElapsedMilliseconds);
- //////////////////////////////////////////////////////////////////////////
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement