Avoid LINQ in some Tick methods.

As Tick is called often, avoiding allocation overhead in these methods is useful.
This commit is contained in:
RoosterDragon
2017-12-15 19:26:09 +00:00
committed by reaperrr
parent 86f9b8807e
commit dd2ae9fe5e
3 changed files with 36 additions and 11 deletions

View File

@@ -172,9 +172,11 @@ namespace OpenRA.Traits
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
ResourceCapacity = self.World.ActorsWithTrait<IStoreResources>() // PERF: Avoid LINQ.
.Where(a => a.Actor.Owner == owner) ResourceCapacity = 0;
.Sum(a => a.Trait.Capacity); foreach (var tp in self.World.ActorsWithTrait<IStoreResources>())
if (tp.Actor.Owner == owner)
ResourceCapacity += tp.Trait.Capacity;
if (Resources > ResourceCapacity) if (Resources > ResourceCapacity)
Resources = ResourceCapacity; Resources = ResourceCapacity;

View File

@@ -33,6 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly ConquestVictoryConditionsInfo info; readonly ConquestVictoryConditionsInfo info;
readonly MissionObjectives mo; readonly MissionObjectives mo;
Player[] otherPlayers;
int objectiveID = -1; int objectiveID = -1;
public ConquestVictoryConditions(Actor self, ConquestVictoryConditionsInfo cvcInfo) public ConquestVictoryConditions(Actor self, ConquestVictoryConditionsInfo cvcInfo)
@@ -51,13 +52,18 @@ namespace OpenRA.Mods.Common.Traits
if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits()) if (!self.Owner.NonCombatant && self.Owner.HasNoRequiredUnits())
mo.MarkFailed(self.Owner, objectiveID); mo.MarkFailed(self.Owner, objectiveID);
var others = self.World.Players.Where(p => !p.NonCombatant // Players, NonCombatants, and IsAlliedWith are all fixed once the game starts, so we can cache the result.
&& !p.IsAlliedWith(self.Owner)); if (otherPlayers == null)
otherPlayers = self.World.Players.Where(p => !p.NonCombatant && !p.IsAlliedWith(self.Owner)).ToArray();
if (!others.Any()) return; if (otherPlayers.Length == 0) return;
if (others.All(p => p.WinState == WinState.Lost)) // PERF: Avoid LINQ.
mo.MarkCompleted(self.Owner, objectiveID); foreach (var otherPlayer in otherPlayers)
if (otherPlayer.WinState != WinState.Lost)
return;
mo.MarkCompleted(self.Owner, objectiveID);
} }
public void OnPlayerLost(Player player) public void OnPlayerLost(Player player)

View File

@@ -130,13 +130,30 @@ namespace OpenRA.Mods.Common.Traits
bool HasPrerequisites(Cache<string, List<Actor>> ownedPrerequisites) bool HasPrerequisites(Cache<string, List<Actor>> ownedPrerequisites)
{ {
return prerequisites.All(p => !(p.Replace("~", "").StartsWith("!") ^ !ownedPrerequisites.ContainsKey(p.Replace("!", "").Replace("~", "")))); // PERF: Avoid LINQ.
foreach (var prereq in prerequisites)
{
var withoutTilde = prereq.Replace("~", "");
if (withoutTilde.StartsWith("!") ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", "")))
return false;
}
return true;
} }
bool IsHidden(Cache<string, List<Actor>> ownedPrerequisites) bool IsHidden(Cache<string, List<Actor>> ownedPrerequisites)
{ {
return prerequisites.Any(prereq => prereq.StartsWith("~") && // PERF: Avoid LINQ.
(prereq.Replace("~", "").StartsWith("!") ^ !ownedPrerequisites.ContainsKey(prereq.Replace("~", "").Replace("!", "")))); foreach (var prereq in prerequisites)
{
if (!prereq.StartsWith("~"))
continue;
var withoutTilde = prereq.Replace("~", "");
if (withoutTilde.StartsWith("!") ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", "")))
return true;
}
return false;
} }
public void Update(Cache<string, List<Actor>> ownedPrerequisites) public void Update(Cache<string, List<Actor>> ownedPrerequisites)