Remove allocations when enumerating sync hashes on an actor.

Exposing Actor.SyncHashes as an array allows allocation free enumeration, we just need to adjust the SyncHash type to run the hash function.
This commit is contained in:
RoosterDragon
2017-11-17 21:37:16 +00:00
committed by Paul Chote
parent 5338784e45
commit 8ef8c60a1a
3 changed files with 17 additions and 11 deletions

View File

@@ -28,8 +28,9 @@ namespace OpenRA
internal struct SyncHash
{
public readonly ISync Trait;
public readonly int Hash;
public SyncHash(ISync trait, int hash) { Trait = trait; Hash = hash; }
readonly Func<object, int> hashFunction;
public SyncHash(ISync trait) { Trait = trait; hashFunction = Sync.GetHashFunction(trait); }
public int Hash() { return hashFunction(Trait); }
}
public readonly ActorInfo Info;
@@ -70,7 +71,7 @@ namespace OpenRA
}
}
internal IEnumerable<SyncHash> SyncHashes { get; private set; }
internal SyncHash[] SyncHashes { get; private set; }
readonly IFacing facing;
readonly IHealth health;
@@ -129,11 +130,7 @@ namespace OpenRA
defaultVisibility = Trait<IDefaultVisibility>();
Targetables = TraitsImplementing<ITargetable>().ToArray();
SyncHashes =
TraitsImplementing<ISync>()
.Select(sync => Pair.New(sync, Sync.GetHashFunction(sync)))
.ToArray()
.Select(pair => new SyncHash(pair.First, pair.Second(pair.First)));
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
}
Rectangle DetermineRenderBounds()

View File

@@ -68,28 +68,37 @@ namespace OpenRA.Network
report.Effects.Clear();
foreach (var actor in orderManager.World.ActorsHavingTrait<ISync>())
{
foreach (var syncHash in actor.SyncHashes)
if (syncHash.Hash != 0)
{
var hash = syncHash.Hash();
if (hash != 0)
{
report.Traits.Add(new TraitReport()
{
ActorID = actor.ActorID,
Type = actor.Info.Name,
Owner = (actor.Owner == null) ? "null" : actor.Owner.PlayerName,
Trait = syncHash.Trait.GetType().Name,
Hash = syncHash.Hash,
Hash = hash,
NamesValues = DumpSyncTrait(syncHash.Trait)
});
}
}
}
foreach (var sync in orderManager.World.SyncedEffects)
{
var hash = Sync.Hash(sync);
if (hash != 0)
{
report.Effects.Add(new EffectReport()
{
Name = sync.GetType().Name,
Hash = hash,
NamesValues = DumpSyncTrait(sync)
});
}
}
}

View File

@@ -404,7 +404,7 @@ namespace OpenRA
// Hash fields marked with the ISync interface.
foreach (var actor in ActorsHavingTrait<ISync>())
foreach (var syncHash in actor.SyncHashes)
ret += n++ * (int)(1 + actor.ActorID) * syncHash.Hash;
ret += n++ * (int)(1 + actor.ActorID) * syncHash.Hash();
// Hash game state relevant effects such as projectiles.
foreach (var sync in SyncedEffects)