Skip to content

Commit

Permalink
fix: crash concurrent modification/casting in tile management (#3107)
Browse files Browse the repository at this point in the history
This adds the implementation for dynamically determining the type of
tile (HouseTile, StaticTile, DynamicTile) when creating a new tile
object. The motivation is to correctly identify and assign specific tile
types, which enhances code readability and maintainability. The change
also ensures that houses have associated HouseTile objects for better
data integrity.
  • Loading branch information
dudantas authored Nov 13, 2024
1 parent 982f184 commit d360a63
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/items/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ class DynamicTile : public Tile {
CreatureVector creatures;

public:
explicit DynamicTile(const Position &position) :
Tile(position.x, position.y, position.z) { }
DynamicTile(uint16_t x, uint16_t y, uint8_t z) :
Tile(x, y, z) { }

Expand Down Expand Up @@ -323,6 +325,8 @@ class StaticTile final : public Tile {
std::unique_ptr<CreatureVector> creatures;

public:
explicit StaticTile(const Position &position) :
Tile(position.x, position.y, position.z) { }
StaticTile(uint16_t x, uint16_t y, uint8_t z) :
Tile(x, y, z) { }

Expand Down
3 changes: 3 additions & 0 deletions src/map/house/housetile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "map/house/house.hpp"
#include "utils/tools.hpp"

HouseTile::HouseTile(const Position &position, std::shared_ptr<House> newHouse) :
DynamicTile(position.x, position.y, position.z), house(std::move(newHouse)) { }

HouseTile::HouseTile(int32_t initX, int32_t initY, int32_t initZ, std::shared_ptr<House> initHouse) :
DynamicTile(initX, initY, initZ), house(std::move(initHouse)) { }

Expand Down
1 change: 1 addition & 0 deletions src/map/house/housetile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class HouseTile final : public DynamicTile {
public:
using Tile::addThing;

HouseTile(const Position &position, std::shared_ptr<House> house);
HouseTile(int32_t x, int32_t y, int32_t z, std::shared_ptr<House> house);

// cylinder implementations
Expand Down
19 changes: 12 additions & 7 deletions src/map/mapcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,23 @@ std::shared_ptr<Tile> MapCache::getOrCreateTileFromCache(const std::shared_ptr<F

std::shared_ptr<Tile> tile = nullptr;

auto pos = Position(x, y, z);

if (cachedTile->isHouse()) {
const auto &house = map->houses.getHouse(cachedTile->houseId);
tile = std::make_shared<HouseTile>(x, y, z, house);
house->addTile(std::static_pointer_cast<HouseTile>(tile));
if (const auto &house = map->houses.getHouse(cachedTile->houseId)) {
tile = std::make_shared<HouseTile>(pos, house);
tile->safeCall([tile] {
tile->getHouse()->addTile(tile->static_self_cast<HouseTile>());
});
} else {
g_logger().error("[{}] house not found for houseId {}", std::source_location::current().function_name(), cachedTile->houseId);
}
} else if (cachedTile->isStatic) {
tile = std::make_shared<StaticTile>(x, y, z);
tile = std::make_shared<StaticTile>(pos);
} else {
tile = std::make_shared<DynamicTile>(x, y, z);
tile = std::make_shared<DynamicTile>(pos);
}

auto pos = Position(x, y, z);

if (cachedTile->ground != nullptr) {
tile->internalAddThing(createItem(cachedTile->ground, pos));
}
Expand Down

0 comments on commit d360a63

Please sign in to comment.