Merge pull request #5433 from RoosterDragon/main-loop-alloc

Reduce memory allocations in the main loop.
This commit is contained in:
Chris Forbes
2014-05-25 10:38:27 +12:00
6 changed files with 63 additions and 37 deletions

View File

@@ -81,9 +81,6 @@ namespace OpenRA
health = Exts.Lazy(() => TraitOrDefault<Health>());
effectiveOwner = Exts.Lazy(() => TraitOrDefault<IEffectiveOwner>());
applyIRender = (x, wr) => x.Render(this, wr);
applyRenderModifier = (m, p, wr) => p.ModifyRender(this, wr, m);
Bounds = Exts.Lazy(() =>
{
var si = Info.Traits.GetOrDefault<SelectableInfo>();
@@ -112,14 +109,19 @@ namespace OpenRA
get { return currentActivity == null; }
}
// note: these delegates are cached to avoid massive allocation.
Func<IRender, WorldRenderer, IEnumerable<IRenderable>> applyIRender;
Func<IEnumerable<IRenderable>, IRenderModifier, WorldRenderer, IEnumerable<IRenderable>> applyRenderModifier;
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
var mods = TraitsImplementing<IRenderModifier>();
var sprites = TraitsImplementing<IRender>().SelectMany(x => applyIRender(x, wr));
return mods.Aggregate(sprites, (m, p) => applyRenderModifier(m, p, wr));
var renderables = Renderables(wr);
foreach (var modifier in TraitsImplementing<IRenderModifier>())
renderables = modifier.ModifyRender(this, wr, renderables);
return renderables;
}
IEnumerable<IRenderable> Renderables(WorldRenderer wr)
{
foreach (var render in TraitsImplementing<IRender>())
foreach (var renderable in render.Render(this, wr))
yield return renderable;
}
public bool IsInWorld { get; internal set; }

View File

@@ -49,13 +49,16 @@ namespace OpenRA.Graphics
public IEnumerable<IRenderable> Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale)
{
var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration);
if (CurrentSequence.ShadowStart >= 0)
{
var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
yield return new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true);
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true);
return new IRenderable[] { shadowRenderable, imageRenderable };
}
yield return new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration);
return new IRenderable[] { imageRenderable };
}
public IEnumerable<IRenderable> Render(WPos pos, PaletteReference palette)

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Traits
public class FrozenActor
{
public readonly IEnumerable<CPos> Footprint;
public readonly CPos[] Footprint;
public readonly WPos CenterPosition;
public readonly Rectangle Bounds;
readonly Actor actor;
@@ -41,7 +41,7 @@ namespace OpenRA.Traits
public FrozenActor(Actor self, IEnumerable<CPos> footprint)
{
actor = self;
Footprint = footprint;
Footprint = footprint.ToArray();
CenterPosition = self.CenterPosition;
Bounds = self.Bounds.Value;
}
@@ -54,7 +54,13 @@ namespace OpenRA.Traits
int flashTicks;
public void Tick(World world, Shroud shroud)
{
Visible = !Footprint.Any(c => shroud.IsVisible(c));
Visible = false;
foreach (var pos in Footprint)
if (shroud.IsVisible(pos))
{
Visible = true;
break;
}
if (flashTicks > 0)
flashTicks--;

View File

@@ -237,10 +237,11 @@ namespace OpenRA.Widgets
public virtual Rectangle GetEventBounds()
{
return Children
.Where(c => c.IsVisible())
.Select(c => c.GetEventBounds())
.Aggregate(EventBounds, Rectangle.Union);
var bounds = EventBounds;
foreach (var child in Children)
if (child.IsVisible())
bounds = Rectangle.Union(bounds, child.GetEventBounds());
return bounds;
}
public bool HasMouseFocus { get { return Ui.MouseFocusWidget == this; } }