Merge pull request #9302 from RoosterDragon/alloc-tweaks

Reduce allocations for shroud checks and lost actors.
This commit is contained in:
atlimit8
2015-09-26 15:31:57 -05:00
6 changed files with 59 additions and 18 deletions

View File

@@ -182,6 +182,7 @@ namespace OpenRA.Mods.Common.AI
readonly IPathFinder pathfinder; readonly IPathFinder pathfinder;
readonly Func<Actor, bool> isEnemyUnit; readonly Func<Actor, bool> isEnemyUnit;
readonly Predicate<Actor> unitIsDeadOrHasNewOwner;
Dictionary<SupportPowerInstance, int> waitingPowers = new Dictionary<SupportPowerInstance, int>(); Dictionary<SupportPowerInstance, int> waitingPowers = new Dictionary<SupportPowerInstance, int>();
Dictionary<string, SupportPowerDecision> powerDecisions = new Dictionary<string, SupportPowerDecision>(); Dictionary<string, SupportPowerDecision> powerDecisions = new Dictionary<string, SupportPowerDecision>();
@@ -235,6 +236,7 @@ namespace OpenRA.Mods.Common.AI
Player.Stances[unit.Owner] == Stance.Enemy Player.Stances[unit.Owner] == Stance.Enemy
&& !unit.Info.HasTraitInfo<HuskInfo>() && !unit.Info.HasTraitInfo<HuskInfo>()
&& unit.Info.HasTraitInfo<ITargetableInfo>(); && unit.Info.HasTraitInfo<ITargetableInfo>();
unitIsDeadOrHasNewOwner = a => a.Owner != Player || a.IsDead;
foreach (var decision in info.PowerDecisions) foreach (var decision in info.PowerDecisions)
powerDecisions.Add(decision.OrderName, decision); powerDecisions.Add(decision.OrderName, decision);
@@ -604,7 +606,7 @@ namespace OpenRA.Mods.Common.AI
{ {
squads.RemoveAll(s => !s.IsValid); squads.RemoveAll(s => !s.IsValid);
foreach (var s in squads) foreach (var s in squads)
s.Units.RemoveAll(a => a.IsDead || a.Owner != Player); s.Units.RemoveAll(unitIsDeadOrHasNewOwner);
} }
// Use of this function requires that one squad of this type. Hence it is a piece of shit // Use of this function requires that one squad of this type. Hence it is a piece of shit
@@ -623,8 +625,8 @@ namespace OpenRA.Mods.Common.AI
void AssignRolesToIdleUnits(Actor self) void AssignRolesToIdleUnits(Actor self)
{ {
CleanSquads(); CleanSquads();
activeUnits.RemoveAll(a => a.IsDead || a.Owner != Player); activeUnits.RemoveAll(unitIsDeadOrHasNewOwner);
unitsHangingAroundTheBase.RemoveAll(a => a.IsDead || a.Owner != Player); unitsHangingAroundTheBase.RemoveAll(unitIsDeadOrHasNewOwner);
if (--rushTicks <= 0) if (--rushTicks <= 0)
{ {
@@ -805,12 +807,14 @@ namespace OpenRA.Mods.Common.AI
void SetRallyPointsForNewProductionBuildings(Actor self) void SetRallyPointsForNewProductionBuildings(Actor self)
{ {
var buildings = self.World.ActorsWithTrait<RallyPoint>() foreach (var rp in self.World.ActorsWithTrait<RallyPoint>())
.Where(rp => rp.Actor.Owner == Player && if (rp.Actor.Owner == Player &&
!IsRallyPointValid(rp.Trait.Location, rp.Actor.Info.TraitInfoOrDefault<BuildingInfo>())).ToArray(); !IsRallyPointValid(rp.Trait.Location, rp.Actor.Info.TraitInfoOrDefault<BuildingInfo>()))
QueueOrder(new Order("SetRallyPoint", rp.Actor, false)
foreach (var a in buildings) {
QueueOrder(new Order("SetRallyPoint", a.Actor, false) { TargetLocation = ChooseRallyLocationNear(a.Actor), SuppressVisualFeedback = true }); TargetLocation = ChooseRallyLocationNear(rp.Actor),
SuppressVisualFeedback = true
});
} }
// Won't work for shipyards... // Won't work for shipyards...
@@ -878,10 +882,10 @@ namespace OpenRA.Mods.Common.AI
if (supportPowerMngr == null) if (supportPowerMngr == null)
return; return;
var powers = supportPowerMngr.Powers.Where(p => !p.Value.Disabled); foreach (var sp in supportPowerMngr.Powers.Values)
foreach (var kv in powers)
{ {
var sp = kv.Value; if (sp.Disabled)
continue;
// Add power to dictionary if not in delay dictionary yet // Add power to dictionary if not in delay dictionary yet
if (!waitingPowers.ContainsKey(sp)) if (!waitingPowers.ContainsKey(sp))

View File

@@ -194,6 +194,7 @@
<Compile Include="Lint\LintBuildablePrerequisites.cs" /> <Compile Include="Lint\LintBuildablePrerequisites.cs" />
<Compile Include="Lint\LintExts.cs" /> <Compile Include="Lint\LintExts.cs" />
<Compile Include="LoadScreens\ModChooserLoadScreen.cs" /> <Compile Include="LoadScreens\ModChooserLoadScreen.cs" />
<Compile Include="ShroudExts.cs" />
<Compile Include="Orders\BeaconOrderGenerator.cs" /> <Compile Include="Orders\BeaconOrderGenerator.cs" />
<Compile Include="Orders\DeployOrderTargeter.cs" /> <Compile Include="Orders\DeployOrderTargeter.cs" />
<Compile Include="Orders\EnterAlliedActorTargeter.cs" /> <Compile Include="Orders\EnterAlliedActorTargeter.cs" />

View File

@@ -0,0 +1,39 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common
{
using OccupiedCells = IEnumerable<Pair<CPos, SubCell>>;
public static class ShroudExts
{
public static bool AnyExplored(this Shroud shroud, OccupiedCells cells)
{
foreach (var cell in cells)
if (shroud.IsExplored(cell.First))
return true;
return false;
}
public static bool AnyVisible(this Shroud shroud, OccupiedCells cells)
{
foreach (var cell in cells)
if (shroud.IsVisible(cell.First))
return true;
return false;
}
}
}

View File

@@ -70,8 +70,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
// If fog is disabled visibility is determined by shroud // If fog is disabled visibility is determined by shroud
if (!byPlayer.Shroud.FogEnabled) if (!byPlayer.Shroud.FogEnabled)
return self.OccupiesSpace.OccupiedCells() return byPlayer.Shroud.AnyExplored(self.OccupiesSpace.OccupiedCells());
.Any(o => byPlayer.Shroud.IsExplored(o.First));
return initialized && stateByPlayer[byPlayer].IsVisible; return initialized && stateByPlayer[byPlayer].IsVisible;
} }

View File

@@ -33,8 +33,7 @@ namespace OpenRA.Mods.Common.Traits
return base.IsVisibleInner(self, byPlayer); return base.IsVisibleInner(self, byPlayer);
if (Info.Type == VisibilityType.Footprint) if (Info.Type == VisibilityType.Footprint)
return self.OccupiesSpace.OccupiedCells() return byPlayer.Shroud.AnyVisible(self.OccupiesSpace.OccupiedCells());
.Any(o => byPlayer.Shroud.IsVisible(o.First));
return byPlayer.Shroud.IsVisible(self.CenterPosition); return byPlayer.Shroud.IsVisible(self.CenterPosition);
} }

View File

@@ -42,8 +42,7 @@ namespace OpenRA.Mods.Common.Traits
protected virtual bool IsVisibleInner(Actor self, Player byPlayer) protected virtual bool IsVisibleInner(Actor self, Player byPlayer)
{ {
if (Info.Type == VisibilityType.Footprint) if (Info.Type == VisibilityType.Footprint)
return self.OccupiesSpace.OccupiedCells() return byPlayer.Shroud.AnyExplored(self.OccupiesSpace.OccupiedCells());
.Any(o => byPlayer.Shroud.IsExplored(o.First));
return byPlayer.Shroud.IsExplored(self.CenterPosition); return byPlayer.Shroud.IsExplored(self.CenterPosition);
} }