Added FieldLoader.SerializeAttribute.Required to require fields in MiniYaml
This commit is contained in:
@@ -24,6 +24,26 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public static class FieldLoader
|
public static class FieldLoader
|
||||||
{
|
{
|
||||||
|
public class MissingFieldsException : YamlException
|
||||||
|
{
|
||||||
|
public readonly string[] Missing;
|
||||||
|
public readonly string Header;
|
||||||
|
public override string Message
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (string.IsNullOrEmpty(Header) ? "" : Header + ": ") + Missing[0]
|
||||||
|
+ string.Concat(Missing.Skip(1).Select(m => ", " + m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MissingFieldsException(string[] missing, string header = null, string headerSingle = null) : base(null)
|
||||||
|
{
|
||||||
|
Header = missing.Length > 1 ? header : headerSingle ?? header;
|
||||||
|
Missing = missing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Func<string, Type, string, object> InvalidValueAction = (s, t, f) =>
|
public static Func<string, Type, string, object> InvalidValueAction = (s, t, f) =>
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s, f, t));
|
throw new InvalidOperationException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s, f, t));
|
||||||
@@ -45,6 +65,7 @@ namespace OpenRA
|
|||||||
public static void Load(object self, MiniYaml my)
|
public static void Load(object self, MiniYaml my)
|
||||||
{
|
{
|
||||||
var loadInfo = TypeLoadInfo[self.GetType()];
|
var loadInfo = TypeLoadInfo[self.GetType()];
|
||||||
|
var missing = new List<string>();
|
||||||
|
|
||||||
Dictionary<string, MiniYaml> md = null;
|
Dictionary<string, MiniYaml> md = null;
|
||||||
|
|
||||||
@@ -52,19 +73,33 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
object val;
|
object val;
|
||||||
|
|
||||||
|
if (md == null)
|
||||||
|
md = my.ToDictionary();
|
||||||
if (fli.Loader != null)
|
if (fli.Loader != null)
|
||||||
val = fli.Loader(my);
|
{
|
||||||
|
if (!fli.Attribute.Required || md.ContainsKey(fli.YamlName))
|
||||||
|
val = fli.Loader(my);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
missing.Add(fli.YamlName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (md == null)
|
|
||||||
md = my.ToDictionary();
|
|
||||||
|
|
||||||
if (!TryGetValueFromYaml(fli.YamlName, fli.Field, md, out val))
|
if (!TryGetValueFromYaml(fli.YamlName, fli.Field, md, out val))
|
||||||
|
{
|
||||||
|
if (fli.Attribute.Required)
|
||||||
|
missing.Add(fli.YamlName);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fli.Field.SetValue(self, val);
|
fli.Field.SetValue(self, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (missing.Any())
|
||||||
|
throw new MissingFieldsException(missing.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TryGetValueFromYaml(string yamlName, FieldInfo field, Dictionary<string, MiniYaml> md, out object ret)
|
static bool TryGetValueFromYaml(string yamlName, FieldInfo field, Dictionary<string, MiniYaml> md, out object ret)
|
||||||
@@ -557,12 +592,20 @@ namespace OpenRA
|
|||||||
: base(false) { }
|
: base(false) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
|
public sealed class RequireAttribute : SerializeAttribute
|
||||||
|
{
|
||||||
|
public RequireAttribute()
|
||||||
|
: base(true, true) { }
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Field)]
|
[AttributeUsage(AttributeTargets.Field)]
|
||||||
public sealed class LoadUsingAttribute : SerializeAttribute
|
public sealed class LoadUsingAttribute : SerializeAttribute
|
||||||
{
|
{
|
||||||
public LoadUsingAttribute(string loader)
|
public LoadUsingAttribute(string loader, bool required = false)
|
||||||
{
|
{
|
||||||
Loader = loader;
|
Loader = loader;
|
||||||
|
Required = required;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,10 +620,12 @@ namespace OpenRA
|
|||||||
public string YamlName;
|
public string YamlName;
|
||||||
public string Loader;
|
public string Loader;
|
||||||
public bool FromYamlKey;
|
public bool FromYamlKey;
|
||||||
|
public bool Required;
|
||||||
|
|
||||||
public SerializeAttribute(bool serialize = true)
|
public SerializeAttribute(bool serialize = true, bool required = false)
|
||||||
{
|
{
|
||||||
Serialize = serialize;
|
Serialize = serialize;
|
||||||
|
Required = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Func<MiniYaml, object> GetLoader(Type type)
|
internal Func<MiniYaml, object> GetLoader(Type type)
|
||||||
|
|||||||
@@ -94,7 +94,16 @@ namespace OpenRA
|
|||||||
throw new YamlException("Junk value `{0}` on trait node {1}"
|
throw new YamlException("Junk value `{0}` on trait node {1}"
|
||||||
.F(my.Value, traitName));
|
.F(my.Value, traitName));
|
||||||
var info = Game.CreateObject<ITraitInfo>(traitName + "Info");
|
var info = Game.CreateObject<ITraitInfo>(traitName + "Info");
|
||||||
FieldLoader.Load(info, my);
|
try
|
||||||
|
{
|
||||||
|
FieldLoader.Load(info, my);
|
||||||
|
}
|
||||||
|
catch (FieldLoader.MissingFieldsException e)
|
||||||
|
{
|
||||||
|
var header = "Trait name " + traitName + ": " + (e.Missing.Length > 1 ? "Required properties missing" : "Required property missing");
|
||||||
|
throw new FieldLoader.MissingFieldsException(e.Missing, header);
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[Desc("This actor's experience increases when it has killed a GivesExperience actor.")]
|
[Desc("This actor's experience increases when it has killed a GivesExperience actor.")]
|
||||||
public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo>, Requires<UpgradeManagerInfo>
|
public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo>, Requires<UpgradeManagerInfo>
|
||||||
{
|
{
|
||||||
[FieldLoader.LoadUsing("LoadUpgrades")]
|
[FieldLoader.LoadUsing("LoadUpgrades", true)]
|
||||||
[Desc("Upgrades to grant at each level. (Required property)",
|
[Desc("Upgrades to grant at each level.",
|
||||||
"Key is the XP requirements for each level as a percentage of our own value.",
|
"Key is the XP requirements for each level as a percentage of our own value.",
|
||||||
"Value is a list of the upgrade types to grant")]
|
"Value is a list of the upgrade types to grant")]
|
||||||
public readonly Dictionary<int, string[]> Upgrades = null;
|
public readonly Dictionary<int, string[]> Upgrades = null;
|
||||||
@@ -36,10 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
static object LoadUpgrades(MiniYaml y)
|
static object LoadUpgrades(MiniYaml y)
|
||||||
{
|
{
|
||||||
MiniYaml upgrades;
|
MiniYaml upgrades = y.ToDictionary()["Upgrades"];
|
||||||
|
|
||||||
if (!y.ToDictionary().TryGetValue("Upgrades", out upgrades))
|
|
||||||
throw new YamlException("GainsExperience is missing Upgrades.");
|
|
||||||
|
|
||||||
return upgrades.Nodes.ToDictionary(
|
return upgrades.Nodes.ToDictionary(
|
||||||
kv => FieldLoader.GetValue<int>("(key)", kv.Key),
|
kv => FieldLoader.GetValue<int>("(key)", kv.Key),
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
|||||||
{
|
{
|
||||||
var fieldDescLines = info.Field.GetCustomAttributes<DescAttribute>(true).SelectMany(d => d.Lines);
|
var fieldDescLines = info.Field.GetCustomAttributes<DescAttribute>(true).SelectMany(d => d.Lines);
|
||||||
var fieldType = FriendlyTypeName(info.Field.FieldType);
|
var fieldType = FriendlyTypeName(info.Field.FieldType);
|
||||||
var defaultValue = FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value;
|
var loadInfo = info.Field.GetCustomAttributes<FieldLoader.SerializeAttribute>(true).FirstOrDefault();
|
||||||
|
var defaultValue = loadInfo != null && loadInfo.Required ? "<em>(required)</em>" : FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value;
|
||||||
doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(info.YamlName, defaultValue, fieldType));
|
doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(info.YamlName, defaultValue, fieldType));
|
||||||
doc.Append("<td>");
|
doc.Append("<td>");
|
||||||
foreach (var line in fieldDescLines)
|
foreach (var line in fieldDescLines)
|
||||||
|
|||||||
Reference in New Issue
Block a user