Пример #1
0
        public override void Execute()
        {
            var assembly   = new Assembly(ModuleDefinition);
            var components = assembly.GetAllTypesByAttribute(assembly.Import <ComponentAttribute>());

            var contextType   = assembly.Import <Context>();
            var intType       = assembly.Import <int>();
            var systemType    = assembly.Import <System.Type>();
            var voidType      = assembly.Import(typeof(void));
            var interfaceType = assembly.Import <IComponent>();

            foreach (var component in components)
            {
                var contextField  = component.AddField(ContextFieldName, contextType, FieldAttributes.Private, new This(component));
                var entityIdField = component.AddField(SourceEntityIdFieldName, intType, FieldAttributes.Private, new This(component));
                var typeField     = component.AddField(TypeFieldName, systemType, FieldAttributes.Private, new This(component));

                var setContextMethod  = component.AddMethod("SetContext", MonoCecilUtilities.GetPublicInterfaceMethodAttributes(), voidType, contextType.ToParameterType("context"));
                var setEntityIdMethod = component.AddMethod("SetEntityId", MonoCecilUtilities.GetPublicInterfaceMethodAttributes(), voidType, intType.ToParameterType("entityId"));
                var setTypeMethod     = component.AddMethod("SetType", MonoCecilUtilities.GetPublicInterfaceMethodAttributes(), voidType, systemType.ToParameterType("type"));

                var setContextMethodState = setContextMethod.GetState(Method.DefaultStates.MethodStart);
                setContextMethodState.AddFieldSet(contextField, setContextMethodState.GetArgument(0));

                var setEntityIdMethodState = setEntityIdMethod.GetState(Method.DefaultStates.MethodStart);
                setEntityIdMethodState.AddFieldSet(entityIdField, setEntityIdMethodState.GetArgument(0));

                var setTypeMethodState = setTypeMethod.GetState(Method.DefaultStates.MethodStart);
                setTypeMethodState.AddFieldSet(typeField, setTypeMethodState.GetArgument(0));

                component.ImplementInterface(interfaceType);

                var properties = component.GetProperties(new This(component))
                                 .Where(p => p.HasAttribute(assembly.Import <NotifyPropertyChangedAttribute>()));

                foreach (var property in properties)
                {
                    var setMethod = property.GetPropertySetMethod();
                    if (setMethod == null)
                    {
                        continue;
                    }

                    var setDirtyMethod = assembly.Import(contextType.GetMethod(MarkDirtyMethodName,
                                                                               intType.ToParameterType(), systemType.ToParameterType()));

                    var setMethodState = setMethod.GetState(Method.DefaultStates.MethodEnd);
                    setMethodState.Call(setDirtyMethod, null, contextField, entityIdField, typeField);
                }
            }

            var indexWeaver = new ECSIndexWeaver();

            indexWeaver.Execute(ModuleDefinition);
        }
Пример #2
0
        public void Execute(ModuleDefinition moduleDefinition)
        {
            var assembly   = new Assembly(moduleDefinition);
            var components = assembly.GetAllTypesByAttribute(assembly.Import <ComponentAttribute>());

            var voidType    = assembly.Import(typeof(void));
            var contextType = assembly.Import <Context>();
            var intType     = assembly.Import <int>();
            var systemType  = assembly.Import <System.Type>();

            var addContextMethod = assembly.Import(contextType.GetMethod(AddEntityWithIndexMethodName,
                                                                         systemType.ToParameterType(), intType.ToParameterType(), intType.ToParameterType()));
            var removeContextMethod = assembly.Import(contextType.GetMethod(RemoveEntityWithIndexMethodName,
                                                                            systemType.ToParameterType(), intType.ToParameterType(), intType.ToParameterType()));

            foreach (var component in components)
            {
                var properties = component.GetProperties(new This(component))
                                 .Where(p => p.HasAttribute(assembly.Import <EntityIndexAttribute>())).ToList();

                var addEntityByIndexMethod    = component.AddMethod("AddEntityByIndex", MonoCecilUtilities.GetPublicInterfaceMethodAttributes(), voidType);
                var removeEntityByIndexMethod = component.AddMethod("RemoveEntityByIndex", MonoCecilUtilities.GetPublicInterfaceMethodAttributes(), voidType);

                if (properties.Count != 1)
                {
                    continue;
                }

                var indexProperty     = properties.First();
                var getHashCodeMethod = assembly.Import(indexProperty.Type.GetMethod("GetHashCode", intType));

                var typeField         = component.GetField(ECSComponentsWeaver.TypeFieldName, new This(component));
                var contextField      = component.GetField(ECSComponentsWeaver.ContextFieldName, new This(component));
                var sourceEntityField = component.GetField(ECSComponentsWeaver.SourceEntityIdFieldName, new This(component));

                var addState = addEntityByIndexMethod.GetState(Method.DefaultStates.MethodStart);
                addState.
                AddVariable(0, intType).
                AddVariableSet(0, indexProperty).
                AddVariable(1, intType).
                Call(getHashCodeMethod, addState.GetVariable(1), addState.GetVariable(0, true)).
                Call(addContextMethod, null, contextField, typeField, addState.GetVariable(1), sourceEntityField);

                var removeState = removeEntityByIndexMethod.GetState(Method.DefaultStates.MethodStart);
                removeState.
                AddVariable(0, intType).
                AddVariableSet(0, indexProperty).
                AddVariable(1, intType).
                Call(getHashCodeMethod, removeState.GetVariable(1), removeState.GetVariable(0, true)).
                Call(removeContextMethod, null, contextField, typeField, removeState.GetVariable(1), sourceEntityField);

                foreach (var property in properties)
                {
                    var setMethod = property.GetPropertySetMethod();
                    if (setMethod == null)
                    {
                        continue;
                    }

                    setMethod.GetState(Method.DefaultStates.MethodStart).Call(removeEntityByIndexMethod, null, new This(component));
                    setMethod.GetState(Method.DefaultStates.MethodEnd).Call(addEntityByIndexMethod, null, new This(component));
                }
            }

            //ExceptionLogger.Save();
        }