예제 #1
0
        private static Func <object, MyClientInfo> GenerateAllocateClientInfo()
        {
            var clientDataType = Type.GetType(ClientData.InternalTypeName);

            if (clientDataType == null)
            {
                throw new InvalidOperationException("Couldn't find " +
                                                    ClientData.InternalTypeName);
            }
            var ctor = typeof(MyClientInfo).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
                                                           new[] { clientDataType }, null);

            if (ctor == null)
            {
                throw new InvalidOperationException("Couldn't find MyClientInfo(ClientData)");
            }

            var meth = new DynamicMethod(nameof(AllocateClientInfo), typeof(MyClientInfo), new[] { typeof(object) },
                                         true);
            var gen = new LoggingIlGenerator(meth.GetILGenerator(), _level);

            gen.EmitComment("// Start" + nameof(AllocateClientInfo));
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, clientDataType);
            gen.Emit(OpCodes.Newobj, ctor);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End" + nameof(AllocateClientInfo));
            Check(meth);
            return(meth.CreateDelegate <Func <object, MyClientInfo> >());
        }
예제 #2
0
        private static Action <object> GenerateCachingIslandDataApplyRemovals()
        {
            var type = Type.GetType(_clientDataIsland);

            if (type == null)
            {
                throw new InvalidOperationException("Couldn't find " + _clientDataIsland);
            }

            var cacheType = typeof(CachingHashSet <>).MakeGenericType(type);
            var backing   = cacheType.GetMethod("ApplyRemovals", BindingFlags.Instance | BindingFlags.Public);

            if (backing == null)
            {
                throw new InvalidOperationException("Couldn't find ApplyRemovals");
            }
            var meth = new DynamicMethod(nameof(ClientDataIslandsApplyRemovals), typeof(void),
                                         new[] { typeof(object) }, true);
            var gen = new LoggingIlGenerator(meth.GetILGenerator(), _level);

            gen.EmitComment("// Start " + meth.Name);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, cacheType);
            gen.Emit(OpCodes.Callvirt, backing);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End " + meth.Name);
            Check(meth);
            return(meth.CreateDelegate <Action <object> >());
        }
예제 #3
0
        GenerateCreateNewCachedIsland()
        {
            var clientDataType = Type.GetType(ClientData.InternalTypeName);

            if (clientDataType == null)
            {
                throw new InvalidOperationException("Couldn't fine " +
                                                    ClientData.InternalTypeName);
            }

            var type = Type.GetType(_clientDataIsland);

            if (type == null)
            {
                throw new InvalidOperationException("Couldn't find " + _clientDataIsland);
            }

            var backing = clientDataType.GetMethod("CreateNewCachedIsland");

            if (backing == null)
            {
                throw new InvalidOperationException("Couldn't find CreateNewCachedIsland");
            }

            var meth = new DynamicMethod(nameof(CreateNewCachedIsland), typeof(IslandData),
                                         new[] { typeof(object), typeof(IMyReplicable), typeof(HashSet <IMyReplicable>), typeof(MyTimeSpan) },
                                         true);

            var gen = new LoggingIlGenerator(meth.GetILGenerator(), _level);

            gen.EmitComment("// Start " + meth.Name);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, clientDataType);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Ldarg_2);
            gen.Emit(OpCodes.Ldarg_3);
            gen.Emit(OpCodes.Callvirt, backing);

            var islandInternal = gen.DeclareLocal(type);
            var islandExternal = gen.DeclareLocal(typeof(IslandData));

            gen.Emit(OpCodes.Stloc, islandInternal);
            EmitCopyAs(gen, islandInternal, islandExternal);
            gen.Emit(OpCodes.Ldloc, islandExternal);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End " + meth.Name);

            Check(meth);
            return(meth.CreateDelegate <Func <object, IMyReplicable, HashSet <IMyReplicable>, MyTimeSpan, IslandData> >());
        }
예제 #4
0
        GenerateClientDataReplicableToIslandTryGetValue()
        {
            var type = Type.GetType(_clientDataIsland);

            if (type == null)
            {
                throw new InvalidOperationException("Couldn't find " + _clientDataIsland);
            }

            var cacheType = typeof(Dictionary <,>).MakeGenericType(typeof(IMyStreamableReplicable), type);
            var backing   = cacheType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public);

            if (backing == null)
            {
                throw new InvalidOperationException("Couldn't find TryGetValue");
            }
            var meth = new DynamicMethod(nameof(ClientDataReplicableToIslandTryGetValue), typeof(bool),
                                         new[] { typeof(object), typeof(IMyStreamableReplicable), typeof(IslandData).MakeByRefType() }, true);
            var gen = new LoggingIlGenerator(meth.GetILGenerator(), _level);

            gen.EmitComment("// Start " + meth.Name);
            var islandInternal = gen.DeclareLocal(type);
            var islandExternal = gen.DeclareLocal(typeof(IslandData));
            var tmpResult      = gen.DeclareLocal(typeof(bool));

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, cacheType);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Ldloca, islandInternal);
            gen.Emit(OpCodes.Callvirt, backing);
            gen.Emit(OpCodes.Stloc, tmpResult);

            EmitCopyAs(gen, islandInternal, islandExternal);

            gen.Emit(OpCodes.Ldarg_2);
            gen.Emit(OpCodes.Ldloc, islandExternal);
            gen.Emit(OpCodes.Stobj, typeof(IslandData));

            gen.Emit(OpCodes.Ldloc, tmpResult);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End " + meth.Name);

            Check(meth);
            return((TryGetValueTemplate <IMyStreamableReplicable, IslandData>)meth.CreateDelegate(
                       typeof(TryGetValueTemplate <IMyStreamableReplicable, IslandData>)));
        }
예제 #5
0
        private static Action <object, IslandData> GenerateRemoveCachedIsland()
        {
            var clientDataType = Type.GetType(ClientData.InternalTypeName);

            if (clientDataType == null)
            {
                throw new InvalidOperationException("Couldn't fine " +
                                                    ClientData.InternalTypeName);
            }

            var type = Type.GetType(_clientDataIsland);

            if (type == null)
            {
                throw new InvalidOperationException("Couldn't find " + _clientDataIsland);
            }

            var backing = clientDataType.GetMethod("RemoveCachedIsland");

            if (backing == null)
            {
                throw new InvalidOperationException("Couldn't find RemoveCachedIsland");
            }
            var meth = new DynamicMethod(nameof(RemoveCachedIsland), typeof(void),
                                         new[] { typeof(object), typeof(IslandData) }, true);
            var gen = new LoggingIlGenerator(meth.GetILGenerator(), _level);

            gen.EmitComment("// Start " + meth.Name);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, clientDataType);
            var islandExternal = gen.DeclareLocal(typeof(IslandData));
            var islandInternal = gen.DeclareLocal(type);

            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Stloc, islandExternal);
            EmitCopyAs(gen, islandExternal, islandInternal);
            gen.Emit(OpCodes.Ldloc, islandInternal);
            gen.Emit(OpCodes.Callvirt, backing);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End " + meth.Name);

            Check(meth);
            return(meth.CreateDelegate <Action <object, IslandData> >());
        }
예제 #6
0
        private static DynamicProxyEnumerable <IslandData> GenerateClientDataIslandsEnumerator()
        {
            var type = Type.GetType(_clientDataIsland);

            if (type == null)
            {
                throw new InvalidOperationException("Couldn't find " + _clientDataIsland);
            }

            var meth = new DynamicMethod(nameof(ClientDataIslandsEnumerator) + "_Mapper", typeof(IslandData),
                                         new[] { typeof(IEnumerator) }, true);

            var genericEnumerator = typeof(IEnumerator <>).MakeGenericType(type);
            var currentProp       = genericEnumerator.GetProperty("Current");

            if (currentProp == null)
            {
                throw new InvalidOperationException("Couldn't find Current property on " + genericEnumerator.FullName);
            }

            var gen            = new LoggingIlGenerator(meth.GetILGenerator(), _level);
            var islandInternal = gen.DeclareLocal(type);
            var islandExternal = gen.DeclareLocal(typeof(IslandData));

            gen.EmitComment("// Start " + meth.Name);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Castclass, genericEnumerator);
            gen.Emit(OpCodes.Callvirt, currentProp.GetMethod);
            gen.Emit(OpCodes.Stloc, islandInternal);
            EmitCopyAs(gen, islandInternal, islandExternal);
            gen.Emit(OpCodes.Ldloc, islandExternal);
            gen.Emit(OpCodes.Ret);
            gen.EmitComment("// End " + meth.Name);

            Check(meth);
            return(new DynamicProxyEnumerable <IslandData>((o) => ((IEnumerable)o).GetEnumerator(),
                                                           meth.CreateDelegate <Func <IEnumerator, IslandData> >()));
        }
예제 #7
0
        private static void EmitCopyAs(LoggingIlGenerator gen, LocalBuilder src, LocalBuilder dst)
        {
            var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            Debug.Assert(src.LocalType != null, "src.LocalType != null");
            Debug.Assert(dst.LocalType != null, "dst.LocalType != null");
            var fields = src.LocalType.GetFields(flags);

            gen.EmitComment($"Copy {src.LocalType} to {dst.LocalType}");
            gen.Emit(OpCodes.Ldloca, dst);
            gen.Emit(OpCodes.Initobj, dst.LocalType);
            foreach (var sf in fields)
            {
                gen.Emit(OpCodes.Ldloca, dst);
                gen.Emit(OpCodes.Ldloca, src);
                var df = dst.LocalType?.GetField(sf.Name, flags);
                Debug.Assert(df != null, $"{dst.LocalType}.{sf.Name} != null");
                gen.Emit(OpCodes.Ldfld, sf);
                gen.Emit(OpCodes.Stfld, df);
            }

            gen.EmitComment("EndCopy");
        }