TechTree.GatherOwnedPrerequisites performance improvements.
- Consuming methods cared only about the count and not the actual actors, so only counts the actors rather that creating lists. - ProvidesPrerequisites implementations return cached objects rather then allocating new enumerables on each call.
This commit is contained in:
@@ -43,6 +43,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
public class GrantPrerequisiteChargeDrainPower : SupportPower, ITechTreePrerequisite, INotifyOwnerChanged
|
public class GrantPrerequisiteChargeDrainPower : SupportPower, ITechTreePrerequisite, INotifyOwnerChanged
|
||||||
{
|
{
|
||||||
readonly GrantPrerequisiteChargeDrainPowerInfo info;
|
readonly GrantPrerequisiteChargeDrainPowerInfo info;
|
||||||
|
readonly string[] prerequisites;
|
||||||
TechTree techTree;
|
TechTree techTree;
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
: base(self, info)
|
: base(self, info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
prerequisites = new[] { info.Prerequisite };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Created(Actor self)
|
protected override void Created(Actor self)
|
||||||
@@ -82,16 +84,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
techTree.ActorChanged(self);
|
techTree.ActorChanged(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<string> ITechTreePrerequisite.ProvidesPrerequisites
|
IEnumerable<string> ITechTreePrerequisite.ProvidesPrerequisites => active ? prerequisites : Enumerable.Empty<string>();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!active)
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
yield return info.Prerequisite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DischargeableSupportPowerInstance : SupportPowerInstance
|
public class DischargeableSupportPowerInstance : SupportPowerInstance
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
@@ -39,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public class ProvidesPrerequisite : ConditionalTrait<ProvidesPrerequisiteInfo>, ITechTreePrerequisite, INotifyOwnerChanged, INotifyCreated
|
public class ProvidesPrerequisite : ConditionalTrait<ProvidesPrerequisiteInfo>, ITechTreePrerequisite, INotifyOwnerChanged, INotifyCreated
|
||||||
{
|
{
|
||||||
readonly string prerequisite;
|
readonly string[] prerequisites;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
TechTree techTree;
|
TechTree techTree;
|
||||||
@@ -48,24 +49,15 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public ProvidesPrerequisite(ActorInitializer init, ProvidesPrerequisiteInfo info)
|
public ProvidesPrerequisite(ActorInitializer init, ProvidesPrerequisiteInfo info)
|
||||||
: base(info)
|
: base(info)
|
||||||
{
|
{
|
||||||
prerequisite = info.Prerequisite;
|
if (string.IsNullOrEmpty(info.Prerequisite))
|
||||||
|
prerequisites = new[] { init.Self.Info.Name };
|
||||||
if (string.IsNullOrEmpty(prerequisite))
|
else
|
||||||
prerequisite = init.Self.Info.Name;
|
prerequisites = new[] { info.Prerequisite };
|
||||||
|
|
||||||
faction = init.GetValue<FactionInit, string>(init.Self.Owner.Faction.InternalName);
|
faction = init.GetValue<FactionInit, string>(init.Self.Owner.Faction.InternalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> ProvidesPrerequisites
|
public IEnumerable<string> ProvidesPrerequisites => enabled ? prerequisites : Enumerable.Empty<string>();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!enabled)
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
yield return prerequisite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Created(Actor self)
|
protected override void Created(Actor self)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
@@ -38,11 +39,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly ProvidesTechPrerequisiteInfo info;
|
readonly ProvidesTechPrerequisiteInfo info;
|
||||||
readonly bool enabled;
|
readonly bool enabled;
|
||||||
|
|
||||||
static readonly string[] NoPrerequisites = Array.Empty<string>();
|
|
||||||
|
|
||||||
public string Name => info.Name;
|
public string Name => info.Name;
|
||||||
|
|
||||||
public IEnumerable<string> ProvidesPrerequisites => enabled ? info.Prerequisites : NoPrerequisites;
|
public IEnumerable<string> ProvidesPrerequisites => enabled ? info.Prerequisites : Enumerable.Empty<string>();
|
||||||
|
|
||||||
public ProvidesTechPrerequisite(ProvidesTechPrerequisiteInfo info, ActorInitializer init)
|
public ProvidesTechPrerequisite(ProvidesTechPrerequisiteInfo info, ActorInitializer init)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Primitives;
|
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
@@ -71,9 +70,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
^ !ownedPrereqs.ContainsKey(p.Replace("!", "").Replace("~", ""))));
|
^ !ownedPrereqs.ContainsKey(p.Replace("!", "").Replace("~", ""))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Cache<string, List<Actor>> GatherOwnedPrerequisites(Player player)
|
static Dictionary<string, int> GatherOwnedPrerequisites(Player player)
|
||||||
{
|
{
|
||||||
var ret = new Cache<string, List<Actor>>(x => new List<Actor>());
|
var ret = new Dictionary<string, int>();
|
||||||
if (player == null)
|
if (player == null)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -89,7 +88,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (p == null)
|
if (p == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret[p].Add(b.Actor);
|
ret.TryGetValue(p, out var count);
|
||||||
|
ret[p] = count + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
a.Actor.Info.TraitInfo<BuildableInfo>().BuildLimit > 0);
|
a.Actor.Info.TraitInfo<BuildableInfo>().BuildLimit > 0);
|
||||||
|
|
||||||
foreach (var buildable in buildables)
|
foreach (var buildable in buildables)
|
||||||
ret[buildable.Actor.Info.Name].Add(buildable.Actor);
|
{
|
||||||
|
var name = buildable.Actor.Info.Name;
|
||||||
|
ret.TryGetValue(name, out var count);
|
||||||
|
ret[name] = count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -132,7 +136,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
hidden = false;
|
hidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasPrerequisites(Cache<string, List<Actor>> ownedPrerequisites)
|
bool HasPrerequisites(Dictionary<string, int> ownedPrerequisites)
|
||||||
{
|
{
|
||||||
// PERF: Avoid LINQ.
|
// PERF: Avoid LINQ.
|
||||||
foreach (var prereq in prerequisites)
|
foreach (var prereq in prerequisites)
|
||||||
@@ -145,7 +149,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHidden(Cache<string, List<Actor>> ownedPrerequisites)
|
bool IsHidden(Dictionary<string, int> ownedPrerequisites)
|
||||||
{
|
{
|
||||||
// PERF: Avoid LINQ.
|
// PERF: Avoid LINQ.
|
||||||
foreach (var prereq in prerequisites)
|
foreach (var prereq in prerequisites)
|
||||||
@@ -160,12 +164,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(Cache<string, List<Actor>> ownedPrerequisites)
|
public void Update(Dictionary<string, int> ownedPrerequisites)
|
||||||
{
|
{
|
||||||
var hasReachedLimit = limit > 0 && ownedPrerequisites.ContainsKey(Key) && ownedPrerequisites[Key].Count >= limit;
|
var hasReachedLimit = limit > 0 && ownedPrerequisites.TryGetValue(Key, out var count) && count >= limit;
|
||||||
|
|
||||||
// The '!' annotation inverts prerequisites: "I'm buildable if this prerequisite *isn't* met"
|
// The '!' annotation inverts prerequisites: "I'm buildable if this prerequisite *isn't* met"
|
||||||
var nowHasPrerequisites = HasPrerequisites(ownedPrerequisites) && !hasReachedLimit;
|
var nowHasPrerequisites = !hasReachedLimit && HasPrerequisites(ownedPrerequisites);
|
||||||
var nowHidden = IsHidden(ownedPrerequisites);
|
var nowHidden = IsHidden(ownedPrerequisites);
|
||||||
|
|
||||||
if (initialized == false)
|
if (initialized == false)
|
||||||
|
|||||||
Reference in New Issue
Block a user