ExternalCondition: remove timedTokensBySource

This commit is contained in:
atlimit8
2017-07-23 13:58:48 -05:00
committed by Paul Chote
parent f51323daa3
commit 62c76b8ae9

View File

@@ -51,7 +51,6 @@ namespace OpenRA.Mods.Common.Traits
public readonly ExternalConditionInfo Info; public readonly ExternalConditionInfo Info;
readonly ConditionManager conditionManager; readonly ConditionManager conditionManager;
readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>(); readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>();
readonly Dictionary<object, Dictionary<int, TimedToken>> timedTokensBySource = new Dictionary<object, Dictionary<int, TimedToken>>();
readonly List<KeyValuePair<int, TimedToken>> timedTokensByExpiration = new List<KeyValuePair<int, TimedToken>>(); readonly List<KeyValuePair<int, TimedToken>> timedTokensByExpiration = new List<KeyValuePair<int, TimedToken>>();
public ExternalCondition(Actor self, ExternalConditionInfo info) public ExternalCondition(Actor self, ExternalConditionInfo info)
@@ -80,12 +79,12 @@ namespace OpenRA.Mods.Common.Traits
return true; return true;
} }
void RemoveFromExpiration(TimedToken timedToken) void Remove(TimedToken timedToken)
{ {
timedTokensByExpiration.RemoveAt(timedTokensByExpiration.FindIndex(p => p.Value == timedToken)); timedTokensByExpiration.RemoveAt(timedTokensByExpiration.FindIndex(p => p.Value == timedToken));
} }
void AddForExpiration(TimedToken timedToken) void Add(TimedToken timedToken)
{ {
var index = timedTokensByExpiration.FindIndex(p => p.Key >= timedToken.Expires); var index = timedTokensByExpiration.FindIndex(p => p.Key >= timedToken.Expires);
if (index >= 0) if (index >= 0)
@@ -105,18 +104,18 @@ namespace OpenRA.Mods.Common.Traits
if (duration > 0) if (duration > 0)
{ {
var timed = timedTokensBySource.GetOrAdd(source);
// Check level caps // Check level caps
if (Info.SourceCap > 0) if (Info.SourceCap > 0)
{ {
if ((permanent != null ? permanent.Count + timed.Count : timed.Count) >= Info.SourceCap) var timedCount = timedTokensByExpiration.Count(p => p.Value.Source == source);
if ((permanent != null ? permanent.Count + timedCount : timedCount) >= Info.SourceCap)
{ {
var expire = timed.MinByOrDefault(t => t.Value.Expires).Value; // Get timed token from the same source with closest expiration.
if (expire != null) var expireIndex = timedTokensByExpiration.FindIndex(t => t.Value.Source == source);
if (expireIndex >= 0)
{ {
timed.Remove(expire.Token); var expire = timedTokensByExpiration[expireIndex].Value;
RemoveFromExpiration(expire); Remove(expire);
if (conditionManager.TokenValid(self, expire.Token)) if (conditionManager.TokenValid(self, expire.Token))
conditionManager.RevokeCondition(self, expire.Token); conditionManager.RevokeCondition(self, expire.Token);
@@ -136,15 +135,13 @@ namespace OpenRA.Mods.Common.Traits
if (conditionManager.TokenValid(self, expire.Token)) if (conditionManager.TokenValid(self, expire.Token))
conditionManager.RevokeCondition(self, expire.Token); conditionManager.RevokeCondition(self, expire.Token);
timedTokensBySource[expire.Source].Remove(expire.Token); Remove(expire);
RemoveFromExpiration(expire);
} }
} }
} }
var timedToken = new TimedToken(token, self, source, duration); var timedToken = new TimedToken(token, self, source, duration);
timed.Add(token, timedToken); Add(timedToken);
AddForExpiration(timedToken);
} }
else if (permanent == null) else if (permanent == null)
permanentTokens.Add(source, new HashSet<int> { token }); permanentTokens.Add(source, new HashSet<int> { token });
@@ -169,16 +166,11 @@ namespace OpenRA.Mods.Common.Traits
} }
else else
{ {
Dictionary<int, TimedToken> timedTokensForSource; var index = timedTokensByExpiration.FindIndex(p => p.Value.Token == token);
if (timedTokensBySource.TryGetValue(source, out timedTokensForSource)) if (index >= 0 && timedTokensByExpiration[index].Value.Source == source)
{ timedTokensByExpiration.RemoveAt(index);
TimedToken timedToken; else
if (!timedTokensForSource.TryGetValue(token, out timedToken))
return false; return false;
timedTokensForSource.Remove(token);
RemoveFromExpiration(timedToken);
}
} }
if (conditionManager.TokenValid(self, token)) if (conditionManager.TokenValid(self, token))
@@ -189,26 +181,14 @@ namespace OpenRA.Mods.Common.Traits
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
if (timedTokensByExpiration.Count == 0)
return;
// Remove expired tokens // Remove expired tokens
var worldTick = self.World.WorldTick; var worldTick = self.World.WorldTick;
var pair = timedTokensByExpiration[0]; var count = 0;
while (pair.Key < worldTick) while (count < timedTokensByExpiration.Count && timedTokensByExpiration[count].Key < worldTick)
{ count++;
var timed = pair.Value;
var timedTokensForSource = timedTokensBySource[timed.Source];
timedTokensForSource.Remove(timed.Token);
if (timedTokensForSource.Count == 0)
timedTokensBySource.Remove(timed.Source);
timedTokensByExpiration.RemoveAt(0); if (count > 0)
if (timedTokensByExpiration.Count == 0) timedTokensByExpiration.RemoveRange(0, count);
return;
pair = timedTokensByExpiration[0];
}
} }
} }
} }