Refactoring and fixes for some special cases (mostly lists)
This commit is contained in:
1 parent
8dda647619
commit
ad3f01aded
3 files changed
+102
-66
No files matched your search
@@ -23,6 +23,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VocaluxeLib;
|
using VocaluxeLib;
|
||||||
using VocaluxeLib.Draw;
|
using VocaluxeLib.Draw;
|
||||||
|
using VocaluxeLib.Menu;
|
||||||
using VocaluxeLib.Songs;
|
using VocaluxeLib.Songs;
|
||||||
using VocaluxeLib.Xml;
|
using VocaluxeLib.Xml;
|
||||||
|
|
||||||
@@ -168,10 +169,14 @@ namespace Vocaluxe.Base
|
|||||||
|
|
||||||
private static void _TestNewLoad(string path)
|
private static void _TestNewLoad(string path)
|
||||||
{
|
{
|
||||||
SThemeCover theme;
|
/*SThemeCover theme;
|
||||||
using (var stream = new FileStream(path, FileMode.Open))
|
using (var stream = new FileStream(path, FileMode.Open))
|
||||||
theme = CMyXmlDeserializer.Deserialize<SThemeCover>(stream);
|
theme = CMyXmlDeserializer.Deserialize<SThemeCover>(stream);
|
||||||
string cover = theme.Info.Author;
|
string cover = theme.Info.Author;*/
|
||||||
|
STheme themescreen;
|
||||||
|
using (var stream = new FileStream(@"C:\Users\Alex\Documents\Vocaluxe\Output\Themes\Ambient\Screens\ScreenMain.xml", FileMode.Open))
|
||||||
|
themescreen = CMyXmlDeserializer.Deserialize<STheme>(stream);
|
||||||
|
string foo = themescreen.Informations.ScreenName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ namespace VocaluxeLib
|
|||||||
[XmlRoot("Color")]
|
[XmlRoot("Color")]
|
||||||
public struct SThemeColor
|
public struct SThemeColor
|
||||||
{
|
{
|
||||||
[DefaultValue(null), XmlAttribute] public string Name;
|
[DefaultValue(null), XmlAttribute] public string Name;
|
||||||
public float? R;
|
public float? R;
|
||||||
public float? G;
|
public float? G;
|
||||||
public float? B;
|
public float? B;
|
||||||
@@ -237,7 +237,7 @@ namespace VocaluxeLib
|
|||||||
[XmlRoot("Reflection")]
|
[XmlRoot("Reflection")]
|
||||||
public struct SReflection
|
public struct SReflection
|
||||||
{
|
{
|
||||||
[XmlAttribute(AttributeName = "Enabled")] public bool Enabled;
|
[XmlAttribute] public bool Enabled;
|
||||||
public float Height;
|
public float Height;
|
||||||
public float Space;
|
public float Space;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ namespace VocaluxeLib.Xml
|
|||||||
{
|
{
|
||||||
public string Name;
|
public string Name;
|
||||||
public FieldInfo Info;
|
public FieldInfo Info;
|
||||||
public bool IsList;
|
public bool IsList; //List with child elements (<List><El/><El/></List>)
|
||||||
|
public bool IsEmbeddedList; //List w/o child elements(<List/><List/>)
|
||||||
public bool IsNullable;
|
public bool IsNullable;
|
||||||
public Type SubType;
|
public Type SubType;
|
||||||
}
|
}
|
||||||
@@ -95,7 +96,13 @@ namespace VocaluxeLib.Xml
|
|||||||
if (field.FieldType.IsGenericType)
|
if (field.FieldType.IsGenericType)
|
||||||
{
|
{
|
||||||
if (field.FieldType.GetGenericTypeDefinition() == typeof(List<>))
|
if (field.FieldType.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
info.IsList = true;
|
{
|
||||||
|
attElement = field.GetCustomAttributes(typeof(XmlArrayAttribute), false);
|
||||||
|
if (attElement.Length > 0)
|
||||||
|
info.IsList = true;
|
||||||
|
else
|
||||||
|
info.IsEmbeddedList = true;
|
||||||
|
}
|
||||||
else if (field.FieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
else if (field.FieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||||
info.IsNullable = true;
|
info.IsNullable = true;
|
||||||
info.SubType = field.FieldType.GetGenericArguments()[0];
|
info.SubType = field.FieldType.GetGenericArguments()[0];
|
||||||
@@ -105,6 +112,18 @@ namespace VocaluxeLib.Xml
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string _GetTypeName(Type type)
|
||||||
|
{
|
||||||
|
object[] att = type.GetCustomAttributes(typeof(XmlTypeAttribute), false);
|
||||||
|
if (att.Length > 0)
|
||||||
|
{
|
||||||
|
string name = ((XmlTypeAttribute)att[0]).TypeName;
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return type.Name;
|
||||||
|
}
|
||||||
|
|
||||||
public static T Deserialize<T>(Stream stream) where T : new()
|
public static T Deserialize<T>(Stream stream) where T : new()
|
||||||
{
|
{
|
||||||
return Deserialize<T>(new XmlTextReader(stream)
|
return Deserialize<T>(new XmlTextReader(stream)
|
||||||
@@ -117,60 +136,61 @@ namespace VocaluxeLib.Xml
|
|||||||
|
|
||||||
private static object _GetValue(XmlNode node, Type type)
|
private static object _GetValue(XmlNode node, Type type)
|
||||||
{
|
{
|
||||||
object value;
|
|
||||||
if (type.IsEnum)
|
if (type.IsEnum)
|
||||||
{
|
{
|
||||||
string stringValue = node.InnerText;
|
string stringValue = node.InnerText;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
value = Enum.Parse(type, stringValue);
|
return Enum.Parse(type, stringValue);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw new XmlException("Invalid value in " + _FindXPath(node));
|
throw new XmlException("Invalid value in " + _FindXPath(node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
if (type == typeof(string))
|
||||||
|
return node.InnerText;
|
||||||
|
if (type.IsPrimitive)
|
||||||
|
return _GetPrimitiveValue(node, type);
|
||||||
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
{
|
{
|
||||||
Type subType = type.GetGenericArguments()[0];
|
Type subType = type.GetGenericArguments()[0];
|
||||||
value = Activator.CreateInstance(type);
|
String subName = _GetTypeName(subType);
|
||||||
MethodInfo addMethod = value.GetType().GetMethod("Add");
|
List<object> subValues = new List<object>();
|
||||||
List<object> subValues = new List<object>(node.ChildNodes.Count);
|
|
||||||
foreach (XmlNode subNode in node.ChildNodes)
|
foreach (XmlNode subNode in node.ChildNodes)
|
||||||
{
|
{
|
||||||
if (subNode is XmlComment)
|
if (subNode is XmlComment)
|
||||||
continue;
|
continue;
|
||||||
|
if (subName != subNode.Name)
|
||||||
|
throw new XmlException("Invalid list entry '" + subNode.Name + "' in " + _FindXPath(node) + "; Expected: " + subName);
|
||||||
object subValue = _GetValue(subNode, subType);
|
object subValue = _GetValue(subNode, subType);
|
||||||
_ProcessChildNodes(subNode, ref subValue, true);
|
_ProcessChildNodes(subNode, ref subValue, true);
|
||||||
subValues.Add(subValue);
|
subValues.Add(subValue);
|
||||||
}
|
}
|
||||||
addMethod.Invoke(value, subValues.ToArray());
|
return _CreateList(type, subValues);
|
||||||
}
|
}
|
||||||
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||||
{
|
{
|
||||||
Type subType = type.GetGenericArguments()[0];
|
Type subType = type.GetGenericArguments()[0];
|
||||||
string stringValue = node.InnerText;
|
return _GetPrimitiveValue(node, subType);
|
||||||
value = Convert.ChangeType(stringValue, subType);
|
|
||||||
}
|
}
|
||||||
else if (type == typeof(string))
|
|
||||||
value = node.InnerText;
|
object value = Activator.CreateInstance(type);
|
||||||
else if (!type.IsPrimitive)
|
_ProcessChildNodes(node, ref value, true);
|
||||||
|
_ProcessChildNodes(node, ref value, false);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object _GetPrimitiveValue(XmlNode node, Type type)
|
||||||
|
{
|
||||||
|
object value;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
value = Activator.CreateInstance(type);
|
value = Convert.ChangeType(node.InnerText, type, CultureInfo.InvariantCulture);
|
||||||
_ProcessChildNodes(node, ref value, true);
|
|
||||||
_ProcessChildNodes(node, ref value, false);
|
|
||||||
}
|
}
|
||||||
else
|
catch (FormatException)
|
||||||
{
|
{
|
||||||
string stringValue = node.InnerText;
|
throw new XmlException("Invalid format in " + _FindXPath(node) + ": '" + node.InnerText + "'");
|
||||||
try
|
|
||||||
{
|
|
||||||
value = Convert.ChangeType(stringValue, type, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
catch (FormatException)
|
|
||||||
{
|
|
||||||
throw new XmlException("Invalid format in " + _FindXPath(node));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -184,6 +204,23 @@ namespace VocaluxeLib.Xml
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static object _CreateList(Type type, List<object> values)
|
||||||
|
{
|
||||||
|
object list = Activator.CreateInstance(type, new object[] {values.Count});
|
||||||
|
if (values.Count > 0)
|
||||||
|
{
|
||||||
|
MethodInfo addMethod = type.GetMethod("Add");
|
||||||
|
foreach (object value in values)
|
||||||
|
addMethod.Invoke(list, new object[] {value});
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _AddList(object result, SFieldInfo listField, List<object> list)
|
||||||
|
{
|
||||||
|
listField.Info.SetValue(result, _CreateList(listField.Info.FieldType, list));
|
||||||
|
}
|
||||||
|
|
||||||
private static void _ProcessChildNodes(XmlNode parent, ref object result, bool attributes)
|
private static void _ProcessChildNodes(XmlNode parent, ref object result, bool attributes)
|
||||||
{
|
{
|
||||||
IEnumerable nodes;
|
IEnumerable nodes;
|
||||||
@@ -210,56 +247,50 @@ namespace VocaluxeLib.Xml
|
|||||||
if (node.Name != curListName)
|
if (node.Name != curListName)
|
||||||
{
|
{
|
||||||
// End an embedded List
|
// End an embedded List
|
||||||
object list = Activator.CreateInstance(curListField.Info.FieldType);
|
_AddList(result, curListField, subValues);
|
||||||
MethodInfo addMethod = curListField.Info.FieldType.GetMethod("Add");
|
|
||||||
addMethod.Invoke(list, subValues.ToArray());
|
|
||||||
curListField.Info.SetValue(result, list);
|
|
||||||
curField++;
|
curField++;
|
||||||
curListName = null;
|
curListName = null;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Continue an embedded List
|
||||||
|
object subValue = _GetValue(node, curListField.SubType);
|
||||||
|
subValues.Add(subValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SFieldInfo field = new SFieldInfo();
|
SFieldInfo field = new SFieldInfo();
|
||||||
if (curListName == null)
|
for (; curField < fields.Count; curField++)
|
||||||
{
|
{
|
||||||
for (; curField < fields.Count; curField++)
|
field = fields[curField];
|
||||||
{
|
if (field.Name == node.Name)
|
||||||
field = fields[curField];
|
break;
|
||||||
if (field.Name == node.Name)
|
if (!_CheckAndSetDefaultValue(ref result, field))
|
||||||
break;
|
throw new XmlException("Unexpected element: " + _FindXPath(node) + "; Expected: " + field.Name);
|
||||||
if (!_CheckAndSetDefaultValue(ref result, field))
|
|
||||||
throw new XmlException("Unexpected element: " + _FindXPath(node) + "; Expected: " + field.Name);
|
|
||||||
}
|
|
||||||
if (curField >= fields.Count)
|
|
||||||
throw new XmlException("Unexpected element: " + _FindXPath(node));
|
|
||||||
|
|
||||||
if (field.IsList)
|
|
||||||
{
|
|
||||||
// Start an embedded List
|
|
||||||
curListField = field;
|
|
||||||
curListName = field.Name;
|
|
||||||
subValues.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (curListName == null)
|
if (curField >= fields.Count)
|
||||||
|
throw new XmlException("Unexpected element: " + _FindXPath(node));
|
||||||
|
|
||||||
|
if (field.IsEmbeddedList)
|
||||||
|
{
|
||||||
|
// Start an embedded List
|
||||||
|
curListField = field;
|
||||||
|
curListName = field.Name;
|
||||||
|
subValues.Clear();
|
||||||
|
object subValue = _GetValue(node, curListField.SubType);
|
||||||
|
subValues.Add(subValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
object value = _GetValue(node, field.Info.FieldType);
|
object value = _GetValue(node, field.Info.FieldType);
|
||||||
field.Info.SetValue(result, value);
|
field.Info.SetValue(result, value);
|
||||||
curField++;
|
curField++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Continue an embedded List
|
|
||||||
object value = _GetValue(node, field.SubType);
|
|
||||||
subValues.Add(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (curListName != null)
|
if (curListName != null)
|
||||||
{
|
{
|
||||||
// End an embedded List
|
// End an embedded List
|
||||||
object list = Activator.CreateInstance(curListField.Info.FieldType);
|
_AddList(result, curListField, subValues);
|
||||||
MethodInfo addMethod = curListField.Info.FieldType.GetMethod("Add");
|
|
||||||
addMethod.Invoke(list, subValues.ToArray());
|
|
||||||
curListField.Info.SetValue(result, list);
|
|
||||||
curField++;
|
curField++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user