Add FirstEnabledTraitOrDefault helper method.
This avoids the allocations caused by LINQ when using traits.FirstOrDefault(Exts.IsTraitEnabled). This is important in FrozenActorLayer.RefreshState which is called very often. We apply the new helper method to all areas using the old pattern. An overload that takes an array allows arrays to be enumerated without causing allocations.
This commit is contained in:
committed by
Paul Chote
parent
cb670d83b3
commit
7a7eed4fb7
@@ -503,6 +503,26 @@ namespace OpenRA
|
||||
{
|
||||
return IsTraitEnabled(t as object);
|
||||
}
|
||||
|
||||
public static T FirstEnabledTraitOrDefault<T>(this IEnumerable<T> ts)
|
||||
{
|
||||
// PERF: Avoid LINQ.
|
||||
foreach (var t in ts)
|
||||
if (t.IsTraitEnabled())
|
||||
return t;
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public static T FirstEnabledTraitOrDefault<T>(this T[] ts)
|
||||
{
|
||||
// PERF: Avoid LINQ.
|
||||
foreach (var t in ts)
|
||||
if (t.IsTraitEnabled())
|
||||
return t;
|
||||
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Enum<T>
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace OpenRA.Traits
|
||||
DamageState = health.DamageState;
|
||||
}
|
||||
|
||||
var tooltip = tooltips.FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var tooltip = tooltips.FirstEnabledTraitOrDefault();
|
||||
if (tooltip != null)
|
||||
{
|
||||
TooltipInfo = tooltip.TooltipInfo;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (buildable == null)
|
||||
continue;
|
||||
|
||||
var tooltip = actorInfo.Value.TraitInfos<TooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var tooltip = actorInfo.Value.TraitInfos<TooltipInfo>().FirstEnabledTraitOrDefault();
|
||||
if (tooltip == null)
|
||||
emitError("The following buildable actor has no (enabled) Tooltip: " + actorInfo.Key);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken)
|
||||
token = conditionManager.GrantCondition(self, info.Condition);
|
||||
|
||||
var wsb = wsbs.FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var wsb = wsbs.FirstEnabledTraitOrDefault();
|
||||
|
||||
if (wsb == null)
|
||||
return;
|
||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
if (conditionManager != null && !string.IsNullOrEmpty(info.Condition) && token == ConditionManager.InvalidConditionToken)
|
||||
token = conditionManager.GrantCondition(self, info.Condition);
|
||||
|
||||
var wsb = wsbs.FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var wsb = wsbs.FirstEnabledTraitOrDefault();
|
||||
|
||||
if (wsb == null)
|
||||
return;
|
||||
@@ -99,7 +99,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
Reverse(self, () =>
|
||||
{
|
||||
var wsb = wsbs.FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var wsb = wsbs.FirstEnabledTraitOrDefault();
|
||||
|
||||
// HACK: The actor remains alive and active for one tick before the followup activity
|
||||
// (sell/transform/etc) runs. This causes visual glitches that we attempt to minimize
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
var haveNeighbour = false;
|
||||
foreach (var n in kv.Value)
|
||||
{
|
||||
var rb = init.World.Map.Rules.Actors[n].TraitInfos<IWallConnectorInfo>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var rb = init.World.Map.Rules.Actors[n].TraitInfos<IWallConnectorInfo>().FirstEnabledTraitOrDefault();
|
||||
if (rb != null && rb.GetWallConnectionType() == Type)
|
||||
{
|
||||
haveNeighbour = true;
|
||||
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
foreach (var a in adjacentActors)
|
||||
{
|
||||
CVec facing;
|
||||
var wc = a.TraitsImplementing<IWallConnector>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var wc = a.TraitsImplementing<IWallConnector>().FirstEnabledTraitOrDefault();
|
||||
if (wc == null || !wc.AdjacentWallCanConnect(a, self.Location, wallInfo.Type, out facing))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
Footprint = new ReadOnlyDictionary<CPos, SubCell>(footprint);
|
||||
}
|
||||
|
||||
var tooltip = Info.TraitInfos<EditorOnlyTooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled) as TooltipInfoBase
|
||||
?? Info.TraitInfos<TooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var tooltip = Info.TraitInfos<EditorOnlyTooltipInfo>().FirstEnabledTraitOrDefault() as TooltipInfoBase
|
||||
?? Info.TraitInfos<TooltipInfo>().FirstEnabledTraitOrDefault();
|
||||
|
||||
Tooltip = (tooltip == null ? " < " + Info.Name + " >" : tooltip.Name) + "\n" + owner.Name + " (" + owner.Faction + ")"
|
||||
+ "\nID: " + ID + "\nType: " + Info.Name;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (actor == lastActor && hotkey == lastHotkey && pm.PowerState == lastPowerState)
|
||||
return;
|
||||
|
||||
var tooltip = actor.TraitInfos<TooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var tooltip = actor.TraitInfos<TooltipInfo>().FirstEnabledTraitOrDefault();
|
||||
var name = tooltip != null ? tooltip.Name : actor.Name;
|
||||
var buildable = actor.TraitInfo<BuildableInfo>();
|
||||
var cost = actor.TraitInfo<ValuedInfo>().Cost;
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
ActorInfo ai;
|
||||
if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai))
|
||||
{
|
||||
var actorTooltip = ai.TraitInfos<TooltipInfo>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
var actorTooltip = ai.TraitInfos<TooltipInfo>().FirstEnabledTraitOrDefault();
|
||||
if (actorTooltip != null)
|
||||
return actorTooltip.Name;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
if (underCursor != null)
|
||||
{
|
||||
ActorTooltip = underCursor.TraitsImplementing<ITooltip>().FirstOrDefault(Exts.IsTraitEnabled);
|
||||
ActorTooltip = underCursor.TraitsImplementing<ITooltip>().FirstEnabledTraitOrDefault();
|
||||
if (ActorTooltip != null)
|
||||
{
|
||||
ActorTooltipExtra = underCursor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
|
||||
|
||||
Reference in New Issue
Block a user