public static MacroSpec CompileData(DeviceProfile profile) { var res = new MacroSpec(); foreach (var op in MacroOpManager.FindAll()) { var xmlOp = new MacroOperationSpec() { Id = op.Key.ToString() }; res.Operations.Add(xmlOp); IEnumerable <PropertyInfo> props = op.Value.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(prop => prop.GetCustomAttribute <NoSerializeAttribute>() == null) .OrderBy(prop => prop.GetCustomAttribute <SerializeAttribute>()?.StartByte ?? 999); foreach (PropertyInfo prop in props) { var fieldAttr = prop.GetCustomAttribute <MacroFieldAttribute>(); if (fieldAttr == null) { continue; } var xmlField = new MacroFieldSpec() { Id = fieldAttr.Id, Name = fieldAttr.Name, IsId = prop.GetCustomAttribute <CommandIdAttribute>() != null }; xmlOp.Fields.Add(xmlField); if (prop.GetCustomAttribute <BoolAttribute>() != null) { xmlField.Type = MacroFieldType.Bool; } else if (prop.GetCustomAttribute <Enum8Attribute>() != null || prop.GetCustomAttribute <Enum16Attribute>() != null || prop.GetCustomAttribute <Enum32Attribute>() != null) { xmlField.Type = prop.PropertyType.GetCustomAttribute <FlagsAttribute>() != null ? MacroFieldType.Flags : MacroFieldType.Enum; string mappedTypeName = TypeMappings.MapType(prop.PropertyType.FullName); Type mappedType = prop.PropertyType; if (mappedTypeName != mappedType.FullName && mappedTypeName.IndexOf("System.") != 0) { mappedType = GetType(mappedTypeName); } foreach (object val in Enum.GetValues(mappedType)) { string id = val.ToString(); var xmlAttr = mappedType.GetMember(val.ToString())[0].GetCustomAttribute <XmlEnumAttribute>(); if (xmlAttr != null) { id = xmlAttr.Name; } if (!AvailabilityChecker.IsAvailable(profile, val)) { continue; } // TODO check value is available for usage location xmlField.Values.Add(new MacroFieldValueSpec() { Id = id, Name = val.ToString(), }); } } else { SetNumericProps(profile, op.Key, xmlField, prop); } } } return(res); }