Merge pull request #6710 from huwpascoe/depends
Fixes #3160 Fixes #3568 Fixes #4894 Closes #6701
This commit is contained in:
@@ -27,6 +27,7 @@ namespace OpenRA
|
|||||||
"You can remove inherited traits by adding a - infront of them as in -TraitName: to inherit everything, but this trait.")]
|
"You can remove inherited traits by adding a - infront of them as in -TraitName: to inherit everything, but this trait.")]
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
public readonly TypeDictionary Traits = new TypeDictionary();
|
public readonly TypeDictionary Traits = new TypeDictionary();
|
||||||
|
List<ITraitInfo> constructOrderCache = null;
|
||||||
|
|
||||||
public ActorInfo( string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits )
|
public ActorInfo( string name, MiniYaml node, Dictionary<string, MiniYaml> allUnits )
|
||||||
{
|
{
|
||||||
@@ -87,31 +88,46 @@ namespace OpenRA
|
|||||||
|
|
||||||
public IEnumerable<ITraitInfo> TraitsInConstructOrder()
|
public IEnumerable<ITraitInfo> TraitsInConstructOrder()
|
||||||
{
|
{
|
||||||
var ret = new List<ITraitInfo>();
|
if (constructOrderCache != null)
|
||||||
var t = Traits.WithInterface<ITraitInfo>().ToList();
|
return constructOrderCache;
|
||||||
var index = 0;
|
|
||||||
while (t.Count != 0)
|
var source = Traits.WithInterface<ITraitInfo>().Select(i => new {
|
||||||
|
Trait = i,
|
||||||
|
Type = i.GetType(),
|
||||||
|
Dependencies = PrerequisitesOf(i).ToList()
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var resolved = source.Where(s => !s.Dependencies.Any()).ToList();
|
||||||
|
var unresolved = source.Except(resolved);
|
||||||
|
|
||||||
|
var testResolve = new Func<Type, Type, bool>((a, b) => a == b || a.IsAssignableFrom(b));
|
||||||
|
var more = unresolved.Where(u => u.Dependencies.All( d => resolved.Exists(r => testResolve(d, r.Type)) ));
|
||||||
|
|
||||||
|
// Re-evaluate the vars above until sorted
|
||||||
|
while (more.Any())
|
||||||
|
resolved.AddRange(more);
|
||||||
|
|
||||||
|
if (unresolved.Any())
|
||||||
{
|
{
|
||||||
var prereqs = PrerequisitesOf(t[index]);
|
var exceptionString = "ActorInfo(\"" + Name + "\") failed to initialize because of the following:\r\n";
|
||||||
var unsatisfied = prereqs.Where(n => !ret.Any(x =>
|
var missing = unresolved.SelectMany(u => u.Dependencies.Where(d => !source.Any(s => testResolve(d, s.Type)))).Distinct();
|
||||||
|
|
||||||
|
exceptionString += "Missing:\r\n";
|
||||||
|
foreach (var m in missing)
|
||||||
|
exceptionString += m + " \r\n";
|
||||||
|
|
||||||
|
exceptionString += "Unresolved:\r\n";
|
||||||
|
foreach (var u in unresolved)
|
||||||
{
|
{
|
||||||
var type = x.GetType();
|
var deps = u.Dependencies.Where(d => !resolved.Exists(r => r.Type == d));
|
||||||
return type == n || n.IsAssignableFrom(type);
|
exceptionString += u.Type + ": { " + string.Join(", ", deps) + " }\r\n";
|
||||||
}));
|
|
||||||
if (!unsatisfied.Any())
|
|
||||||
{
|
|
||||||
ret.Add(t[index]);
|
|
||||||
t.RemoveAt(index);
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
else if (++index >= t.Count)
|
|
||||||
throw new InvalidOperationException("Trait prerequisites not satisfied (or prerequisite loop) Actor={0} Unresolved={1} Missing={2}".F(
|
|
||||||
Name,
|
|
||||||
t.Select(x => x.GetType().Name).JoinWith(","),
|
|
||||||
unsatisfied.Select(x => x.Name).JoinWith(",")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
throw new Exception(exceptionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructOrderCache = resolved.Select(r => r.Trait).ToList();
|
||||||
|
return constructOrderCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IEnumerable<Type> PrerequisitesOf(ITraitInfo info)
|
static IEnumerable<Type> PrerequisitesOf(ITraitInfo info)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.RA.Render
|
namespace OpenRA.Mods.RA.Render
|
||||||
{
|
{
|
||||||
public class RenderLandingCraftInfo : RenderUnitInfo, Requires<IMoveInfo>
|
public class RenderLandingCraftInfo : RenderUnitInfo, Requires<IMoveInfo>, Requires<CargoInfo>
|
||||||
{
|
{
|
||||||
public readonly string[] OpenTerrainTypes = { "Clear" };
|
public readonly string[] OpenTerrainTypes = { "Clear" };
|
||||||
public readonly string OpenAnim = "open";
|
public readonly string OpenAnim = "open";
|
||||||
|
|||||||
Reference in New Issue
Block a user