-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
While reviewing the spectator cache logic in the map system, I noticed that when Tile::addThing is called, we currently perform a full cache clear.
I’m considering replacing these calls with a selective cache invalidation approach instead of clearing the entire cache every time.
void Map::clearSpectatorCache() { spectatorCache.clear(); }
void Map::clearPlayersSpectatorCache() { playersSpectatorCache.clear(); }This ensures consistency but can be costly since all cached spectator data is discarded and needs to be recalculated, even when only a small area is affected.
Here’s the proposed selective invalidation approach:
void Map::invalidateSpectatorCacheForCreature(const Creature* creature)
{
const auto& creaturePos = creature->getPosition();
auto invalidateCache = [&](SpectatorCache& cache) {
std::vector<Position> positionsToInvalidate;
for (auto& [centerPos, _] : cache) {
if (std::abs(centerPos.x - creaturePos.x) <= maxViewportX &&
std::abs(centerPos.y - creaturePos.y) <= maxViewportY) {
positionsToInvalidate.push_back(centerPos);
}
}
for (const auto& pos : positionsToInvalidate) {
cache.erase(pos);
}
};
invalidateCache(spectatorCache);
if (creature->getPlayer()) {
invalidateCache(playersSpectatorCache);
}
}This would only remove cache entries affected by the moving creature’s position, keeping the rest of the cache valid.
Questions
When invalidating, what’s the better approach?
A) Recalculate everything using getSpectatorsInternal(), ensuring correctness but increasing CPU usage.
B) Simply erase the affected positions from the cache and let them be lazily recalculated later when requested.