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); }
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(); }