Remove some global state dependence in ActorInfo.

Instead on relying on the global Game.ModData.ObjectCreator, this is passed in via a parameter.
This commit is contained in:
RoosterDragon
2015-11-20 21:21:12 +00:00
committed by Oliver Brakmann
parent c7249e6fa6
commit 0caffa8196
4 changed files with 14 additions and 21 deletions

View File

@@ -31,7 +31,7 @@ namespace OpenRA
readonly TypeDictionary traits = new TypeDictionary(); readonly TypeDictionary traits = new TypeDictionary();
List<ITraitInfo> constructOrderCache = null; List<ITraitInfo> constructOrderCache = null;
public ActorInfo(string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits) public ActorInfo(ObjectCreator creator, string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits)
{ {
try try
{ {
@@ -48,7 +48,7 @@ namespace OpenRA
if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@")) if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
try try
{ {
traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value)); traits.Add(LoadTraitInfo(creator, t.Key.Split('@')[0], t.Value));
} }
catch (FieldLoader.MissingFieldsException e) catch (FieldLoader.MissingFieldsException e)
{ {
@@ -99,12 +99,12 @@ namespace OpenRA
return node; return node;
} }
static ITraitInfo LoadTraitInfo(string traitName, MiniYaml my) static ITraitInfo LoadTraitInfo(ObjectCreator creator, string traitName, MiniYaml my)
{ {
if (!string.IsNullOrEmpty(my.Value)) if (!string.IsNullOrEmpty(my.Value))
throw new YamlException("Junk value `{0}` on trait node {1}" throw new YamlException("Junk value `{0}` on trait node {1}"
.F(my.Value, traitName)); .F(my.Value, traitName));
var info = Game.CreateObject<ITraitInfo>(traitName + "Info"); var info = creator.CreateObject<ITraitInfo>(traitName + "Info");
try try
{ {
FieldLoader.Load(info, my); FieldLoader.Load(info, my);

View File

@@ -61,7 +61,7 @@ namespace OpenRA
using (new PerfTimer("Actors")) using (new PerfTimer("Actors"))
actors = LoadYamlRules(actorCache, m.Rules, actors = LoadYamlRules(actorCache, m.Rules,
map != null ? map.RuleDefinitions : NoMapRules, map != null ? map.RuleDefinitions : NoMapRules,
(k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); (k, y) => new ActorInfo(Game.ModData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value, y));
using (new PerfTimer("Weapons")) using (new PerfTimer("Weapons"))
weapons = LoadYamlRules(weaponCache, m.Weapons, weapons = LoadYamlRules(weaponCache, m.Weapons,

View File

@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using OpenRA.FileSystem; using OpenRA.FileSystem;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Widgets; using OpenRA.Widgets;
@@ -38,7 +39,12 @@ namespace OpenRA
{ {
Languages = new string[0]; Languages = new string[0];
Manifest = new Manifest(mod); Manifest = new Manifest(mod);
ObjectCreator = new ObjectCreator(Manifest);
// Allow mods to load types from the core Game assembly, and any additional assemblies they specify.
var assemblies =
new[] { typeof(Game).Assembly }.Concat(
Manifest.Assemblies.Select(path => Assembly.LoadFrom(Platform.ResolvePath(path))));
ObjectCreator = new ObjectCreator(assemblies);
Manifest.LoadCustomData(ObjectCreator); Manifest.LoadCustomData(ObjectCreator);
if (useLoadScreen) if (useLoadScreen)

View File

@@ -22,24 +22,11 @@ namespace OpenRA
readonly Cache<Type, ConstructorInfo> ctorCache; readonly Cache<Type, ConstructorInfo> ctorCache;
readonly Pair<Assembly, string>[] assemblies; readonly Pair<Assembly, string>[] assemblies;
public ObjectCreator(Manifest manifest) public ObjectCreator(IEnumerable<Assembly> sourceAssemblies)
{ {
typeCache = new Cache<string, Type>(FindType); typeCache = new Cache<string, Type>(FindType);
ctorCache = new Cache<Type, ConstructorInfo>(GetCtor); ctorCache = new Cache<Type, ConstructorInfo>(GetCtor);
assemblies = sourceAssemblies.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray();
// All the core namespaces
var asms = typeof(Game).Assembly.GetNamespaces() // Game
.Select(c => Pair.New(typeof(Game).Assembly, c))
.ToList();
// Namespaces from each mod assembly
foreach (var a in manifest.Assemblies)
{
var asm = Assembly.LoadFile(Platform.ResolvePath(a));
asms.AddRange(asm.GetNamespaces().Select(ns => Pair.New(asm, ns)));
}
assemblies = asms.ToArray();
} }
public static Action<string> MissingTypeAction = public static Action<string> MissingTypeAction =