make yaml into a list, rather than a dict

This commit is contained in:
Bob
2010-08-26 21:59:43 +12:00
committed by Chris Forbes
parent bce52e989f
commit 2f92b873e8
15 changed files with 176 additions and 141 deletions

View File

@@ -30,7 +30,7 @@ namespace OpenRA.FileFormats
public static void Load( object self, MiniYaml my )
{
foreach( var x in my.Nodes )
foreach( var x in my.NodesDict )
if (!x.Key.StartsWith("-"))
LoadField(self, x.Key, x.Value.Value);
@@ -154,7 +154,7 @@ namespace OpenRA.FileFormats
{
public static MiniYaml Save(object o)
{
var dict = new Dictionary<string, MiniYaml>();
var nodes = new List<MiniYamlNode>();
string root = null;
foreach( var f in o.GetType().GetFields( BindingFlags.Public | BindingFlags.Instance ) )
@@ -162,10 +162,10 @@ namespace OpenRA.FileFormats
if( f.HasAttribute<FieldFromYamlKeyAttribute>() )
root = FormatValue( o, f );
else
dict.Add( f.Name, new MiniYaml( FormatValue( o, f ) ) );
nodes.Add( new MiniYamlNode( f.Name, FormatValue( o, f ) ) );
}
return new MiniYaml( root, dict );
return new MiniYaml( root, nodes );
}
public static MiniYaml SaveDifferences(object o, object from)
@@ -175,10 +175,10 @@ namespace OpenRA.FileFormats
var fields = o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(f => FormatValue(o,f) != FormatValue(from,f));
return new MiniYaml(null, fields.ToDictionary(
f => f.Name,
f => new MiniYaml(FormatValue(o, f))));
return new MiniYaml( null, fields.Select( f => new MiniYamlNode(
f.Name,
FormatValue( o, f ) ) ).ToList() );
}
public static string FormatValue(object o, FieldInfo f)

View File

@@ -43,13 +43,17 @@ namespace OpenRA.FileFormats
Movies = YamlList(yaml, "Movies");
TileSets = YamlList(yaml, "TileSets");
ShellmapUid = yaml["ShellmapUid"].Value;
LoadScreen = yaml["LoadScreen"].Value;
ShellmapUid = yaml.First( x => x.Key == "ShellmapUid" ).Value.Value;
LoadScreen = yaml.First( x => x.Key == "LoadScreen" ).Value.Value;
}
static string[] YamlList(Dictionary<string, MiniYaml> ys, string key)
static string[] YamlList(List<MiniYamlNode> ys, string key)
{
return ys.ContainsKey(key) ? ys[key].Nodes.Keys.ToArray() : new string[] { };
var y = ys.FirstOrDefault( x => x.Key == key );
if( y == null )
return new string[ 0 ];
return y.Value.NodesDict.Keys.ToArray();
}
}
}

View File

@@ -43,11 +43,11 @@ namespace OpenRA.FileFormats
public MapStub(IFolder package)
{
Package = package;
var yaml = MiniYaml.FromStream(Package.GetContent("map.yaml"));
var yaml = MiniYaml.DictFromStream(Package.GetContent("map.yaml"));
FieldLoader.LoadFields(this, yaml, Fields);
// Waypoints
foreach (var wp in yaml["Waypoints"].Nodes)
foreach (var wp in yaml["Waypoints"].NodesDict)
{
string[] loc = wp.Value.Value.Split(',');
Waypoints.Add(wp.Key, new int2(int.Parse(loc[0]), int.Parse(loc[1])));

View File

@@ -42,27 +42,25 @@ namespace OpenRA.FileFormats
public TileTemplate() {}
public TileTemplate(MiniYaml my)
{
FieldLoader.LoadFields(this, my.Nodes, fields);
FieldLoader.LoadFields(this, my.NodesDict, fields);
Tiles = my.Nodes["Tiles"].Nodes.ToDictionary(
Tiles = my.NodesDict["Tiles"].NodesDict.ToDictionary(
t => byte.Parse(t.Key),
t => t.Value.Value);
}
public MiniYaml Save()
{
var root = new Dictionary<string, MiniYaml>();
var root = new List<MiniYamlNode>();
foreach (var field in fields)
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
root.Add(field, new MiniYaml(FieldSaver.FormatValue(this, f), null));
root.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
root.Add("Tiles",
new MiniYaml(null, Tiles.ToDictionary(
p => p.Key.ToString(),
p => new MiniYaml(p.Value))));
root.Add( new MiniYamlNode( "Tiles", null,
Tiles.Select( x => new MiniYamlNode( x.Key.ToString(), x.Value ) ).ToList() ) );
return new MiniYaml(null, root);
}
@@ -82,17 +80,17 @@ namespace OpenRA.FileFormats
public TileSet() {}
public TileSet( string filepath )
{
var yaml = MiniYaml.FromFile(filepath);
var yaml = MiniYaml.FromFile(filepath).ToDictionary( x => x.Key, x => x.Value );
// General info
FieldLoader.Load(this, yaml["General"]);
// TerrainTypes
Terrain = yaml["Terrain"].Nodes.Values
Terrain = yaml["Terrain"].NodesDict.Values
.Select(y => new TerrainTypeInfo(y)).ToDictionary(t => t.Type);
// Templates
Templates = yaml["Templates"].Nodes.Values
Templates = yaml["Templates"].NodesDict.Values
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
}
@@ -108,32 +106,32 @@ namespace OpenRA.FileFormats
public void Save(string filepath)
{
var root = new Dictionary<string, MiniYaml>();
var root = new List<MiniYamlNode>();
foreach (var field in fields)
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
root.Add(field, new MiniYaml(FieldSaver.FormatValue(this, f), null));
root.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
var gen = new Dictionary<string, MiniYaml>();
var gen = new List<MiniYamlNode>();
foreach (var field in fields)
{
FieldInfo f = this.GetType().GetField(field);
if (f.GetValue(this) == null) continue;
gen.Add(field, new MiniYaml(FieldSaver.FormatValue(this, f), null));
gen.Add( new MiniYamlNode( field, FieldSaver.FormatValue( this, f ) ) );
}
root.Add("General", new MiniYaml(null, gen));
root.Add("Terrain",
new MiniYaml(null, Terrain.ToDictionary(
t => "TerrainType@{0}".F(t.Value.Type),
t => t.Value.Save())));
root.Add("Templates",
new MiniYaml(null, Templates.ToDictionary(
t => "Template@{0}".F(t.Value.Id),
t => t.Value.Save())));
root.Add( new MiniYamlNode( "General", null, gen ) );
root.Add( new MiniYamlNode( "Terrain", null,
Terrain.Select( t => new MiniYamlNode(
"TerrainType@{0}".F( t.Value.Type ),
t.Value.Save() ) ).ToList() ) );
root.Add( new MiniYamlNode( "Templates", null,
Templates.Select( t => new MiniYamlNode(
"Template@{0}".F( t.Value.Id ),
t.Value.Save() ) ).ToList() ) );
root.WriteToFile(filepath);
}

View File

@@ -15,35 +15,58 @@ using System.Linq;
namespace OpenRA.FileFormats
{
using MiniYamlNodes = Dictionary<string, MiniYaml>;
using MiniYamlNodes = List<MiniYamlNode>;
public class MiniYamlNode
{
public string Key;
public MiniYaml Value;
public MiniYamlNode( string k, MiniYaml v )
{
Key = k;
Value = v;
}
public MiniYamlNode( string k, string v )
: this( k, new MiniYaml( v, null ) )
{
}
public MiniYamlNode( string k, string v, List<MiniYamlNode> n )
: this( k, new MiniYaml( v, n ) )
{
}
}
public class MiniYaml
{
public string Value;
public Dictionary<string, MiniYaml> Nodes = new Dictionary<string,MiniYaml>();
public List<MiniYamlNode> Nodes;
public MiniYaml( string value ) : this( value, new Dictionary<string, MiniYaml>() ) { }
public Dictionary<string, MiniYaml> NodesDict { get { return Nodes.ToDictionary( x => x.Key, x => x.Value ); } }
public MiniYaml( string value, Dictionary<string, MiniYaml> nodes )
public MiniYaml( string value ) : this( value, null ) { }
public MiniYaml( string value, List<MiniYamlNode> nodes )
{
Value = value;
Nodes = nodes;
Nodes = nodes ?? new List<MiniYamlNode>();
}
public static MiniYaml FromDictionary<K, V>( Dictionary<K, V> dict )
{
return new MiniYaml( null, dict.Select( x => new MiniYamlNode( x.Key.ToString(), new MiniYaml( x.Value.ToString() ) ) ).ToList() );
}
public static MiniYaml FromList<T>( List<T> list )
{
return new MiniYaml( null, list.Select( x => new MiniYamlNode( x.ToString(), new MiniYaml( null ) ) ).ToList() );
}
public static MiniYaml FromDictionary<K,V>(Dictionary<K,V>dict)
static List<MiniYamlNode> FromLines(string[] lines)
{
return new MiniYaml( null, dict.ToDictionary( x=>x.Key.ToString(), x=>new MiniYaml(x.Value.ToString())));
}
public static MiniYaml FromList<T>(List<T>list)
{
return new MiniYaml( null, list.ToDictionary( x=>x.ToString(), x=>new MiniYaml(null)));
}
static Dictionary<string, MiniYaml> FromLines(string[] lines)
{
var levels = new List<Dictionary<string, MiniYaml>>();
levels.Add(new Dictionary<string, MiniYaml>());
var levels = new List<List<MiniYamlNode>>();
levels.Add(new List<MiniYamlNode>());
foreach (var line in lines)
{
@@ -58,27 +81,27 @@ namespace OpenRA.FileFormats
levels.RemoveAt(levels.Count - 1);
var colon = t.IndexOf(':');
var d = new Dictionary<string, MiniYaml>();
var d = new List<MiniYamlNode>();
try
{
if (colon == -1)
levels[level].Add(t.Trim(), new MiniYaml(null, d));
if( colon == -1 )
levels[ level ].Add( new MiniYamlNode( t.Trim(), new MiniYaml( null, d ) ) );
else
{
var value = t.Substring(colon + 1).Trim();
if (value.Length == 0)
var value = t.Substring( colon + 1 ).Trim();
if( value.Length == 0 )
value = null;
levels[level].Add(t.Substring(0, colon).Trim(), new MiniYaml(value, d));
levels[ level ].Add( new MiniYamlNode( t.Substring( 0, colon ).Trim(), new MiniYaml( value, d ) ) );
}
}
catch (ArgumentException) { throw new InvalidDataException("Duplicate Identifier:`{0}`".F(t)); }
levels.Add(d);
}
return levels[0];
return levels[ 0 ];
}
public static Dictionary<string, MiniYaml> FromFileInPackage( string path )
public static List<MiniYamlNode> FromFileInPackage( string path )
{
StreamReader reader = new StreamReader( FileSystem.Open(path) );
List<string> lines = new List<string>();
@@ -89,52 +112,61 @@ namespace OpenRA.FileFormats
return FromLines(lines.ToArray());
}
public static Dictionary<string, MiniYaml> FromFile( string path )
public static Dictionary<string, MiniYaml> DictFromFile( string path )
{
return FromFile( path ).ToDictionary( x => x.Key, x => x.Value );
}
public static Dictionary<string, MiniYaml> DictFromStream( Stream stream )
{
return FromStream( stream ).ToDictionary( x => x.Key, x => x.Value );
}
public static List<MiniYamlNode> FromFile( string path )
{
return FromLines(File.ReadAllLines( path ));
}
public static Dictionary<string, MiniYaml> FromStream(Stream s)
public static List<MiniYamlNode> FromStream(Stream s)
{
using (var reader = new StreamReader(s))
return FromString(reader.ReadToEnd());
}
public static Dictionary<string, MiniYaml> FromString(string text)
public static List<MiniYamlNode> FromString(string text)
{
return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries));
}
public static Dictionary<string, MiniYaml> Merge( Dictionary<string, MiniYaml> a, Dictionary<string, MiniYaml> b )
public static List<MiniYamlNode> Merge( List<MiniYamlNode> a, List<MiniYamlNode> b )
{
if( a.Count == 0 )
return b;
if( b.Count == 0 )
return a;
var ret = new Dictionary<string, MiniYaml>();
var ret = new List<MiniYamlNode>();
var keys = a.Keys.Union( b.Keys ).ToList();
var aDict = a.ToDictionary( x => x.Key, x => x.Value );
var bDict = b.ToDictionary( x => x.Key, x => x.Value );
var keys = aDict.Keys.Union( bDict.Keys ).ToList();
var noInherit = keys.Where( x => x.Length > 0 && x[ 0 ] == '-' ).Select( x => x.Substring( 1 ) ).ToList();
foreach( var key in keys )
{
MiniYaml aa, bb;
a.TryGetValue( key, out aa );
b.TryGetValue( key, out bb );
aDict.TryGetValue( key, out aa );
bDict.TryGetValue( key, out bb );
// if( key.Length > 0 && key[ 0 ] == '-' )
// continue;
// else
if( noInherit.Contains( key ) )
{
if( aa != null )
ret.Add( key, aa );
ret.Add( new MiniYamlNode( key, aa ) );
}
else
ret.Add( key, Merge( aa, bb ) );
ret.Add( new MiniYamlNode( key, Merge( aa, bb ) ) );
}
return ret;