public XMLComplexBaseTypeHandler CloneWithExclusions(DontSerializeMembersAttribute exclusions) { Debug.Assert(exclusions != null); var clone = (XMLComplexBaseTypeHandler)MemberwiseClone(); clone._clonedFrom = this; // Copy all field handlers to the clone, except the ones that are excluded. Dictionary <string, XMLFieldHandler> fieldHandlers = _fieldHandlers.Value; var cloneHandlers = new Dictionary <string, XMLFieldHandler>(); HashSet <string> excludedFields = exclusions.Members; foreach (KeyValuePair <string, XMLFieldHandler> fields in fieldHandlers) { XMLFieldHandler fieldHandler = fields.Value; if (excludedFields.Contains(fields.Key)) { fieldHandler = new XMLFieldHandler(fieldHandler.ReflectionInfo, fieldHandler.TypeHandler) { Skip = true } } ; cloneHandlers.Add(fields.Key, fieldHandler); } clone._fieldHandlers = new Lazy <Dictionary <string, XMLFieldHandler> >(cloneHandlers); return(clone); }
public IEnumerator <XMLFieldHandler> EnumFields() { Dictionary <string, XMLFieldHandler> handlers = _fieldHandlers.Value; foreach (KeyValuePair <string, XMLFieldHandler> field in handlers) { XMLFieldHandler fieldHandler = field.Value; if (fieldHandler.Skip) { continue; } yield return(fieldHandler); } }
protected virtual Dictionary <string, XMLFieldHandler> IndexFields() { // Gather fields and create field handlers for them. PropertyInfo[] properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); FieldInfo[] fields = Type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); var fieldHandlers = new Dictionary <string, XMLFieldHandler>(properties.Length + fields.Length); for (var i = 0; i < properties.Length; i++) { PropertyInfo property = properties[i]; // Only serialize properties with public get; set; and who aren't marked as "DontSerialize" MethodInfo readMethod = property.GetMethod; MethodInfo writeMethod = property.SetMethod; if (!property.CanRead || !property.CanWrite || readMethod == null || writeMethod == null || !readMethod.IsPublic || !writeMethod.IsPublic || property.CustomAttributes.Any(x => x.AttributeType == XMLHelpers.DontSerializeAttributeType)) { continue; } XMLFieldHandler handler = XMLHelpers.ResolveFieldHandler(property.PropertyType, new XMLReflectionHandler(property)); if (handler == null) { continue; } fieldHandlers.TryAdd(property.Name, handler); } for (var i = 0; i < fields.Length; i++) { FieldInfo field = fields[i]; // Exclude fields marked as "DontSerialize" if (field.CustomAttributes.Any(x => x.AttributeType == XMLHelpers.DontSerializeAttributeType)) { continue; } XMLFieldHandler handler = XMLHelpers.ResolveFieldHandler(field.FieldType, new XMLReflectionHandler(field)); if (handler == null) { continue; } fieldHandlers.TryAdd(field.Name, handler); } return(fieldHandlers); }
public static object?TransformClass(object window, Type newType) { var oldTypeHandler = (XMLComplexBaseTypeHandler?)XMLHelpers.GetTypeHandler(window.GetType()); var newTypeHandler = (XMLComplexBaseTypeHandler?)XMLHelpers.GetTypeHandler(newType); if (oldTypeHandler == null || newTypeHandler == null) { return(null); } object?newTypeObject = Activator.CreateInstance(newType, true); Debug.Assert(newTypeObject != null); IEnumerator <XMLFieldHandler>?oldFields = oldTypeHandler.EnumFields(); while (oldFields.MoveNext()) { XMLFieldHandler oldField = oldFields.Current; XMLFieldHandler?newFieldsMatch = null; IEnumerator <XMLFieldHandler>?newFields = newTypeHandler.EnumFields(); while (newFields.MoveNext()) { XMLFieldHandler newField = newFields.Current; if (newField.Name != oldField.Name || newField.TypeHandler != oldField.TypeHandler) { continue; } newFieldsMatch = newField; break; } if (newFieldsMatch == null) { continue; } object value = oldField.ReflectionInfo.GetValue(window); newFieldsMatch.ReflectionInfo.SetValue(newTypeObject, value); } return(newTypeObject); }
public override bool Serialize(object obj, StringBuilder output, int indentation = 1, XMLRecursionChecker recursionChecker = null, string fieldName = null) { if (obj == null) { return(false); } fieldName ??= TypeName; output.AppendJoin(XMLFormat.IndentChar, new string[indentation]); output.Append($"<{fieldName}>\n"); XMLFieldHandler keyHandler = _keyHandler.Value; XMLFieldHandler valueHandler = _valueHandler.Value; keyHandler.TypeHandler.Serialize(keyHandler.ReflectionInfo.GetValue(obj), output, indentation + 1, recursionChecker, "Key"); valueHandler.TypeHandler.Serialize(valueHandler.ReflectionInfo.GetValue(obj), output, indentation + 1, recursionChecker, "Value"); output.AppendJoin(XMLFormat.IndentChar, new string[indentation]); output.Append($"</{fieldName}>\n"); return(true); }
protected virtual Dictionary <string, XMLFieldHandler> IndexFields() { // Gather fields and create field handlers for them. PropertyInfo[] properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = Type.GetFields(BindingFlags.Public | BindingFlags.Instance); var fieldHandlers = new Dictionary <string, XMLFieldHandler>(properties.Length + fields.Length); for (var i = 0; i < properties.Length; i++) { PropertyInfo property = properties[i]; // Only serialize properties with get and set methods; MethodInfo readMethod = property.GetMethod; MethodInfo writeMethod = property.SetMethod; if (!property.CanRead || !property.CanWrite || readMethod == null || writeMethod == null) { continue; } bool nonPublicAllowed = property.GetCustomAttribute <SerializeNonPublicGetSetAttribute>() != null; bool valid = nonPublicAllowed || readMethod.IsPublic && writeMethod.IsPublic; if (!valid) { continue; } var excludeProp = property.GetCustomAttribute <DontSerializeMembersAttribute>(); // Mark members marked as "DontSerialize" or "DontSerializeMembers" as skip. bool skip = property.GetCustomAttribute <DontSerializeAttribute>() != null; string propertyName = property.Name; if (!skip && _excludedMembers != null && _excludedMembers.Contains(propertyName)) { skip = true; } var reflectionHandler = new ReflectedMemberHandler(property); XMLFieldHandler handler = skip ? new XMLSkippedMember(reflectionHandler) : XMLHelpers.ResolveFieldHandlerWithExclusions(property.PropertyType, reflectionHandler, excludeProp); if (handler == null) { continue; } fieldHandlers.TryAdd(propertyName, handler); } for (var i = 0; i < fields.Length; i++) { FieldInfo field = fields[i]; var excludeProp = field.GetCustomAttribute <DontSerializeMembersAttribute>(); bool skip = field.GetCustomAttribute <DontSerializeAttribute>() != null; string fieldName = field.Name; if (!skip && _excludedMembers != null && _excludedMembers.Contains(fieldName)) { skip = true; } var reflectionHandler = new ReflectedMemberHandler(field); XMLFieldHandler handler = skip ? new XMLSkippedMember(reflectionHandler) : XMLHelpers.ResolveFieldHandlerWithExclusions(field.FieldType, reflectionHandler, excludeProp); if (handler == null) { continue; } fieldHandlers.TryAdd(fieldName, handler); } return(fieldHandlers); }
public static bool ImGuiEditorForType <T>(T obj, XMLFieldHandler xmlHandler) { XMLTypeHandler?typeHandler = xmlHandler.TypeHandler; object value = xmlHandler.ReflectionInfo.GetValue(obj); switch (typeHandler) { case XMLStringTypeHandler: { var stringValue = (string)(value ?? ""); if (ImGui.InputText(xmlHandler.Name, ref stringValue, 1000)) { xmlHandler.ReflectionInfo.SetValue(obj, stringValue); return(true); } break; } case XMLEnumTypeHandler enumHandler: { string[] enumValueNames = Enum.GetNames(enumHandler.Type); int currentItem = enumValueNames.IndexOf(value.ToString()); if (ImGui.Combo(xmlHandler.Name, ref currentItem, enumValueNames, enumValueNames.Length)) { value = Enum.Parse(enumHandler.Type, enumValueNames[currentItem]); xmlHandler.ReflectionInfo.SetValue(obj, value); return(true); } break; } case XMLPrimitiveTypeHandler primitive: { if (primitive.Type == typeof(int)) { var intValue = (int)(value ?? 0); if (ImGui.InputInt(xmlHandler.Name, ref intValue)) { xmlHandler.ReflectionInfo.SetValue(obj, intValue); return(true); } break; } if (primitive.Type == typeof(bool)) { var boolValue = (bool)(value ?? false); if (ImGui.Checkbox(xmlHandler.Name, ref boolValue)) { xmlHandler.ReflectionInfo.SetValue(obj, boolValue); return(true); } break; } if (primitive.Type == typeof(float)) { var floatVal = (float)value; if (ImGui.InputFloat(xmlHandler.Name, ref floatVal)) { xmlHandler.ReflectionInfo.SetValue(obj, floatVal); return(true); } } break; } case XMLComplexValueTypeHandler valueType: { if (valueType.Type == typeof(Vector2)) { var vec2Value = (Vector2)(value ?? Vector2.Zero); if (ImGui.InputFloat2(xmlHandler.Name, ref vec2Value)) { xmlHandler.ReflectionInfo.SetValue(obj, vec2Value); return(true); } break; } if (valueType.Type == typeof(Vector3)) { var vec3Value = (Vector3)(value ?? Vector3.Zero); if (ImGui.InputFloat3(xmlHandler.Name, ref vec3Value)) { xmlHandler.ReflectionInfo.SetValue(obj, vec3Value); return(true); } break; } if (valueType.Type == typeof(Color)) { var colorValue = (Color)(value ?? Color.White); Vector4 colorAsVec4 = colorValue.ToVec4(); ImGui.Text(xmlHandler.Name); ImGui.SameLine(); ImGui.Text($"(RGBA) {colorValue}"); ImGui.SameLine(); if (ImGui.ColorButton(xmlHandler.Name, colorAsVec4)) { ImGui.OpenPopup(xmlHandler.Name); } if (ImGui.BeginPopup(xmlHandler.Name)) { if (ImGui.ColorPicker4($"Edit: {xmlHandler.Name}", ref colorAsVec4)) { colorValue = new Color(colorAsVec4); xmlHandler.ReflectionInfo.SetValue(obj, colorValue); return(true); } ImGui.EndPopup(); } break; } if (valueType.Type == typeof(Rectangle)) { var rectValue = (Rectangle)(value ?? Rectangle.Empty); var vec4Value = new Vector4(rectValue.X, rectValue.Y, rectValue.Width, rectValue.Height); if (ImGui.InputFloat4(xmlHandler.Name, ref vec4Value)) { var r = new Rectangle(vec4Value.X, vec4Value.Y, vec4Value.Z, vec4Value.W); xmlHandler.ReflectionInfo.SetValue(obj, r); return(true); } } break; } default: { ImGui.Text($"{xmlHandler.Name}: {value}"); break; } } object defaultVal = xmlHandler.DefaultValue; bool valueIsNotDefault = value != null && !value.Equals(defaultVal); bool defaultIsNotValue = defaultVal != null && !defaultVal.Equals(value); if (valueIsNotDefault || defaultIsNotValue) { ImGui.PushID(xmlHandler.Name); ImGui.SameLine(); if (ImGui.SmallButton("X")) { xmlHandler.ReflectionInfo.SetValue(obj, defaultVal); return(true); } ImGui.PopID(); } return(false); }