From 9fedeefdbc69bf95bbda1e2d8f81db83bced177d Mon Sep 17 00:00:00 2001 From: Bob Date: Fri, 27 Aug 2010 19:13:42 +1200 Subject: [PATCH] attribute individual fields, not the class --- OpenRA.FileFormats/FieldLoader.cs | 51 ++++++++++-------------------- OpenRA.FileFormats/Map/MapStub.cs | 17 +++++----- OpenRA.FileFormats/Map/TileSet.cs | 11 +++---- OpenRA.Game/GameRules/MusicInfo.cs | 7 ++-- OpenRA.Game/GameRules/VoiceInfo.cs | 16 ++++++---- OpenRA.Game/Map.cs | 21 ++++++------ 6 files changed, 52 insertions(+), 71 deletions(-) diff --git a/OpenRA.FileFormats/FieldLoader.cs b/OpenRA.FileFormats/FieldLoader.cs index be62449e18..bdc0e3ea20 100644 --- a/OpenRA.FileFormats/FieldLoader.cs +++ b/OpenRA.FileFormats/FieldLoader.cs @@ -165,49 +165,30 @@ namespace OpenRA.FileFormats { var ret = new Dictionary>(); - var fieldsToLoad = new List(); - 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() ) { - var use = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false ); - if( use.Length != 0 ) - ret[ field ] = ( _1, fieldType, yaml ) => use[ 0 ].LoaderFunc( field )( yaml ); - else - { - var attr2 = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false ); - if( attr2.Length != 0 ) - ret[ field ] = ( f, ft, yaml ) => GetValue( f, ft, yaml.Value ); - } + var load = (LoadAttribute[])field.GetCustomAttributes( typeof( LoadAttribute ), false ); + var loadUsing = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false ); + var fromYamlKey = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false ); + if( loadUsing.Length != 0 ) + ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml ); + else if( fromYamlKey.Length != 0 ) + 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; } - public class FooAttribute : Attribute - { - public string[] Fields; - - public FooAttribute( params string[] fields ) - { - Fields = fields; - } - } + [AttributeUsage( AttributeTargets.Field )] + public class LoadAttribute : Attribute { } + [AttributeUsage( AttributeTargets.Field )] public class LoadUsingAttribute : Attribute { Func loaderFuncCache; diff --git a/OpenRA.FileFormats/Map/MapStub.cs b/OpenRA.FileFormats/Map/MapStub.cs index fed9e488d4..bada08356d 100644 --- a/OpenRA.FileFormats/Map/MapStub.cs +++ b/OpenRA.FileFormats/Map/MapStub.cs @@ -15,27 +15,26 @@ using System.Linq; namespace OpenRA.FileFormats { - [FieldLoader.Foo( "Selectable", "Title", "Description", "Author", "PlayerCount", "Tileset", "TopLeft", "BottomRight" )] public class MapStub { public readonly IFolder Package; // Yaml map data public readonly string Uid; - public bool Selectable; + [FieldLoader.Load] public bool Selectable; - public string Title; - public string Description; - public string Author; - public int PlayerCount; - public string Tileset; + [FieldLoader.Load] public string Title; + [FieldLoader.Load] public string Description; + [FieldLoader.Load] public string Author; + [FieldLoader.Load] public int PlayerCount; + [FieldLoader.Load] public string Tileset; [FieldLoader.LoadUsing( "LoadWaypoints" )] public Dictionary Waypoints = new Dictionary(); public IEnumerable SpawnPoints { get { return Waypoints.Select(kv => kv.Value); } } - public int2 TopLeft; - public int2 BottomRight; + [FieldLoader.Load] public int2 TopLeft; + [FieldLoader.Load] public int2 BottomRight; public int Width { get { return BottomRight.X - TopLeft.X; } } public int Height { get { return BottomRight.Y - TopLeft.Y; } } diff --git a/OpenRA.FileFormats/Map/TileSet.cs b/OpenRA.FileFormats/Map/TileSet.cs index 0b55934dfe..cde06ea959 100644 --- a/OpenRA.FileFormats/Map/TileSet.cs +++ b/OpenRA.FileFormats/Map/TileSet.cs @@ -29,13 +29,12 @@ namespace OpenRA.FileFormats public MiniYaml Save() { return FieldSaver.Save(this); } } - [FieldLoader.Foo("Id", "Image", "Size", "PickAny")] public class TileTemplate { - public ushort Id; - public string Image; - public int2 Size; - public bool PickAny; + [FieldLoader.Load] public ushort Id; + [FieldLoader.Load] public string Image; + [FieldLoader.Load] public int2 Size; + [FieldLoader.Load] public bool PickAny; [FieldLoader.LoadUsing( "LoadTiles" )] public Dictionary Tiles = new Dictionary(); @@ -84,7 +83,7 @@ namespace OpenRA.FileFormats public TileSet() {} public TileSet( string filepath ) { - var yaml = MiniYaml.FromFile(filepath).ToDictionary( x => x.Key, x => x.Value ); + var yaml = MiniYaml.DictFromFile( filepath ); // General info FieldLoader.Load(this, yaml["General"]); diff --git a/OpenRA.Game/GameRules/MusicInfo.cs b/OpenRA.Game/GameRules/MusicInfo.cs index 945efb600a..049bab7239 100644 --- a/OpenRA.Game/GameRules/MusicInfo.cs +++ b/OpenRA.Game/GameRules/MusicInfo.cs @@ -12,12 +12,11 @@ using OpenRA.FileFormats; namespace OpenRA.GameRules { - [FieldLoader.Foo()] public class MusicInfo { - public readonly string Filename = null; - public readonly string Title = null; - public readonly int Length = 0; // seconds + [FieldLoader.Load] public readonly string Filename = null; + [FieldLoader.Load] public readonly string Title = null; + [FieldLoader.Load] public readonly int Length = 0; // seconds public MusicInfo( string key, MiniYaml value ) { diff --git a/OpenRA.Game/GameRules/VoiceInfo.cs b/OpenRA.Game/GameRules/VoiceInfo.cs index 07bf8c3d76..6adad3d21a 100644 --- a/OpenRA.Game/GameRules/VoiceInfo.cs +++ b/OpenRA.Game/GameRules/VoiceInfo.cs @@ -15,17 +15,21 @@ using System; namespace OpenRA.GameRules { - [FieldLoader.Foo( "DisableVariants" )] public class VoiceInfo { public readonly Dictionary Variants; public readonly Dictionary Voices; public readonly string DefaultVariant = ".aud" ; - public readonly string[] DisableVariants = { }; - - Func> Load = (y,name) => (y.NodesDict.ContainsKey(name))? y.NodesDict[name].NodesDict.ToDictionary(a => a.Key, - a => (string[])FieldLoader.GetValue( "(value)", typeof(string[]), a.Value.Value )) - : new Dictionary(); + [FieldLoader.Load] public readonly string[] DisableVariants = { }; + + static Dictionary Load( MiniYaml y, string name ) + { + 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(); + } public readonly Lazy> Pools; diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index 76a52c664f..a108bee8c1 100755 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -19,20 +19,19 @@ using OpenRA.FileFormats; namespace OpenRA { - [FieldLoader.Foo( "Selectable", "MapFormat", "Title", "Description", "Author", "PlayerCount", "Tileset", "MapSize", "TopLeft", "BottomRight" )] public class Map { public IFolder Package; public string Uid; // Yaml map data - public bool Selectable = true; - public int MapFormat; - public string Title; - public string Description; - public string Author; - public int PlayerCount; - public string Tileset; + [FieldLoader.Load] public bool Selectable = true; + [FieldLoader.Load] public int MapFormat; + [FieldLoader.Load] public string Title; + [FieldLoader.Load] public string Description; + [FieldLoader.Load] public string Author; + [FieldLoader.Load] public int PlayerCount; + [FieldLoader.Load] public string Tileset; public Dictionary Players = new Dictionary(); public Dictionary Actors = new Dictionary(); @@ -44,10 +43,10 @@ namespace OpenRA // Binary map data public byte TileFormat = 1; - public int2 MapSize; + [FieldLoader.Load] public int2 MapSize; - public int2 TopLeft; - public int2 BottomRight; + [FieldLoader.Load] public int2 TopLeft; + [FieldLoader.Load] public int2 BottomRight; public TileReference[,] MapTiles; public TileReference[,] MapResources;