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:
Bob
2010-01-30 18:37:27 +13:00
parent 43a27bcfa0
commit c012cf3c7f
4 changed files with 37 additions and 2 deletions

View File

@@ -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));
}
}

View File

@@ -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();
}
}
}

View File

@@ -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); }
}

View File

@@ -94,4 +94,5 @@ namespace OpenRa.Traits
public object Create(Actor self) { return Instance.Value; }
}
interface ITraitPrerequisite<T> { }
}