fix trait ordering, via ITraitPrerequisite<>. We'll need to do this for other traits, later (I've just fixed the crashbug)
This commit is contained in:
@@ -39,7 +39,7 @@ namespace OpenRa
|
||||
Info = Rules.Info[name.ToLowerInvariant()];
|
||||
Health = this.GetMaxHP();
|
||||
|
||||
foreach (var trait in Info.Traits.WithInterface<ITraitInfo>())
|
||||
foreach (var trait in Info.TraitsInConstructOrder())
|
||||
traits.Add(trait.Create(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,5 +79,39 @@ namespace OpenRa.GameRules
|
||||
|
||||
throw new InvalidOperationException("Cannot locate trait: {0}".F(traitName));
|
||||
}
|
||||
|
||||
public IEnumerable<ITraitInfo> TraitsInConstructOrder()
|
||||
{
|
||||
var ret = new List<ITraitInfo>();
|
||||
var t = Traits.WithInterface<ITraitInfo>().ToList();
|
||||
int index = 0;
|
||||
while( t.Count != 0 )
|
||||
{
|
||||
if( index >= t.Count )
|
||||
throw new InvalidOperationException( "Trait prerequisites not satisfied (or prerequisite loop)" );
|
||||
|
||||
var prereqs = PrerequisitesOf( t[ index ] );
|
||||
if( prereqs.Count == 0 || prereqs.All( n => ret.Any( x => x.GetType().IsSubclassOf( n ) ) ) )
|
||||
{
|
||||
ret.Add( t[ index ] );
|
||||
t.RemoveAt( index );
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
++index;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static List<Type> PrerequisitesOf( ITraitInfo info )
|
||||
{
|
||||
return info
|
||||
.GetType()
|
||||
.GetInterfaces()
|
||||
.Where( t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof( ITraitPrerequisite<> ) )
|
||||
.Select( t => t.GetGenericArguments()[ 0 ] )
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using OpenRa.Graphics;
|
||||
|
||||
namespace OpenRa.Traits
|
||||
{
|
||||
class RenderWarFactoryInfo : ITraitInfo
|
||||
class RenderWarFactoryInfo : ITraitInfo, ITraitPrerequisite<RenderSimpleInfo>
|
||||
{
|
||||
public object Create(Actor self) { return new RenderWarFactory(self); }
|
||||
}
|
||||
|
||||
@@ -94,4 +94,5 @@ namespace OpenRa.Traits
|
||||
public object Create(Actor self) { return Instance.Value; }
|
||||
}
|
||||
|
||||
interface ITraitPrerequisite<T> { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user