new object creation logic
This commit is contained in:
@@ -73,5 +73,17 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
return mi.GetCustomAttributes(typeof(T), true).Length != 0;
|
return mi.GetCustomAttributes(typeof(T), true).Length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T[] GetCustomAttributes<T>( this MemberInfo mi, bool inherit )
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
return (T[])mi.GetCustomAttributes( typeof( T ), inherit );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T[] GetCustomAttributes<T>( this ParameterInfo mi )
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
return (T[])mi.GetCustomAttributes( typeof( T ), true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
foreach( var field in type.GetFields() )
|
foreach( var field in type.GetFields() )
|
||||||
{
|
{
|
||||||
var load = (LoadAttribute[])field.GetCustomAttributes( typeof( LoadAttribute ), false );
|
var load = field.GetCustomAttributes<LoadAttribute>( false );
|
||||||
var loadUsing = (LoadUsingAttribute[])field.GetCustomAttributes( typeof( LoadUsingAttribute ), false );
|
var loadUsing = field.GetCustomAttributes<LoadUsingAttribute>( false );
|
||||||
var fromYamlKey = (FieldFromYamlKeyAttribute[])field.GetCustomAttributes( typeof( FieldFromYamlKeyAttribute ), false );
|
var fromYamlKey = field.GetCustomAttributes<FieldFromYamlKeyAttribute>( false );
|
||||||
if( loadUsing.Length != 0 )
|
if( loadUsing.Length != 0 )
|
||||||
ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml );
|
ret[ field ] = ( _1, fieldType, yaml ) => loadUsing[ 0 ].LoaderFunc( field )( yaml );
|
||||||
else if( fromYamlKey.Length != 0 )
|
else if( fromYamlKey.Length != 0 )
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
@@ -30,19 +31,61 @@ namespace OpenRA
|
|||||||
public static Action<string> MissingTypeAction =
|
public static Action<string> MissingTypeAction =
|
||||||
s => { throw new InvalidOperationException("Cannot locate type: {0}".F(s)); };
|
s => { throw new InvalidOperationException("Cannot locate type: {0}".F(s)); };
|
||||||
|
|
||||||
public T CreateObject<T>(string classname)
|
public T CreateObject<T>(string className)
|
||||||
{
|
{
|
||||||
foreach (var mod in ModAssemblies)
|
return CreateObject<T>( className, new Dictionary<string, object>() );
|
||||||
{
|
}
|
||||||
var fullTypeName = mod.Second + "." + classname;
|
|
||||||
var obj = mod.First.CreateInstance(fullTypeName);
|
|
||||||
if (obj != null)
|
|
||||||
return (T)obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
MissingTypeAction(classname);
|
public T CreateObject<T>( string className, Dictionary<string, object> args )
|
||||||
|
{
|
||||||
|
foreach( var mod in ModAssemblies )
|
||||||
|
{
|
||||||
|
var type = mod.First.GetType( mod.Second + "." + className, false );
|
||||||
|
if( type == null ) continue;
|
||||||
|
var ctors = type.GetConstructors().Where( x => x.HasAttribute<UseCtorAttribute>() ).ToList();
|
||||||
|
if( ctors.Count == 0 )
|
||||||
|
return (T)CreateBasic( type );
|
||||||
|
else if( ctors.Count == 1 )
|
||||||
|
return (T)CreateUsingArgs( ctors[ 0 ], args );
|
||||||
|
else
|
||||||
|
throw new InvalidOperationException( "ObjectCreator: UseCtor on multiple constructors; invalid." );
|
||||||
|
}
|
||||||
|
MissingTypeAction(className);
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object CreateBasic( Type type )
|
||||||
|
{
|
||||||
|
return type.GetConstructor( new Type[ 0 ] ).Invoke( new object[ 0 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public object CreateUsingArgs( ConstructorInfo ctor, Dictionary<string, object> args )
|
||||||
|
{
|
||||||
|
var p = ctor.GetParameters();
|
||||||
|
var a = new object[ p.Length ];
|
||||||
|
for( int i = 0 ; i < p.Length ; i++ )
|
||||||
|
{
|
||||||
|
var attrs = p[ i ].GetCustomAttributes<ParamAttribute>();
|
||||||
|
if( attrs.Length != 1 ) throw new InvalidOperationException( "ObjectCreator: argument in [UseCtor] doesn't have [Param]" );
|
||||||
|
a[ i ] = args[ attrs[ 0 ].ParamName ];
|
||||||
|
}
|
||||||
|
return ctor.Invoke( a );
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage( AttributeTargets.Parameter )]
|
||||||
|
public class ParamAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string ParamName { get; private set; }
|
||||||
|
|
||||||
|
public ParamAttribute( string paramName )
|
||||||
|
{
|
||||||
|
ParamName = paramName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage( AttributeTargets.Constructor )]
|
||||||
|
public class UseCtorAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user