Cache the initial path layer for faster path search startups.
Reinitializing the initial cell info layer for the path search took a fair bit of time. We cache this initial setup so it only has to be done each time the map size changes. A CopyValuesFrom method in CellLayer is provided which copies values between layers by just copying the internal arrays for super speed. This speeds up InitCellInfo 10x.
This commit is contained in:
@@ -34,6 +34,17 @@ namespace OpenRA
|
|||||||
entries = new T[size.Width * size.Height];
|
entries = new T[size.Width * size.Height];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyValuesFrom(CellLayer<T> anotherLayer)
|
||||||
|
{
|
||||||
|
if (Size != anotherLayer.Size || Shape != anotherLayer.Shape)
|
||||||
|
throw new ArgumentException(
|
||||||
|
"layers must have a matching size and shape.", "anotherLayer");
|
||||||
|
if (CellEntryChanged != null)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"Cannot copy values when there are listeners attached to the CellEntryChanged event.");
|
||||||
|
Array.Copy(anotherLayer.entries, entries, entries.Length);
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve an array index from cell coordinates
|
// Resolve an array index from cell coordinates
|
||||||
int Index(CPos cell)
|
int Index(CPos cell)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -285,6 +285,8 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
}
|
}
|
||||||
|
|
||||||
static readonly Queue<CellLayer<CellInfo>> CellInfoPool = new Queue<CellLayer<CellInfo>>();
|
static readonly Queue<CellLayer<CellInfo>> CellInfoPool = new Queue<CellLayer<CellInfo>>();
|
||||||
|
static readonly object defaultCellInfoLayerSync = new object();
|
||||||
|
static CellLayer<CellInfo> defaultCellInfoLayer;
|
||||||
|
|
||||||
static CellLayer<CellInfo> GetFromPool()
|
static CellLayer<CellInfo> GetFromPool()
|
||||||
{
|
{
|
||||||
@@ -301,7 +303,8 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
CellLayer<CellInfo> InitCellInfo()
|
CellLayer<CellInfo> InitCellInfo()
|
||||||
{
|
{
|
||||||
CellLayer<CellInfo> result = null;
|
CellLayer<CellInfo> result = null;
|
||||||
var mapSize = new Size(self.World.Map.MapSize.X, self.World.Map.MapSize.Y);
|
var map = self.World.Map;
|
||||||
|
var mapSize = new Size(map.MapSize.X, map.MapSize.Y);
|
||||||
|
|
||||||
// HACK: Uses a static cache so that double-ended searches (which have two PathSearch instances)
|
// HACK: Uses a static cache so that double-ended searches (which have two PathSearch instances)
|
||||||
// can implicitly share data. The PathFinder should allocate the CellInfo array and pass it
|
// can implicitly share data. The PathFinder should allocate the CellInfo array and pass it
|
||||||
@@ -309,7 +312,7 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
while (CellInfoPool.Count > 0)
|
while (CellInfoPool.Count > 0)
|
||||||
{
|
{
|
||||||
var cellInfo = GetFromPool();
|
var cellInfo = GetFromPool();
|
||||||
if (cellInfo.Size != mapSize || cellInfo.Shape != self.World.Map.TileShape)
|
if (cellInfo.Size != mapSize || cellInfo.Shape != map.TileShape)
|
||||||
{
|
{
|
||||||
Log.Write("debug", "Discarding old pooled CellInfo of wrong size.");
|
Log.Write("debug", "Discarding old pooled CellInfo of wrong size.");
|
||||||
continue;
|
continue;
|
||||||
@@ -320,10 +323,22 @@ namespace OpenRA.Mods.RA.Move
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
if (result == null)
|
||||||
result = new CellLayer<CellInfo>(self.World.Map);
|
result = new CellLayer<CellInfo>(map);
|
||||||
|
|
||||||
|
lock (defaultCellInfoLayerSync)
|
||||||
|
{
|
||||||
|
if (defaultCellInfoLayer == null ||
|
||||||
|
defaultCellInfoLayer.Size != mapSize ||
|
||||||
|
defaultCellInfoLayer.Shape != map.TileShape)
|
||||||
|
{
|
||||||
|
defaultCellInfoLayer = new CellLayer<CellInfo>(map);
|
||||||
|
foreach (var cell in map.Cells)
|
||||||
|
defaultCellInfoLayer[cell] = new CellInfo(int.MaxValue, cell, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.CopyValuesFrom(defaultCellInfoLayer);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var cell in self.World.Map.Cells)
|
|
||||||
result[cell] = new CellInfo(int.MaxValue, cell, false);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user