Performance optimization
This commit is contained in:
@@ -39,7 +39,13 @@ namespace CaveGame::Core
|
||||
explicit Chunk(const Vector2 &cell, const std::filesystem::path &file);
|
||||
|
||||
/// Returns the TileID enumeration that occupies the given tile-cell.
|
||||
TileID GetTile(int x, int y) const;
|
||||
[[nodiscard]] inline TileID GetTile(int x, int y) const {
|
||||
/* This is kind-of a cheat, If x or y is negative, the cast to unsigned will wrap it around to a large positive.
|
||||
* That makes it so you only have to check two conditions rather than 4 - Redacted. */
|
||||
if ((unsigned int) x >= (unsigned int)ChunkSize || (unsigned int) y >= (unsigned int)ChunkSize)
|
||||
throw std::runtime_error("Out of bounds!");
|
||||
return tiles[x][y];
|
||||
}
|
||||
|
||||
/// Sets the tile ID at the given tile-cell.
|
||||
/// @param trigger_tile_updates Whether to force adjacent tiles to update.
|
||||
@@ -49,10 +55,11 @@ namespace CaveGame::Core
|
||||
void SetTileSilent(int x, int y, TileID t);
|
||||
|
||||
/// Returns the value of the update flag field at the given tile-cell.
|
||||
bool GetTileUpdateFlag(int x, int y) const;
|
||||
[[nodiscard]] bool GetTileUpdateFlag(int x, int y) const;
|
||||
|
||||
bool GetTileUpdateBufferFlag(int x, int y) const;
|
||||
[[nodiscard]] bool GetTileUpdateBufferFlag(int x, int y) const;
|
||||
|
||||
[[nodiscard]] bool HasUpdate() const { return has_update; };
|
||||
void SetTileUpdateBufferFlag(int x, int y, bool flag = true);
|
||||
|
||||
/// Sets the value of the update flag field at the given tile-cell.A
|
||||
@@ -103,9 +110,9 @@ namespace CaveGame::Core
|
||||
|
||||
void SwapTileUpdateBuffers();
|
||||
|
||||
bool FirstPassCompleted() const;
|
||||
[[nodiscard]] bool FirstPassCompleted() const;
|
||||
|
||||
bool SecondPassCompleted() const;
|
||||
[[nodiscard]] bool SecondPassCompleted() const;
|
||||
|
||||
void SetFirstPassCompleted(bool complete = true);
|
||||
|
||||
@@ -120,6 +127,7 @@ namespace CaveGame::Core
|
||||
std::bitset<ChunkSize * ChunkSize> update_buffer;
|
||||
bool first_pass_complete = false;
|
||||
bool second_pass_complete = false;
|
||||
bool has_update = false;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -50,17 +50,12 @@ namespace CaveGame::Core
|
||||
size_t index = y * ChunkSize + x;
|
||||
|
||||
if (flag)
|
||||
tagged_for_update.set(index);
|
||||
tagged_for_update.set(index),
|
||||
has_update = true;
|
||||
else
|
||||
tagged_for_update.reset(index);
|
||||
}
|
||||
|
||||
TileID Chunk::GetTile(int x, int y) const {
|
||||
if (!(0 <= x && x < ChunkSize || 0 <= y && y < ChunkSize))
|
||||
throw std::runtime_error("Out of bounds!");
|
||||
return tiles[x][y];
|
||||
}
|
||||
|
||||
Chunk::Chunk(const Vector2& cell_coords) : cell(cell_coords), touched(false), update_buffer{}, tagged_for_update{}, tiles{} {}
|
||||
|
||||
Chunk::Chunk(const Vector2& cell_coords, const std::filesystem::path& file): Chunk(cell_coords)
|
||||
@@ -97,6 +92,7 @@ namespace CaveGame::Core
|
||||
void Chunk::SwapTileUpdateBuffers() {
|
||||
memcpy(&update_buffer, &tagged_for_update, sizeof(tagged_for_update));
|
||||
tagged_for_update.reset();
|
||||
has_update = false;
|
||||
}
|
||||
|
||||
bool Chunk::FirstPassCompleted() const { return first_pass_complete;}
|
||||
|
@@ -33,9 +33,6 @@ namespace CaveGame::Core
|
||||
DoForcedTileTick(coords, chunk);
|
||||
|
||||
}
|
||||
|
||||
//DoRandomTileTicks();
|
||||
//DoForcedTileTicks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,9 +387,7 @@ namespace CaveGame::Core
|
||||
Tile* tile = nullptr;
|
||||
|
||||
for (auto& [coords, chunk] : loaded_chunks) {
|
||||
|
||||
chunk->SwapTileUpdateBuffers();
|
||||
|
||||
for (int x = 0; x < Core::Chunk::ChunkSize; x++) {
|
||||
for (int y = 0; y < Core::Chunk::ChunkSize; y++) {
|
||||
int wx = coords.x*Chunk::ChunkSize + x;
|
||||
@@ -401,7 +396,8 @@ namespace CaveGame::Core
|
||||
if (!chunk->GetTileUpdateBufferFlag(x, y))
|
||||
continue;
|
||||
|
||||
chunk->SetTileUpdateBufferFlag(x, y, false);
|
||||
// Because we're swapping the whole thing, We don't have to set it to empty after.
|
||||
//chunk->SetTileUpdateBufferFlag(x, y, false);
|
||||
|
||||
TileID at = chunk->GetTile(x, y);
|
||||
|
||||
@@ -479,7 +475,11 @@ namespace CaveGame::Core
|
||||
Logs::Info("Saving successful!");
|
||||
}
|
||||
|
||||
void World::DoRandomTileTick(const Vector2& coords, Chunk *chunk) {
|
||||
// TODO
|
||||
/* This is what's taking all our CPU time now because we don't know if we have a tile in
|
||||
* our chunk that does random tile ticks *before* having to observe it right here. If that
|
||||
* were the case, We could just skip the whole thing. - Redacted. */
|
||||
void World::DoRandomTileTick(const Vector2& coords, Chunk* chunk) {
|
||||
Tile* tile = nullptr;
|
||||
|
||||
int max_tries = RandomTileTickCoefficient*5;
|
||||
@@ -500,22 +500,19 @@ namespace CaveGame::Core
|
||||
continue;
|
||||
|
||||
tile = GetByNumeric(at);
|
||||
|
||||
/*
|
||||
if (tile != nullptr)
|
||||
if (tile->DoesRandomTicc())
|
||||
tile->RandomTicc(this, 0, wx, wy);
|
||||
*/
|
||||
if ((tile != nullptr) && (tile->DoesRandomTicc()))
|
||||
tile->RandomTicc(this, 0, wx, wy);
|
||||
}
|
||||
}
|
||||
|
||||
void World::DoForcedTileTick(const Vector2& coords, Chunk *chunk) {
|
||||
Tile* tile = nullptr;
|
||||
void World::DoForcedTileTick(const Vector2& coords, Chunk* chunk) {
|
||||
/* We keep track of whether this chunk has had any tile updates put into the list
|
||||
* And if there's not, We just exit early to skip the whole thing - Redacted. */
|
||||
if (!chunk->HasUpdate())
|
||||
return;
|
||||
|
||||
Tile* tile;
|
||||
chunk->SwapTileUpdateBuffers();
|
||||
|
||||
for (int x = 0; x < Core::Chunk::ChunkSize; x++) {
|
||||
for (int y = 0; y < Core::Chunk::ChunkSize; y++) {
|
||||
int wx = coords.x*Chunk::ChunkSize + x;
|
||||
@@ -524,21 +521,14 @@ namespace CaveGame::Core
|
||||
if (!chunk->GetTileUpdateBufferFlag(x, y))
|
||||
continue;
|
||||
|
||||
chunk->SetTileUpdateBufferFlag(x, y, false);
|
||||
|
||||
TileID at = chunk->GetTile(x, y);
|
||||
|
||||
if (at == TileID::AIR)
|
||||
continue;
|
||||
|
||||
tile = GetByNumeric(at);
|
||||
|
||||
if (tile != nullptr) {
|
||||
if (tile->DoesForcedTicc()) {
|
||||
if (tile != nullptr)
|
||||
if (tile->DoesForcedTicc())
|
||||
tile->ForcedTicc(this, 0, wx, wy);
|
||||
//chunk->SetTileUpdateFlag(x, y, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user