Replace arrays with sets.

In places where arrays were being treated as a set, just create a set directly. This reveals the intention of such collections better, and also improves performance by allowing set based methods to be used.
This commit is contained in:
RoosterDragon
2015-09-03 20:09:16 +01:00
parent 4f4bab2cdf
commit 901e604cf3
19 changed files with 43 additions and 38 deletions

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Traits
public readonly PPos[] Footprint; public readonly PPos[] Footprint;
public readonly WPos CenterPosition; public readonly WPos CenterPosition;
public readonly Rectangle Bounds; public readonly Rectangle Bounds;
public readonly string[] TargetTypes; public readonly HashSet<string> TargetTypes;
readonly IRemoveFrozenActor[] removeFrozenActors; readonly IRemoveFrozenActor[] removeFrozenActors;
readonly Actor actor; readonly Actor actor;
readonly Shroud shroud; readonly Shroud shroud;
@@ -57,7 +57,7 @@ namespace OpenRA.Traits
CenterPosition = self.CenterPosition; CenterPosition = self.CenterPosition;
Bounds = self.Bounds; Bounds = self.Bounds;
TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).Distinct().ToArray(); TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).ToHashSet();
UpdateVisibility(); UpdateVisibility();
} }

View File

@@ -310,13 +310,13 @@ namespace OpenRA.Traits
public interface ITargetableInfo public interface ITargetableInfo
{ {
string[] GetTargetTypes(); HashSet<string> GetTargetTypes();
} }
public interface ITargetable public interface ITargetable
{ {
// Check IsTraitEnabled or !IsTraitDisabled first // Check IsTraitEnabled or !IsTraitDisabled first
string[] TargetTypes { get; } HashSet<string> TargetTypes { get; }
bool TargetableBy(Actor self, Actor byActor); bool TargetableBy(Actor self, Actor byActor);
bool RequiresForceFire { get; } bool RequiresForceFire { get; }
} }

View File

@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.AI
public readonly Stance Against = Stance.Enemy; public readonly Stance Against = Stance.Enemy;
[Desc("What types should the desired targets of this power be?")] [Desc("What types should the desired targets of this power be?")]
public readonly string[] Types = { "Air", "Ground", "Water" }; public readonly HashSet<string> Types = new HashSet<string> { "Air", "Ground", "Water" };
[Desc("How attractive are these types of targets?")] [Desc("How attractive are these types of targets?")]
public readonly int Attractiveness = 100; public readonly int Attractiveness = 100;
@@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.AI
if (!targetable.Any(t => t.TargetableBy(a, firedBy.PlayerActor))) if (!targetable.Any(t => t.TargetableBy(a, firedBy.PlayerActor)))
return 0; return 0;
if (Types.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any()) if (Types.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
{ {
switch (TargetMetric) switch (TargetMetric)
{ {

View File

@@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.Lint
continue; continue;
// This warhead cannot affect this actor. // This warhead cannot affect this actor.
if (!warhead.ValidTargets.Intersect(targetable).Any()) if (!warhead.ValidTargets.Overlaps(targetable))
continue; continue;
if (!warhead.DamageTypes.Intersect(deathTypes).Any()) if (!warhead.DamageTypes.Overlaps(deathTypes))
emitError("Actor type `{0}` does not define a death animation for weapon `{1}`!" emitError("Actor type `{0}` does not define a death animation for weapon `{1}`!"
.F(actorInfo.Key, weaponInfo.Key)); .F(actorInfo.Key, weaponInfo.Key));
} }

View File

@@ -77,12 +77,12 @@ namespace OpenRA.Mods.Common.Orders
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{ {
return target.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetTypes.Intersect(targetTypes).Any()); return target.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetTypes.Overlaps(targetTypes));
} }
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
{ {
return target.TargetTypes.Intersect(targetTypes).Any(); return target.TargetTypes.Overlaps(targetTypes);
} }
} }
} }

View File

@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
if (world.ActorsWithTrait<LineBuildNode>().Any(a => if (world.ActorsWithTrait<LineBuildNode>().Any(a =>
(a.Actor.Location == cell && (a.Actor.Location == cell &&
a.Actor.Info.Traits.Get<LineBuildNodeInfo>() a.Actor.Info.Traits.Get<LineBuildNodeInfo>()
.Types.Intersect(lbi.NodeTypes).Any()))) .Types.Overlaps(lbi.NodeTypes))))
dirs[d] = i; // Cell contains actor of correct type dirs[d] = i; // Cell contains actor of correct type
else else
dirs[d] = -1; // Cell is blocked by another actor type dirs[d] = -1; // Cell is blocked by another actor type

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -16,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
public class LineBuildNodeInfo : TraitInfo<LineBuildNode> public class LineBuildNodeInfo : TraitInfo<LineBuildNode>
{ {
[Desc("This actor is of LineBuild 'NodeType'...")] [Desc("This actor is of LineBuild 'NodeType'...")]
public readonly string[] Types = { "wall" }; public readonly HashSet<string> Types = new HashSet<string> { "wall" };
} }
public class LineBuildNode { } public class LineBuildNode { }

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly string UncloakSound = null; public readonly string UncloakSound = null;
[PaletteReference] public readonly string Palette = "cloak"; [PaletteReference] public readonly string Palette = "cloak";
public readonly string[] CloakTypes = { "Cloak" }; public readonly HashSet<string> CloakTypes = new HashSet<string> { "Cloak" };
[UpgradeGrantedReference] [UpgradeGrantedReference]
[Desc("The upgrades to grant to self while cloaked.")] [Desc("The upgrades to grant to self while cloaked.")]
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.Common.Traits
return true; return true;
return self.World.ActorsWithTrait<DetectCloaked>().Any(a => !a.Trait.IsTraitDisabled && a.Actor.Owner.IsAlliedWith(viewer) return self.World.ActorsWithTrait<DetectCloaked>().Any(a => !a.Trait.IsTraitDisabled && a.Actor.Owner.IsAlliedWith(viewer)
&& Info.CloakTypes.Intersect(a.Trait.Info.CloakTypes).Any() && Info.CloakTypes.Overlaps(a.Trait.Info.CloakTypes)
&& (self.CenterPosition - a.Actor.CenterPosition).Length <= WDist.FromCells(a.Trait.Info.Range).Length); && (self.CenterPosition - a.Actor.CenterPosition).Length <= WDist.FromCells(a.Trait.Info.Range).Length);
} }

View File

@@ -9,6 +9,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Primitives; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
@@ -31,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int MaxRadius = 4; public readonly int MaxRadius = 4;
[Desc("The list of unit target types we are allowed to duplicate.")] [Desc("The list of unit target types we are allowed to duplicate.")]
public readonly string[] ValidTargets = { "Ground", "Water" }; public readonly HashSet<string> ValidTargets = new HashSet<string> { "Ground", "Water" };
[Desc("Which factions this crate action can occur for.")] [Desc("Which factions this crate action can occur for.")]
public readonly string[] ValidFactions = { }; public readonly string[] ValidFactions = { };
@@ -58,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits
return false; return false;
var targetable = collector.TraitsImplementing<ITargetable>(); var targetable = collector.TraitsImplementing<ITargetable>();
if (!info.ValidTargets.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any()) if (!info.ValidTargets.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
return false; return false;
var positionable = collector.TraitOrDefault<IPositionable>(); var positionable = collector.TraitOrDefault<IPositionable>();

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Traits; using OpenRA.Traits;
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Sound to play when being crushed.")] [Desc("Sound to play when being crushed.")]
public readonly string CrushSound = null; public readonly string CrushSound = null;
[Desc("Which crush classes does this actor belong to.")] [Desc("Which crush classes does this actor belong to.")]
public readonly string[] CrushClasses = { "infantry" }; public readonly HashSet<string> CrushClasses = new HashSet<string> { "infantry" };
[Desc("Probability of mobile actors noticing and evading a crush attempt.")] [Desc("Probability of mobile actors noticing and evading a crush attempt.")]
public readonly int WarnProbability = 75; public readonly int WarnProbability = 75;
[Desc("Will friendly units just crush me instead of pathing around.")] [Desc("Will friendly units just crush me instead of pathing around.")]
@@ -72,7 +73,7 @@ namespace OpenRA.Mods.Common.Traits
if (!info.CrushedByFriendlies && crushOwner.IsAlliedWith(self.Owner)) if (!info.CrushedByFriendlies && crushOwner.IsAlliedWith(self.Owner))
return false; return false;
return info.CrushClasses.Intersect(crushClasses).Any(); return info.CrushClasses.Overlaps(crushClasses);
} }
} }
} }

View File

@@ -8,7 +8,7 @@
*/ */
#endregion #endregion
using OpenRA.Traits; using System.Collections.Generic;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
public class DetectCloakedInfo : UpgradableTraitInfo public class DetectCloakedInfo : UpgradableTraitInfo
{ {
[Desc("Specific cloak classifications I can reveal.")] [Desc("Specific cloak classifications I can reveal.")]
public readonly string[] CloakTypes = { "Cloak" }; public readonly HashSet<string> CloakTypes = new HashSet<string> { "Cloak" };
[Desc("Measured in cells.")] [Desc("Measured in cells.")]
public readonly int Range = 5; public readonly int Range = 5;

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
return; return;
var warhead = e.Warhead as DamageWarhead; var warhead = e.Warhead as DamageWarhead;
if (info.DeathType != null && warhead != null && !info.DeathType.Intersect(warhead.DamageTypes).Any()) if (info.DeathType != null && warhead != null && !warhead.DamageTypes.Overlaps(info.DeathType))
return; return;
var weaponName = ChooseWeaponForExplosion(self); var weaponName = ChooseWeaponForExplosion(self);

View File

@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.UseDeathTypeSuffix) if (Info.UseDeathTypeSuffix)
{ {
var warhead = e.Warhead as DamageWarhead; var warhead = e.Warhead as DamageWarhead;
var damageType = warhead.DamageTypes.Intersect(Info.DeathTypes.Keys).FirstOrDefault(); var damageType = Info.DeathTypes.Keys.FirstOrDefault(warhead.DamageTypes.Contains);
if (damageType == null) if (damageType == null)
return; return;

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
if (warhead == null) if (warhead == null)
return; return;
if (info.DeathTypes.Intersect(warhead.DamageTypes).Any()) if (warhead.DamageTypes.Overlaps(info.DeathTypes))
self.PlayVoiceLocal(info.Voice, info.VolumeMultiplier); self.PlayVoiceLocal(info.Voice, info.VolumeMultiplier);
} }
} }

View File

@@ -17,8 +17,8 @@ namespace OpenRA.Mods.Common.Traits
public class TargetableInfo : UpgradableTraitInfo, ITargetableInfo public class TargetableInfo : UpgradableTraitInfo, ITargetableInfo
{ {
[Desc("Target type. Used for filtering (in)valid targets.")] [Desc("Target type. Used for filtering (in)valid targets.")]
public readonly string[] TargetTypes = { }; public readonly HashSet<string> TargetTypes = new HashSet<string>();
public string[] GetTargetTypes() { return TargetTypes; } public HashSet<string> GetTargetTypes() { return TargetTypes; }
public bool RequiresForceFire = false; public bool RequiresForceFire = false;
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits
return cloak.IsVisible(self, viewer.Owner); return cloak.IsVisible(self, viewer.Owner);
} }
public virtual string[] TargetTypes { get { return Info.TargetTypes; } } public virtual HashSet<string> TargetTypes { get { return Info.TargetTypes; } }
public bool RequiresForceFire { get { return Info.RequiresForceFire; } } public bool RequiresForceFire { get { return Info.RequiresForceFire; } }
} }

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Warheads
public readonly int Damage = 0; public readonly int Damage = 0;
[Desc("Types of damage that this warhead causes. Leave empty for no damage.")] [Desc("Types of damage that this warhead causes. Leave empty for no damage.")]
public readonly string[] DamageTypes = new string[0]; public readonly HashSet<string> DamageTypes = new HashSet<string>();
[FieldLoader.LoadUsing("LoadVersus")] [FieldLoader.LoadUsing("LoadVersus")]
[Desc("Damage percentage versus each armortype.")] [Desc("Damage percentage versus each armortype.")]

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Traits; using OpenRA.Traits;
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
{ {
[FieldLoader.Require] [FieldLoader.Require]
[Desc("Uses the \"Cloneable\" trait to determine whether or not we should clone a produced unit.")] [Desc("Uses the \"Cloneable\" trait to determine whether or not we should clone a produced unit.")]
public readonly string[] CloneableTypes = { }; public readonly HashSet<string> CloneableTypes = new HashSet<string>();
public object Create(ActorInitializer init) { return new ClonesProducedUnits(init, this); } public object Create(ActorInitializer init) { return new ClonesProducedUnits(init, this); }
} }
@@ -44,7 +45,7 @@ namespace OpenRA.Mods.RA.Traits
return; return;
var ci = produced.Info.Traits.GetOrDefault<CloneableInfo>(); var ci = produced.Info.Traits.GetOrDefault<CloneableInfo>();
if (ci == null || !info.CloneableTypes.Intersect(ci.Types).Any()) if (ci == null || !info.CloneableTypes.Overlaps(ci.Types))
return; return;
production.Produce(self, produced.Info, faction); production.Produce(self, produced.Info, faction);

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
{ {
class InfiltratesInfo : ITraitInfo class InfiltratesInfo : ITraitInfo
{ {
public readonly string[] Types = { }; public readonly HashSet<string> Types = new HashSet<string>();
[VoiceReference] public readonly string Voice = "Action"; [VoiceReference] public readonly string Voice = "Action";
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA.Traits
targetTypes = order.TargetActor.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled) targetTypes = order.TargetActor.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled)
.SelectMany(t => t.TargetTypes); .SelectMany(t => t.TargetTypes);
return targetTypes.Intersect(Info.Types).Any(); return Info.Types.Overlaps(targetTypes);
} }
public string VoicePhraseForOrder(Actor self, Order order) public string VoicePhraseForOrder(Actor self, Order order)
@@ -96,7 +96,7 @@ namespace OpenRA.Mods.RA.Traits
var target = self.ResolveFrozenActorOrder(order, Color.Red); var target = self.ResolveFrozenActorOrder(order, Color.Red);
if (target.Type != TargetType.Actor if (target.Type != TargetType.Actor
|| target.Actor.TraitsImplementing<ITargetable>().SelectMany(t => t.TargetTypes).Intersect(Info.Types).Any()) || Info.Types.Overlaps(target.Actor.TraitsImplementing<ITargetable>().SelectMany(t => t.TargetTypes)))
return; return;
if (!order.Queued) if (!order.Queued)
@@ -124,7 +124,7 @@ namespace OpenRA.Mods.RA.Traits
if (!info.ValidStances.HasStance(stance)) if (!info.ValidStances.HasStance(stance))
return false; return false;
return target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Intersect(info.Types).Any()); return target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Overlaps(info.Types));
} }
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
@@ -134,7 +134,7 @@ namespace OpenRA.Mods.RA.Traits
if (!info.ValidStances.HasStance(stance)) if (!info.ValidStances.HasStance(stance))
return false; return false;
return target.Info.Traits.WithInterface<ITargetableInfo>().Any(t => t.GetTargetTypes().Intersect(info.Types).Any()); return target.Info.Traits.WithInterface<ITargetableInfo>().Any(t => info.Types.Overlaps(t.GetTargetTypes()));
} }
} }
} }

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Traits; using OpenRA.Traits;
@@ -16,9 +17,9 @@ namespace OpenRA.Mods.RA.Traits
{ {
class MineInfo : ITraitInfo class MineInfo : ITraitInfo
{ {
public readonly string[] CrushClasses = { }; public readonly HashSet<string> CrushClasses = new HashSet<string>();
public readonly bool AvoidFriendly = true; public readonly bool AvoidFriendly = true;
public readonly string[] DetonateClasses = { }; public readonly HashSet<string> DetonateClasses = new HashSet<string>();
public object Create(ActorInitializer init) { return new Mine(init, this); } public object Create(ActorInitializer init) { return new Mine(init, this); }
} }
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.RA.Traits
return; return;
var mobile = crusher.TraitOrDefault<Mobile>(); var mobile = crusher.TraitOrDefault<Mobile>();
if (mobile != null && !info.DetonateClasses.Intersect(mobile.Info.Crushes).Any()) if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.Crushes))
return; return;
self.Kill(crusher); self.Kill(crusher);
@@ -50,7 +51,7 @@ namespace OpenRA.Mods.RA.Traits
public bool CrushableBy(string[] crushClasses, Player owner) public bool CrushableBy(string[] crushClasses, Player owner)
{ {
return info.CrushClasses.Intersect(crushClasses).Any(); return info.CrushClasses.Overlaps(crushClasses);
} }
} }