attribute individual fields, not the class
This commit is contained in:
@@ -165,49 +165,30 @@ namespace OpenRA.FileFormats
|
|||||||
{
|
{
|
||||||
var ret = new Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>();
|
var ret = new Dictionary<FieldInfo, Func<string, Type, MiniYaml, object>>();
|
||||||
|
|
||||||
var fieldsToLoad = new List<FieldInfo>();
|
|
||||||
var attr = (FooAttribute[])type.GetCustomAttributes( typeof( FooAttribute ), false );
|
|
||||||
if( attr.Length == 0 )
|
|
||||||
{
|
|
||||||
var defCtor = type.GetConstructor( new Type[ 0 ] );
|
|
||||||
if( defCtor == null || ( defCtor.GetMethodImplementationFlags() | MethodImplAttributes.Runtime ) == 0 )
|
|
||||||
throw new InvalidOperationException( "FieldLoader: refusing to load type {0}; has non-default ctor".F( type ) );
|
|
||||||
fieldsToLoad.AddRange( type.GetFields() );
|
|
||||||
}
|
|
||||||
else if( attr[ 0 ].Fields != null )
|
|
||||||
fieldsToLoad.AddRange( attr[ 0 ].Fields.Select( x => type.GetField( x ) ) );
|
|
||||||
else
|
|
||||||
fieldsToLoad.AddRange( type.GetFields() );
|
|
||||||
|
|
||||||
foreach( var field in fieldsToLoad )
|
|
||||||
ret.Add( field, null );
|
|
||||||
|
|
||||||
foreach( var field in type.GetFields() )
|
foreach( var field in type.GetFields() )
|
||||||
{
|
{
|
||||||
var use = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false );
|
var load = (LoadAttribute[])field.GetCustomAttributes( typeof( LoadAttribute ), false );
|
||||||
if( use.Length != 0 )
|
var loadUsing = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false );
|
||||||
ret[ field ] = ( _1, fieldType, yaml ) => use[ 0 ].LoaderFunc( field )( yaml );
|
var fromYamlKey = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false );
|
||||||
else
|
if( loadUsing.Length != 0 )
|
||||||
{
|
ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml );
|
||||||
var attr2 = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false );
|
else if( fromYamlKey.Length != 0 )
|
||||||
if( attr2.Length != 0 )
|
ret[ field ] = ( f, ft, yaml ) => GetValue( f, ft, yaml.Value );
|
||||||
ret[ field ] = ( f, ft, yaml ) => GetValue( f, ft, yaml.Value );
|
else if( load.Length != 0 )
|
||||||
}
|
ret[ field ] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret.Count == 0 )
|
||||||
|
foreach( var f in type.GetFields() )
|
||||||
|
ret.Add( f, null );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FooAttribute : Attribute
|
[AttributeUsage( AttributeTargets.Field )]
|
||||||
{
|
public class LoadAttribute : Attribute { }
|
||||||
public string[] Fields;
|
|
||||||
|
|
||||||
public FooAttribute( params string[] fields )
|
|
||||||
{
|
|
||||||
Fields = fields;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[AttributeUsage( AttributeTargets.Field )]
|
||||||
public class LoadUsingAttribute : Attribute
|
public class LoadUsingAttribute : Attribute
|
||||||
{
|
{
|
||||||
Func<MiniYaml, object> loaderFuncCache;
|
Func<MiniYaml, object> loaderFuncCache;
|
||||||
|
|||||||
@@ -15,27 +15,26 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.FileFormats
|
||||||
{
|
{
|
||||||
[FieldLoader.Foo( "Selectable", "Title", "Description", "Author", "PlayerCount", "Tileset", "TopLeft", "BottomRight" )]
|
|
||||||
public class MapStub
|
public class MapStub
|
||||||
{
|
{
|
||||||
public readonly IFolder Package;
|
public readonly IFolder Package;
|
||||||
|
|
||||||
// Yaml map data
|
// Yaml map data
|
||||||
public readonly string Uid;
|
public readonly string Uid;
|
||||||
public bool Selectable;
|
[FieldLoader.Load] public bool Selectable;
|
||||||
|
|
||||||
public string Title;
|
[FieldLoader.Load] public string Title;
|
||||||
public string Description;
|
[FieldLoader.Load] public string Description;
|
||||||
public string Author;
|
[FieldLoader.Load] public string Author;
|
||||||
public int PlayerCount;
|
[FieldLoader.Load] public int PlayerCount;
|
||||||
public string Tileset;
|
[FieldLoader.Load] public string Tileset;
|
||||||
|
|
||||||
[FieldLoader.LoadUsing( "LoadWaypoints" )]
|
[FieldLoader.LoadUsing( "LoadWaypoints" )]
|
||||||
public Dictionary<string, int2> Waypoints = new Dictionary<string, int2>();
|
public Dictionary<string, int2> Waypoints = new Dictionary<string, int2>();
|
||||||
public IEnumerable<int2> SpawnPoints { get { return Waypoints.Select(kv => kv.Value); } }
|
public IEnumerable<int2> SpawnPoints { get { return Waypoints.Select(kv => kv.Value); } }
|
||||||
|
|
||||||
public int2 TopLeft;
|
[FieldLoader.Load] public int2 TopLeft;
|
||||||
public int2 BottomRight;
|
[FieldLoader.Load] public int2 BottomRight;
|
||||||
public int Width { get { return BottomRight.X - TopLeft.X; } }
|
public int Width { get { return BottomRight.X - TopLeft.X; } }
|
||||||
public int Height { get { return BottomRight.Y - TopLeft.Y; } }
|
public int Height { get { return BottomRight.Y - TopLeft.Y; } }
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,12 @@ namespace OpenRA.FileFormats
|
|||||||
public MiniYaml Save() { return FieldSaver.Save(this); }
|
public MiniYaml Save() { return FieldSaver.Save(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
[FieldLoader.Foo("Id", "Image", "Size", "PickAny")]
|
|
||||||
public class TileTemplate
|
public class TileTemplate
|
||||||
{
|
{
|
||||||
public ushort Id;
|
[FieldLoader.Load] public ushort Id;
|
||||||
public string Image;
|
[FieldLoader.Load] public string Image;
|
||||||
public int2 Size;
|
[FieldLoader.Load] public int2 Size;
|
||||||
public bool PickAny;
|
[FieldLoader.Load] public bool PickAny;
|
||||||
|
|
||||||
[FieldLoader.LoadUsing( "LoadTiles" )]
|
[FieldLoader.LoadUsing( "LoadTiles" )]
|
||||||
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
||||||
@@ -84,7 +83,7 @@ namespace OpenRA.FileFormats
|
|||||||
public TileSet() {}
|
public TileSet() {}
|
||||||
public TileSet( string filepath )
|
public TileSet( string filepath )
|
||||||
{
|
{
|
||||||
var yaml = MiniYaml.FromFile(filepath).ToDictionary( x => x.Key, x => x.Value );
|
var yaml = MiniYaml.DictFromFile( filepath );
|
||||||
|
|
||||||
// General info
|
// General info
|
||||||
FieldLoader.Load(this, yaml["General"]);
|
FieldLoader.Load(this, yaml["General"]);
|
||||||
|
|||||||
@@ -12,12 +12,11 @@ using OpenRA.FileFormats;
|
|||||||
|
|
||||||
namespace OpenRA.GameRules
|
namespace OpenRA.GameRules
|
||||||
{
|
{
|
||||||
[FieldLoader.Foo()]
|
|
||||||
public class MusicInfo
|
public class MusicInfo
|
||||||
{
|
{
|
||||||
public readonly string Filename = null;
|
[FieldLoader.Load] public readonly string Filename = null;
|
||||||
public readonly string Title = null;
|
[FieldLoader.Load] public readonly string Title = null;
|
||||||
public readonly int Length = 0; // seconds
|
[FieldLoader.Load] public readonly int Length = 0; // seconds
|
||||||
|
|
||||||
public MusicInfo( string key, MiniYaml value )
|
public MusicInfo( string key, MiniYaml value )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,17 +15,21 @@ using System;
|
|||||||
|
|
||||||
namespace OpenRA.GameRules
|
namespace OpenRA.GameRules
|
||||||
{
|
{
|
||||||
[FieldLoader.Foo( "DisableVariants" )]
|
|
||||||
public class VoiceInfo
|
public class VoiceInfo
|
||||||
{
|
{
|
||||||
public readonly Dictionary<string,string[]> Variants;
|
public readonly Dictionary<string,string[]> Variants;
|
||||||
public readonly Dictionary<string,string[]> Voices;
|
public readonly Dictionary<string,string[]> Voices;
|
||||||
public readonly string DefaultVariant = ".aud" ;
|
public readonly string DefaultVariant = ".aud" ;
|
||||||
public readonly string[] DisableVariants = { };
|
[FieldLoader.Load] public readonly string[] DisableVariants = { };
|
||||||
|
|
||||||
Func<MiniYaml, string, Dictionary<string, string[]>> Load = (y,name) => (y.NodesDict.ContainsKey(name))? y.NodesDict[name].NodesDict.ToDictionary(a => a.Key,
|
static Dictionary<string, string[]> Load( MiniYaml y, string name )
|
||||||
a => (string[])FieldLoader.GetValue( "(value)", typeof(string[]), a.Value.Value ))
|
{
|
||||||
: new Dictionary<string, string[]>();
|
return y.NodesDict.ContainsKey( name )
|
||||||
|
? y.NodesDict[ name ].NodesDict.ToDictionary(
|
||||||
|
a => a.Key,
|
||||||
|
a => (string[])FieldLoader.GetValue( "(value)", typeof( string[] ), a.Value.Value ) )
|
||||||
|
: new Dictionary<string, string[]>();
|
||||||
|
}
|
||||||
|
|
||||||
public readonly Lazy<Dictionary<string, VoicePool>> Pools;
|
public readonly Lazy<Dictionary<string, VoicePool>> Pools;
|
||||||
|
|
||||||
|
|||||||
@@ -19,20 +19,19 @@ using OpenRA.FileFormats;
|
|||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
[FieldLoader.Foo( "Selectable", "MapFormat", "Title", "Description", "Author", "PlayerCount", "Tileset", "MapSize", "TopLeft", "BottomRight" )]
|
|
||||||
public class Map
|
public class Map
|
||||||
{
|
{
|
||||||
public IFolder Package;
|
public IFolder Package;
|
||||||
public string Uid;
|
public string Uid;
|
||||||
|
|
||||||
// Yaml map data
|
// Yaml map data
|
||||||
public bool Selectable = true;
|
[FieldLoader.Load] public bool Selectable = true;
|
||||||
public int MapFormat;
|
[FieldLoader.Load] public int MapFormat;
|
||||||
public string Title;
|
[FieldLoader.Load] public string Title;
|
||||||
public string Description;
|
[FieldLoader.Load] public string Description;
|
||||||
public string Author;
|
[FieldLoader.Load] public string Author;
|
||||||
public int PlayerCount;
|
[FieldLoader.Load] public int PlayerCount;
|
||||||
public string Tileset;
|
[FieldLoader.Load] public string Tileset;
|
||||||
|
|
||||||
public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
|
public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
|
||||||
public Dictionary<string, ActorReference> Actors = new Dictionary<string, ActorReference>();
|
public Dictionary<string, ActorReference> Actors = new Dictionary<string, ActorReference>();
|
||||||
@@ -44,10 +43,10 @@ namespace OpenRA
|
|||||||
|
|
||||||
// Binary map data
|
// Binary map data
|
||||||
public byte TileFormat = 1;
|
public byte TileFormat = 1;
|
||||||
public int2 MapSize;
|
[FieldLoader.Load] public int2 MapSize;
|
||||||
|
|
||||||
public int2 TopLeft;
|
[FieldLoader.Load] public int2 TopLeft;
|
||||||
public int2 BottomRight;
|
[FieldLoader.Load] public int2 BottomRight;
|
||||||
|
|
||||||
public TileReference<ushort, byte>[,] MapTiles;
|
public TileReference<ushort, byte>[,] MapTiles;
|
||||||
public TileReference<byte, byte>[,] MapResources;
|
public TileReference<byte, byte>[,] MapResources;
|
||||||
|
|||||||
Reference in New Issue
Block a user