Merge pull request #7577 from RoosterDragon/shroud-visibility-perf
Speed up shroud visibility updates.
This commit is contained in:
@@ -36,10 +36,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
cachedLocation = self.Location;
|
cachedLocation = self.Location;
|
||||||
cachedDisabled = disabled;
|
cachedDisabled = disabled;
|
||||||
|
Shroud.UpdateShroudGeneration(self.World.Players.Select(p => p.Shroud), self);
|
||||||
var shroud = self.World.Players.Select(p => p.Shroud);
|
|
||||||
foreach (var s in shroud)
|
|
||||||
s.UpdateShroudGeneration(self);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ namespace OpenRA.Traits
|
|||||||
if (cachedLocation != self.Location)
|
if (cachedLocation != self.Location)
|
||||||
{
|
{
|
||||||
cachedLocation = self.Location;
|
cachedLocation = self.Location;
|
||||||
|
Shroud.UpdateVisibility(self.World.Players.Select(p => p.Shroud), self);
|
||||||
foreach (var s in self.World.Players.Select(p => p.Shroud))
|
|
||||||
s.UpdateVisibility(self);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ namespace OpenRA.Traits
|
|||||||
generatedShroudCount = new CellLayer<short>(map);
|
generatedShroudCount = new CellLayer<short>(map);
|
||||||
explored = new CellLayer<bool>(map);
|
explored = new CellLayer<bool>(map);
|
||||||
|
|
||||||
self.World.ActorAdded += AddVisibility;
|
self.World.ActorAdded += a => { CPos[] visible = null; AddVisibility(a, ref visible); };
|
||||||
self.World.ActorRemoved += RemoveVisibility;
|
self.World.ActorRemoved += RemoveVisibility;
|
||||||
|
|
||||||
self.World.ActorAdded += AddShroudGeneration;
|
self.World.ActorAdded += a => { CPos[] shrouded = null; AddShroudGeneration(a, ref shrouded); };
|
||||||
self.World.ActorRemoved += RemoveShroudGeneration;
|
self.World.ActorRemoved += RemoveShroudGeneration;
|
||||||
|
|
||||||
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
|
||||||
@@ -98,6 +98,25 @@ namespace OpenRA.Traits
|
|||||||
Hash += 1;
|
Hash += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UpdateVisibility(IEnumerable<Shroud> shrouds, Actor actor)
|
||||||
|
{
|
||||||
|
CPos[] visbility = null;
|
||||||
|
foreach (var shroud in shrouds)
|
||||||
|
shroud.UpdateVisibility(actor, ref visbility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateShroudGeneration(IEnumerable<Shroud> shrouds, Actor actor)
|
||||||
|
{
|
||||||
|
CPos[] shrouded = null;
|
||||||
|
foreach (var shroud in shrouds)
|
||||||
|
shroud.UpdateShroudGeneration(actor, ref shrouded);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CPos[] FindVisibleTiles(Actor actor, WRange range)
|
||||||
|
{
|
||||||
|
return GetVisOrigins(actor).SelectMany(o => FindVisibleTiles(actor.World, o, range)).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
static IEnumerable<CPos> FindVisibleTiles(World world, CPos position, WRange radius)
|
static IEnumerable<CPos> FindVisibleTiles(World world, CPos position, WRange radius)
|
||||||
{
|
{
|
||||||
var map = world.Map;
|
var map = world.Map;
|
||||||
@@ -110,17 +129,15 @@ namespace OpenRA.Traits
|
|||||||
yield return cell;
|
yield return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVisibility(Actor a)
|
void AddVisibility(Actor a, ref CPos[] visible)
|
||||||
{
|
{
|
||||||
var rs = a.TraitOrDefault<RevealsShroud>();
|
var rs = a.TraitOrDefault<RevealsShroud>();
|
||||||
if (rs == null || !a.Owner.IsAlliedWith(self.Owner) || rs.Range == WRange.Zero)
|
if (rs == null || !a.Owner.IsAlliedWith(self.Owner) || rs.Range == WRange.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var origins = GetVisOrigins(a);
|
// Lazily generate the visible tiles, allowing the caller to re-use them if desired.
|
||||||
var visible = origins.SelectMany(o => FindVisibleTiles(a.World, o, rs.Range))
|
visible = visible ?? FindVisibleTiles(a, rs.Range);
|
||||||
.Distinct().ToArray();
|
|
||||||
|
|
||||||
// Update visibility
|
|
||||||
foreach (var c in visible)
|
foreach (var c in visible)
|
||||||
{
|
{
|
||||||
visibleCount[c]++;
|
visibleCount[c]++;
|
||||||
@@ -147,24 +164,25 @@ namespace OpenRA.Traits
|
|||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateVisibility(Actor a)
|
void UpdateVisibility(Actor a, ref CPos[] visible)
|
||||||
{
|
{
|
||||||
// Actors outside the world don't have any vis
|
// Actors outside the world don't have any vis
|
||||||
if (!a.IsInWorld)
|
if (!a.IsInWorld)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RemoveVisibility(a);
|
RemoveVisibility(a);
|
||||||
AddVisibility(a);
|
AddVisibility(a, ref visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddShroudGeneration(Actor a)
|
void AddShroudGeneration(Actor a, ref CPos[] shrouded)
|
||||||
{
|
{
|
||||||
var cs = a.TraitOrDefault<CreatesShroud>();
|
var cs = a.TraitOrDefault<CreatesShroud>();
|
||||||
if (cs == null || a.Owner.IsAlliedWith(self.Owner) || cs.Range == WRange.Zero)
|
if (cs == null || a.Owner.IsAlliedWith(self.Owner) || cs.Range == WRange.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var shrouded = GetVisOrigins(a).SelectMany(o => FindVisibleTiles(a.World, o, cs.Range))
|
// Lazily generate the shrouded tiles, allowing the caller to re-use them if desired.
|
||||||
.Distinct().ToArray();
|
shrouded = shrouded ?? FindVisibleTiles(a, cs.Range);
|
||||||
|
|
||||||
foreach (var c in shrouded)
|
foreach (var c in shrouded)
|
||||||
generatedShroudCount[c]++;
|
generatedShroudCount[c]++;
|
||||||
|
|
||||||
@@ -188,10 +206,10 @@ namespace OpenRA.Traits
|
|||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateShroudGeneration(Actor a)
|
void UpdateShroudGeneration(Actor a, ref CPos[] shrouded)
|
||||||
{
|
{
|
||||||
RemoveShroudGeneration(a);
|
RemoveShroudGeneration(a);
|
||||||
AddShroudGeneration(a);
|
AddShroudGeneration(a, ref shrouded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdatePlayerStance(World w, Player player, Stance oldStance, Stance newStance)
|
public void UpdatePlayerStance(World w, Player player, Stance oldStance, Stance newStance)
|
||||||
@@ -201,8 +219,10 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
foreach (var a in w.Actors.Where(a => a.Owner == player))
|
foreach (var a in w.Actors.Where(a => a.Owner == player))
|
||||||
{
|
{
|
||||||
UpdateVisibility(a);
|
CPos[] visible = null;
|
||||||
UpdateShroudGeneration(a);
|
UpdateVisibility(a, ref visible);
|
||||||
|
CPos[] shrouded = null;
|
||||||
|
UpdateShroudGeneration(a, ref shrouded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user