Skip to content

Commit

Permalink
Implemented Hash Cache for spectators.
Browse files Browse the repository at this point in the history
Co-Authored-By: Sarah Wesker <[email protected]>
  • Loading branch information
Codinablack and MillhioreBT committed Dec 7, 2024
1 parent 41b1c80 commit 6446aeb
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 21 deletions.
30 changes: 22 additions & 8 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,27 @@ void Map::getSpectators(SpectatorVec& spectators, const Position& centerPos, boo
minRangeY = (minRangeY == 0 ? -maxViewportY : -minRangeY);
maxRangeY = (maxRangeY == 0 ? maxViewportY : maxRangeY);

std::array<int32_t, 4> cache_values{
-maxViewportX , maxViewportX , -maxViewportY , maxViewportY
};
chunkKey.minRangeX = minRangeX;
chunkKey.maxRangeX = maxRangeX;
chunkKey.minRangeY = minRangeY;
chunkKey.maxRangeY = maxRangeY;
chunkKey.x = centerPos.x;
chunkKey.y = centerPos.y;
chunkKey.z = centerPos.z;
chunkKey.multifloor = multifloor;
chunkKey.onlyPlayers = onlyPlayers;

auto it = chunksSpectatorCache.find(chunkKey);
if (it != chunksSpectatorCache.end()) {
if (!spectators.empty()) {
spectators.addSpectators(it->second);
} else {
spectators = it->second;
}
foundCache = true;
} else {
cacheResult = true;
}

if (minRangeX == -maxViewportX && maxRangeX == maxViewportX && minRangeY == -maxViewportY && maxRangeY == maxViewportY && multifloor) {
if (onlyPlayers) {
Expand Down Expand Up @@ -467,11 +485,7 @@ void Map::getSpectators(SpectatorVec& spectators, const Position& centerPos, boo
getSpectatorsInternal(spectators, centerPos, minRangeX, maxRangeX, minRangeY, maxRangeY, minRangeZ, maxRangeZ, onlyPlayers);

if (cacheResult) {
if (onlyPlayers) {
playersSpectatorCache[centerPos] = spectators;
} else {
spectatorCache[centerPos] = spectators;
}
chunksSpectatorCache.emplace(chunkKey, spectators);
}
}
}
Expand Down
44 changes: 43 additions & 1 deletion src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,44 @@ static constexpr int32_t MAX_NODES = 512;
static constexpr int32_t MAP_NORMALWALKCOST = 10;
static constexpr int32_t MAP_DIAGONALWALKCOST = 25;

struct ChunkKey
{
int32_t minRangeX = 0;
int32_t maxRangeX = 0;
int32_t minRangeY = 0;
int32_t maxRangeY = 0;
uint16_t x = 0;
uint16_t y = 0;
uint8_t z = 0;
bool multifloor = false;
bool onlyPlayers = false;
};

static ChunkKey chunkKey;

struct ChunkKeyHash
{
std::size_t operator()(const ChunkKey& key) const
{
return std::hash<int32_t>()(key.minRangeX) ^ std::hash<int32_t>()(key.maxRangeX) ^
std::hash<int32_t>()(key.minRangeY) ^ std::hash<int32_t>()(key.maxRangeY) ^
std::hash<uint16_t>()(key.x) ^ std::hash<uint16_t>()(key.y) ^ std::hash<uint8_t>()(key.z) ^
std::hash<bool>()(key.multifloor) ^ std::hash<bool>()(key.onlyPlayers);
}
};

struct ChunkKeyEqual
{
bool operator()(const ChunkKey& lhs, const ChunkKey& rhs) const
{
return std::tie(lhs.minRangeX, lhs.maxRangeX, lhs.minRangeY, lhs.maxRangeY, lhs.x, lhs.y, lhs.z, lhs.multifloor,
lhs.onlyPlayers) == std::tie(rhs.minRangeX, rhs.maxRangeX, rhs.minRangeY, rhs.maxRangeY, rhs.x,
rhs.y, rhs.z, rhs.multifloor, rhs.onlyPlayers);
}
};

using ChunkCache = std::unordered_map<ChunkKey, SpectatorVec, ChunkKeyHash, ChunkKeyEqual>;

class AStarNodes
{
public:
Expand Down Expand Up @@ -169,6 +207,10 @@ class Map
* \returns true if the map was loaded successfully
*/
bool loadMap(const std::string& identifier, bool loadHouses);
void clearChunkSpectatorCache() {
playersSpectatorCache.clear();
chunksSpectatorCache.clear();
}

/**
* Save a map.
Expand Down Expand Up @@ -268,7 +310,7 @@ class Map
private:
SpectatorCache spectatorCache;
SpectatorCache playersSpectatorCache;

ChunkCache chunksSpectatorCache;
QTreeNode root;

std::filesystem::path spawnfile;
Expand Down
15 changes: 3 additions & 12 deletions src/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,10 +902,7 @@ void Tile::addThing(int32_t, Thing* thing)
{
Creature* creature = thing->getCreature();
if (creature) {
g_game.map.clearSpectatorCache();
if (creature->getPlayer()) {
g_game.map.clearPlayersSpectatorCache();
}
g_game.map.clearChunkSpectatorCache();

creature->setParent(this);
CreatureVector* creatures = makeCreatures();
Expand Down Expand Up @@ -1111,10 +1108,7 @@ void Tile::removeThing(Thing* thing, uint32_t count)
if (creatures) {
auto it = std::find(creatures->begin(), creatures->end(), thing);
if (it != creatures->end()) {
g_game.map.clearSpectatorCache();
if (creature->getPlayer()) {
g_game.map.clearPlayersSpectatorCache();
}
g_game.map.clearChunkSpectatorCache();

creatures->erase(it);
}
Expand Down Expand Up @@ -1491,10 +1485,7 @@ void Tile::internalAddThing(uint32_t, Thing* thing)

Creature* creature = thing->getCreature();
if (creature) {
g_game.map.clearSpectatorCache();
if (creature->getPlayer()) {
g_game.map.clearPlayersSpectatorCache();
}
g_game.map.clearChunkSpectatorCache();

CreatureVector* creatures = makeCreatures();
creatures->insert(creatures->begin(), creature);
Expand Down

0 comments on commit 6446aeb

Please sign in to comment.