Use Array.IndexOf to speed up Shroud.Tick.
As the `touched` cell layer uses Boolean values, Array.IndexOf is able to use a fast vectorised search. Most values in the array are false, so the search is able to significantly improve the performance of finding the next true value in the array.
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
@@ -53,5 +54,15 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
return Bounds.Contains(uv.U, uv.V);
|
return Bounds.Contains(uv.U, uv.V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int IndexOf(T value, int startIndex)
|
||||||
|
{
|
||||||
|
return Array.IndexOf(Entries, value, startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAll(T value)
|
||||||
|
{
|
||||||
|
Array.Fill(Entries, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,48 +182,22 @@ namespace OpenRA.Traits
|
|||||||
// We loop over the direct index that represents the PPos in
|
// We loop over the direct index that represents the PPos in
|
||||||
// the ProjectedCellLayers, converting to a PPos only if
|
// the ProjectedCellLayers, converting to a PPos only if
|
||||||
// it is needed (which is the uncommon case.)
|
// it is needed (which is the uncommon case.)
|
||||||
var maxIndex = touched.MaxIndex;
|
if (disabledChanged)
|
||||||
for (var index = 0; index < maxIndex; index++)
|
|
||||||
{
|
{
|
||||||
// PERF: Most cells are not touched
|
touched.SetAll(false);
|
||||||
if (!touched[index] && !disabledChanged)
|
var maxIndex = touched.MaxIndex;
|
||||||
continue;
|
for (var index = 0; index < maxIndex; index++)
|
||||||
|
UpdateCell(index, self);
|
||||||
touched[index] = false;
|
}
|
||||||
|
else
|
||||||
var type = ShroudCellType.Shroud;
|
{
|
||||||
|
// PERF: Most cells are unchanged, use IndexOf for fast vectorized search.
|
||||||
if (explored[index])
|
var index = touched.IndexOf(true, 0);
|
||||||
|
while (index != -1)
|
||||||
{
|
{
|
||||||
var count = visibleCount[index];
|
touched[index] = false;
|
||||||
if (!shroudGenerationEnabled || count > 0 || generatedShroudCount[index] == 0)
|
UpdateCell(index, self);
|
||||||
{
|
index = touched.IndexOf(true, index + 1);
|
||||||
if (passiveVisibilityEnabled)
|
|
||||||
count += passiveVisibleCount[index];
|
|
||||||
|
|
||||||
type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PERF: Most cells are unchanged
|
|
||||||
var oldResolvedType = resolvedType[index];
|
|
||||||
if (type != oldResolvedType || disabledChanged)
|
|
||||||
{
|
|
||||||
resolvedType[index] = type;
|
|
||||||
var puv = touched.PPosFromIndex(index);
|
|
||||||
if (map.Contains(puv))
|
|
||||||
OnShroudChanged(puv);
|
|
||||||
|
|
||||||
if (!disabledChanged && (fogEnabled || !ExploreMapEnabled))
|
|
||||||
{
|
|
||||||
if (type == ShroudCellType.Visible)
|
|
||||||
RevealedCells++;
|
|
||||||
else if (fogEnabled && oldResolvedType == ShroudCellType.Visible)
|
|
||||||
RevealedCells--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.Owner.WinState == WinState.Lost)
|
|
||||||
RevealedCells = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +205,44 @@ namespace OpenRA.Traits
|
|||||||
disabledChanged = false;
|
disabledChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateCell(int index, Actor self)
|
||||||
|
{
|
||||||
|
var type = ShroudCellType.Shroud;
|
||||||
|
|
||||||
|
if (explored[index])
|
||||||
|
{
|
||||||
|
var count = visibleCount[index];
|
||||||
|
if (!shroudGenerationEnabled || count > 0 || generatedShroudCount[index] == 0)
|
||||||
|
{
|
||||||
|
if (passiveVisibilityEnabled)
|
||||||
|
count += passiveVisibleCount[index];
|
||||||
|
|
||||||
|
type = count > 0 ? ShroudCellType.Visible : ShroudCellType.Fog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PERF: Most cells are unchanged
|
||||||
|
var oldResolvedType = resolvedType[index];
|
||||||
|
if (type != oldResolvedType || disabledChanged)
|
||||||
|
{
|
||||||
|
resolvedType[index] = type;
|
||||||
|
var puv = touched.PPosFromIndex(index);
|
||||||
|
if (map.Contains(puv))
|
||||||
|
OnShroudChanged(puv);
|
||||||
|
|
||||||
|
if (!disabledChanged && (fogEnabled || !ExploreMapEnabled))
|
||||||
|
{
|
||||||
|
if (type == ShroudCellType.Visible)
|
||||||
|
RevealedCells++;
|
||||||
|
else if (fogEnabled && oldResolvedType == ShroudCellType.Visible)
|
||||||
|
RevealedCells--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.Owner.WinState == WinState.Lost)
|
||||||
|
RevealedCells = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, WPos pos, WDist minRange, WDist maxRange, int maxHeightDelta = -1)
|
public static IEnumerable<PPos> ProjectedCellsInRange(Map map, WPos pos, WDist minRange, WDist maxRange, int maxHeightDelta = -1)
|
||||||
{
|
{
|
||||||
// Account for potential extra half-cell from odd-height terrain
|
// Account for potential extra half-cell from odd-height terrain
|
||||||
|
|||||||
Reference in New Issue
Block a user