Merge pull request #5679 from RoosterDragon/main-loop-alloc
Reduce memory allocation in the main loop
This commit is contained in:
@@ -85,7 +85,8 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public int2 Measure(string text)
|
public int2 Measure(string text)
|
||||||
{
|
{
|
||||||
return new int2((int)text.Split('\n').Max(s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance)), text.Split('\n').Count()*size);
|
var lines = text.Split('\n');
|
||||||
|
return new int2((int)Math.Ceiling(lines.Max(s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance))), lines.Length * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache<Pair<char,Color>, GlyphInfo> glyphs;
|
Cache<Pair<char,Color>, GlyphInfo> glyphs;
|
||||||
|
|||||||
@@ -189,21 +189,22 @@ namespace OpenRA.Traits
|
|||||||
var j1 = (top / info.BinSize).Clamp(0, rows - 1);
|
var j1 = (top / info.BinSize).Clamp(0, rows - 1);
|
||||||
var j2 = (bottom / info.BinSize).Clamp(0, rows - 1);
|
var j2 = (bottom / info.BinSize).Clamp(0, rows - 1);
|
||||||
|
|
||||||
var actorsInBox = new List<Actor>();
|
var actorsChecked = new HashSet<Actor>();
|
||||||
for (var j = j1; j <= j2; j++)
|
for (var j = j1; j <= j2; j++)
|
||||||
{
|
{
|
||||||
for (var i = i1; i <= i2; i++)
|
for (var i = i1; i <= i2; i++)
|
||||||
{
|
{
|
||||||
foreach (var actor in actors[j * cols + i])
|
foreach (var actor in actors[j * cols + i])
|
||||||
{
|
{
|
||||||
var c = actor.CenterPosition;
|
if (actor.IsInWorld && actorsChecked.Add(actor))
|
||||||
if (actor.IsInWorld && left <= c.X && c.X <= right && top <= c.Y && c.Y <= bottom)
|
{
|
||||||
actorsInBox.Add(actor);
|
var c = actor.CenterPosition;
|
||||||
|
if (left <= c.X && c.X <= right && top <= c.Y && c.Y <= bottom)
|
||||||
|
yield return actor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return actorsInBox.Distinct();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,14 +153,15 @@ namespace OpenRA.Traits
|
|||||||
var top = (r.Top / info.BinSize).Clamp(0, rows - 1);
|
var top = (r.Top / info.BinSize).Clamp(0, rows - 1);
|
||||||
var bottom = (r.Bottom / info.BinSize).Clamp(0, rows - 1);
|
var bottom = (r.Bottom / info.BinSize).Clamp(0, rows - 1);
|
||||||
|
|
||||||
var actorsInBox = new List<Actor>();
|
var actorsChecked = new HashSet<Actor>();
|
||||||
for (var j = top; j <= bottom; j++)
|
for (var j = top; j <= bottom; j++)
|
||||||
for (var i = left; i <= right; i++)
|
for (var i = left; i <= right; i++)
|
||||||
actorsInBox.AddRange(actors[j * cols + i]
|
foreach (var kvp in actors[j * cols + i])
|
||||||
.Where(kv => kv.Key.IsInWorld && kv.Value.IntersectsWith(r))
|
{
|
||||||
.Select(kv => kv.Key));
|
var actor = kvp.Key;
|
||||||
|
if (actor.IsInWorld && kvp.Value.IntersectsWith(r) && actorsChecked.Add(actor))
|
||||||
return actorsInBox.Distinct();
|
yield return actor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, int2 a, int2 b)
|
public IEnumerable<FrozenActor> FrozenActorsInBox(Player p, int2 a, int2 b)
|
||||||
|
|||||||
@@ -111,18 +111,13 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public void TickRender(WorldRenderer wr, Actor self)
|
public void TickRender(WorldRenderer wr, Actor self)
|
||||||
{
|
{
|
||||||
if (self.Destroyed || !initialized || !visible.Any(v => v.Value))
|
if (self.Destroyed || !initialized || !visible.Values.Any(v => v))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IRenderable[] renderables = null;
|
var renderables = self.Render(wr).ToArray();
|
||||||
foreach (var player in self.World.Players)
|
foreach (var player in self.World.Players)
|
||||||
if (visible[player])
|
if (visible[player])
|
||||||
{
|
|
||||||
// Lazily generate a copy of the underlying data.
|
|
||||||
if (renderables == null)
|
|
||||||
renderables = self.Render(wr).ToArray();
|
|
||||||
frozen[player].Renderables = renderables;
|
frozen[player].Renderables = renderables;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
||||||
|
|||||||
@@ -45,10 +45,13 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public override void Tick(Actor self)
|
public override void Tick(Actor self)
|
||||||
{
|
{
|
||||||
isActive = self.World.ActorsWithTrait<Production>()
|
isActive = false;
|
||||||
.Any(x => x.Actor.Owner == self.Owner
|
foreach (var x in self.World.ActorsWithTrait<Production>())
|
||||||
&& x.Trait.Info.Produces.Contains(Info.Type));
|
if (x.Actor.Owner == self.Owner && x.Trait.Info.Produces.Contains(Info.Type))
|
||||||
|
{
|
||||||
|
isActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
base.Tick(self);
|
base.Tick(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,32 +110,26 @@ namespace OpenRA.Mods.RA
|
|||||||
IEnumerable<Actor> UnitsInRange()
|
IEnumerable<Actor> UnitsInRange()
|
||||||
{
|
{
|
||||||
return Self.World.FindActorsInCircle(Self.CenterPosition, WRange.FromCells(Info.Range))
|
return Self.World.FindActorsInCircle(Self.CenterPosition, WRange.FromCells(Info.Range))
|
||||||
.Where(a => a.IsInWorld && a != Self && !a.Destroyed)
|
.Where(a => a.IsInWorld && a != Self && !a.Destroyed && !a.Owner.NonCombatant);
|
||||||
.Where(a => !a.Owner.NonCombatant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsClear(Actor self, Player currentOwner, Player originalOwner)
|
bool IsClear(Actor self, Player currentOwner, Player originalOwner)
|
||||||
{
|
{
|
||||||
return UnitsInRange().Where(a => a.Owner != originalOwner)
|
return UnitsInRange()
|
||||||
.Where(a => a.Owner != currentOwner)
|
.All(a => a.Owner == originalOwner || a.Owner == currentOwner ||
|
||||||
.Where(a => CanBeCapturedBy(a))
|
WorldUtils.AreMutualAllies(a.Owner, currentOwner) || !CanBeCapturedBy(a));
|
||||||
.All(a => WorldUtils.AreMutualAllies(a.Owner, currentOwner));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO exclude other NeutralActor that arent permanent
|
// TODO exclude other NeutralActor that arent permanent
|
||||||
bool IsStillInRange(Actor self)
|
bool IsStillInRange(Actor self)
|
||||||
{
|
{
|
||||||
return UnitsInRange()
|
return UnitsInRange().Any(a => a.Owner == self.Owner && CanBeCapturedBy(a));
|
||||||
.Where(a => a.Owner == self.Owner)
|
|
||||||
.Where(a => CanBeCapturedBy(a))
|
|
||||||
.Any();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Actor> CaptorsInRange(Actor self)
|
IEnumerable<Actor> CaptorsInRange(Actor self)
|
||||||
{
|
{
|
||||||
return UnitsInRange()
|
return UnitsInRange()
|
||||||
.Where(a => a.Owner != OriginalOwner)
|
.Where(a => a.Owner != OriginalOwner && CanBeCapturedBy(a));
|
||||||
.Where(a => CanBeCapturedBy(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO exclude other NeutralActor that arent permanent
|
// TODO exclude other NeutralActor that arent permanent
|
||||||
@@ -146,8 +140,8 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
int CountPlayersNear(Actor self, Player ignoreMe)
|
int CountPlayersNear(Actor self, Player ignoreMe)
|
||||||
{
|
{
|
||||||
return CaptorsInRange(self).Select(a => a.Owner)
|
return CaptorsInRange(self).Select(a => a.Owner).Where(p => p != ignoreMe)
|
||||||
.Distinct().Count(p => p != ignoreMe);
|
.Distinct().Count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user