* Unify the FieldLoader-related attributes (Ignore, LoadUsing,
FieldFromYamlKey) into a new 'Serialize' attribute. Keep the
previous attributes as shortcuts/aliases to the new attribute.
* Add 'YamlName' field to the new 'Serialize' attribute to allow
yaml names different from the field names. Example:
[Serialize(YamlName = "Width")]
private int widthExpression = "0";
* The FieldLoader will treat private fields like public now and
will try to load their values. The FieldSaver gets an optional
parameter specifying whether to save private fields by default.
The 'Serialize' attribute can be used to fine-tune individual
fields.
* Updated the traits documentation exporter to write the yaml
name if it has been overriden.
100 lines
2.7 KiB
C#
100 lines
2.7 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation. For more information,
|
|
* see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace OpenRA
|
|
{
|
|
public static class FieldSaver
|
|
{
|
|
public static MiniYaml Save(object o, bool includePrivateByDefault = false)
|
|
{
|
|
var nodes = new List<MiniYamlNode>();
|
|
string root = null;
|
|
|
|
foreach (var info in FieldLoader.GetTypeLoadInfo(o.GetType(), includePrivateByDefault))
|
|
{
|
|
if (info.Attribute.FromYamlKey)
|
|
root = FormatValue(o, info.Field);
|
|
else
|
|
nodes.Add(new MiniYamlNode(info.YamlName, FormatValue(o, info.Field)));
|
|
}
|
|
|
|
return new MiniYaml(root, nodes);
|
|
}
|
|
|
|
public static MiniYaml SaveDifferences(object o, object from, bool includePrivateByDefault = false)
|
|
{
|
|
if (o.GetType() != from.GetType())
|
|
throw new InvalidOperationException("FieldLoader: can't diff objects of different types");
|
|
|
|
var fields = FieldLoader.GetTypeLoadInfo(o.GetType(), includePrivateByDefault)
|
|
.Where(info => FormatValue(o, info.Field) != FormatValue(from, info.Field));
|
|
|
|
return new MiniYaml(
|
|
null,
|
|
fields.Select(info => new MiniYamlNode(info.YamlName, FormatValue(o, info.Field))).ToList()
|
|
);
|
|
}
|
|
|
|
public static MiniYamlNode SaveField(object o, string field)
|
|
{
|
|
return new MiniYamlNode(field, FormatValue(o, o.GetType().GetField(field)));
|
|
}
|
|
|
|
public static string FormatValue(object v, Type t)
|
|
{
|
|
if (v == null)
|
|
return "";
|
|
|
|
// Color.ToString() does the wrong thing; force it to format as an array
|
|
if (t == typeof(Color))
|
|
{
|
|
var c = (Color)v;
|
|
return "{0},{1},{2},{3}".F(((int)c.A).Clamp(0, 255),
|
|
((int)c.R).Clamp(0, 255),
|
|
((int)c.G).Clamp(0, 255),
|
|
((int)c.B).Clamp(0, 255));
|
|
}
|
|
|
|
// Don't save floats in settings.yaml using country-specific decimal separators which can be misunderstood as group seperators.
|
|
if (t == typeof(float))
|
|
return ((float)v).ToString(CultureInfo.InvariantCulture);
|
|
|
|
if (t == typeof(Rectangle))
|
|
{
|
|
var r = (Rectangle)v;
|
|
return "{0},{1},{2},{3}".F(r.X, r.Y, r.Width, r.Height);
|
|
}
|
|
|
|
if (t.IsArray)
|
|
{
|
|
var elems = ((Array)v).OfType<object>();
|
|
return elems.JoinWith(",");
|
|
}
|
|
|
|
if (t == typeof(DateTime))
|
|
return ((DateTime)v).ToString("yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture);
|
|
|
|
return v.ToString();
|
|
}
|
|
|
|
public static string FormatValue(object o, FieldInfo f)
|
|
{
|
|
return FormatValue(f.GetValue(o), f.FieldType);
|
|
}
|
|
}
|
|
}
|