Add FindType method to ObjectCreator
This commit is contained in:
@@ -19,13 +19,15 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class ObjectCreator
|
public class ObjectCreator
|
||||||
{
|
{
|
||||||
Pair<Assembly, string>[] modAssemblies;
|
Pair<Assembly, string>[] assemblies;
|
||||||
|
|
||||||
public ObjectCreator(Manifest manifest)
|
public ObjectCreator(Manifest manifest)
|
||||||
{
|
{
|
||||||
// All the core namespaces
|
// All the core namespaces
|
||||||
var asms = typeof(Game).Assembly.GetNamespaces()
|
var asms = typeof(Game).Assembly.GetNamespaces() // Game
|
||||||
.Select(c => Pair.New(typeof(Game).Assembly, c))
|
.Select(c => Pair.New(typeof(Game).Assembly, c))
|
||||||
|
.Concat(typeof(Mod).Assembly.GetNamespaces() // FileFormats
|
||||||
|
.Select(c => Pair.New(typeof(Mod).Assembly, c)))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Namespaces from each mod assembly
|
// Namespaces from each mod assembly
|
||||||
@@ -35,7 +37,7 @@ namespace OpenRA
|
|||||||
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
|
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
|
||||||
}
|
}
|
||||||
|
|
||||||
modAssemblies = asms.ToArray();
|
assemblies = asms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action<string> MissingTypeAction =
|
public static Action<string> MissingTypeAction =
|
||||||
@@ -48,24 +50,30 @@ namespace OpenRA
|
|||||||
|
|
||||||
public T CreateObject<T>(string className, Dictionary<string, object> args)
|
public T CreateObject<T>(string className, Dictionary<string, object> args)
|
||||||
{
|
{
|
||||||
foreach (var mod in modAssemblies)
|
var type = FindType(className);
|
||||||
|
if (type == null)
|
||||||
{
|
{
|
||||||
var type = mod.First.GetType(mod.Second + "." + className, false);
|
MissingTypeAction(className);
|
||||||
if (type == null) continue;
|
return default(T);
|
||||||
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
|
|
||||||
var ctors = type.GetConstructors(flags)
|
|
||||||
.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);
|
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
|
||||||
return default(T);
|
var ctors = type.GetConstructors(flags)
|
||||||
|
.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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type FindType(string className)
|
||||||
|
{
|
||||||
|
return assemblies
|
||||||
|
.Select(pair => pair.First.GetType(pair.Second + "." + className, false))
|
||||||
|
.FirstOrDefault(t => t != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object CreateBasic(Type type)
|
public object CreateBasic(Type type)
|
||||||
@@ -90,7 +98,7 @@ namespace OpenRA
|
|||||||
public IEnumerable<Type> GetTypesImplementing<T>()
|
public IEnumerable<Type> GetTypesImplementing<T>()
|
||||||
{
|
{
|
||||||
var it = typeof(T);
|
var it = typeof(T);
|
||||||
return modAssemblies.Select(ma => ma.First).Distinct()
|
return assemblies.Select(ma => ma.First).Distinct()
|
||||||
.SelectMany(ma => ma.GetTypes()
|
.SelectMany(ma => ma.GetTypes()
|
||||||
.Where(t => t != it && it.IsAssignableFrom(t)));
|
.Where(t => t != it && it.IsAssignableFrom(t)));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user