Merge pull request #5851 from RoosterDragon/shroud-perf

Speed up shroud checks
This commit is contained in:
Paul Chote
2014-07-23 11:02:27 +12:00
9 changed files with 325 additions and 207 deletions

View File

@@ -12,7 +12,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Graphics;
namespace OpenRA
{
@@ -21,7 +20,7 @@ namespace OpenRA
{
public readonly Size Size;
public readonly TileShape Shape;
T[] entries;
readonly T[] entries;
public CellLayer(Map map)
: this(map.TileShape, new Size(map.MapSize.X, map.MapSize.Y)) { }
@@ -37,35 +36,27 @@ namespace OpenRA
int Index(CPos cell)
{
var uv = Map.CellToMap(Shape, cell);
return uv.Y * Size.Width + uv.X;
return Index(uv.X, uv.Y);
}
// Resolve an array index from map coordinates
int Index(int u, int v)
{
return v * Size.Width + u;
}
/// <summary>Gets or sets the <see cref="OpenRA.CellLayer"/> using cell coordinates</summary>
public T this[CPos cell]
{
get
{
return entries[Index(cell)];
}
set
{
entries[Index(cell)] = value;
}
get { return entries[Index(cell)]; }
set { entries[Index(cell)] = value; }
}
/// <summary>Gets or sets the layer contents using raw map coordinates (not CPos!)</summary>
public T this[int u, int v]
{
get
{
return entries[v * Size.Width + u];
}
set
{
entries[v * Size.Width + u] = value;
}
get { return entries[Index(u, v)]; }
set { entries[Index(u, v)] = value; }
}
/// <summary>Clears the layer contents with a known value</summary>

View File

@@ -11,8 +11,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using OpenRA.Graphics;
using System.Linq;
namespace OpenRA
{
@@ -50,29 +49,69 @@ namespace OpenRA
return new CellRegion(region.shape, tl, br);
}
/// <summary>Returns the minimal region that covers at least the specified cells.</summary>
public static CellRegion BoundingRegion(TileShape shape, IEnumerable<CPos> cells)
{
if (cells == null || !cells.Any())
throw new ArgumentException("cells must not be null or empty.", "cells");
var minX = int.MaxValue;
var minY = int.MaxValue;
var maxX = int.MinValue;
var maxY = int.MinValue;
foreach (var cell in cells)
{
if (minX > cell.X)
minX = cell.X;
if (maxX < cell.X)
maxX = cell.X;
if (minY > cell.Y)
minY = cell.Y;
if (maxY < cell.Y)
maxY = cell.Y;
}
return new CellRegion(shape, new CPos(minX, minY), new CPos(maxX, maxY));
}
public bool Contains(CellRegion region)
{
return
TopLeft.X <= region.TopLeft.X && TopLeft.Y <= region.TopLeft.Y &&
BottomRight.X >= region.BottomRight.X && BottomRight.Y >= region.BottomRight.Y;
}
public bool Contains(CPos cell)
{
var uv = Map.CellToMap(shape, cell);
return uv.X >= mapTopLeft.X && uv.X <= mapBottomRight.X && uv.Y >= mapTopLeft.Y && uv.Y <= mapBottomRight.Y;
}
public IEnumerator<CPos> GetEnumerator()
public CellRegionEnumerator GetEnumerator()
{
return new CellRegionEnumerator(this);
}
IEnumerator<CPos> IEnumerable<CPos>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
class CellRegionEnumerator : IEnumerator<CPos>
public class CellRegionEnumerator : IEnumerator<CPos>
{
readonly CellRegion r;
// Current position, in map coordinates
int u, v;
// Current position, in cell coordinates
CPos current;
public CellRegionEnumerator(CellRegion region)
{
r = region;
@@ -94,6 +133,7 @@ namespace OpenRA
return false;
}
current = Map.MapToCell(r.shape, new CPos(u, v));
return true;
}
@@ -104,7 +144,7 @@ namespace OpenRA
v = r.mapTopLeft.Y;
}
public CPos Current { get { return Map.MapToCell(r.shape, new CPos(u, v)); } }
public CPos Current { get { return current; } }
object IEnumerator.Current { get { return Current; } }
public void Dispose() { }
}