diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-24 22:55:06 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-24 22:55:06 +0200 |
commit | 9076ef2ee672877bbf339d5ca8db182445f127f7 (patch) | |
tree | b1c2c8a379e864867f8ad3878fc81d9f06fa1bda /src | |
parent | 27a04888cfeca3d3db127744dde60b67fe497b94 (diff) |
a
Diffstat (limited to 'src')
-rw-r--r-- | src/chunk.cpp | 4 | ||||
-rw-r--r-- | src/chunk.hpp | 31 | ||||
-rw-r--r-- | src/world.cpp | 35 | ||||
-rw-r--r-- | src/world.hpp | 23 |
4 files changed, 45 insertions, 48 deletions
diff --git a/src/chunk.cpp b/src/chunk.cpp index d8c2d011..92817765 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -2,9 +2,9 @@ namespace floormat { -bool chunk::empty() const +bool chunk::empty(bool force) const noexcept { - if (!_maybe_empty) + if (!force && !_maybe_empty) return false; for (const tile& x : _tiles) diff --git a/src/chunk.hpp b/src/chunk.hpp index f0ed1426..3bf66920 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -10,30 +10,29 @@ template<typename T> class basic_tile_iterator; struct chunk final { - tile& operator[](local_coords xy) { return _tiles[xy.to_index()]; } - const tile& operator[](local_coords xy) const { return _tiles[xy.to_index()]; } - tile& operator[](std::size_t i) { return _tiles[i]; } - const tile& operator[](std::size_t i) const { return _tiles[i]; } - const auto& tiles() const { return _tiles; } - auto& tiles() { return _tiles; } + tile& operator[](local_coords xy) noexcept { return _tiles[xy.to_index()]; } + const tile& operator[](local_coords xy) const noexcept { return _tiles[xy.to_index()]; } + tile& operator[](std::size_t i) noexcept { return _tiles[i]; } + const tile& operator[](std::size_t i) const noexcept { return _tiles[i]; } + const auto& tiles() const noexcept { return _tiles; } + auto& tiles() noexcept { return _tiles; } using iterator = basic_tile_iterator<tile>; using const_iterator = basic_tile_iterator<const tile>; - iterator begin() { return iterator{_tiles.data(), 0}; } - iterator end() { return iterator{_tiles.data(), _tiles.size()}; } - const_iterator cbegin() const { return const_iterator{_tiles.data(), 0}; } - const_iterator cend() const { return const_iterator{_tiles.data(), _tiles.size()}; } - const_iterator begin() const { return cbegin(); } - const_iterator end() const { return cend(); } + iterator begin() noexcept { return iterator{_tiles.data(), 0}; } + iterator end() noexcept { return iterator{_tiles.data(), _tiles.size()}; } + const_iterator cbegin() const noexcept { return const_iterator{_tiles.data(), 0}; } + const_iterator cend() const noexcept { return const_iterator{_tiles.data(), _tiles.size()}; } + const_iterator begin() const noexcept { return cbegin(); } + const_iterator end() const noexcept { return cend(); } - bool empty() const; + bool empty(bool force = false) const noexcept; - chunk() = default; - chunk(chunk&&) = default; - chunk& operator=(chunk&&) = default; + chunk() noexcept = default; fm_DECLARE_DELETED_COPY_ASSIGNMENT(chunk); + fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(chunk); private: std::array<tile, TILE_COUNT> _tiles = {}; diff --git a/src/world.cpp b/src/world.cpp index 4e47f912..dcb1b4a3 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -3,37 +3,32 @@ namespace floormat { -struct chunk_pointer_maker final -{ - inline operator std::shared_ptr<chunk>() const { return std::make_shared<chunk>(); } -}; - world::world() { _chunks.max_load_factor(max_load_factor); } -std::shared_ptr<chunk> world::operator[](chunk_coords c) noexcept +chunk& world::operator[](chunk_coords coord) noexcept { maybe_collect(); - if (_last_chunk) + if (auto& [c, coord2] = _last_chunk; c && coord == coord2) { - auto& [ret, pos] = *_last_chunk; - if (pos == c) - return ret; + return *c; } - auto [it, inserted] = _chunks.try_emplace(c, chunk_pointer_maker{}); - auto ret = it->second; - _last_chunk = { ret, c }; + auto [it, inserted] = _chunks.try_emplace(coord); + auto& ret = it->second; + auto& [_c, _coord] = _last_chunk; + _c = &ret; + _coord = coord; return ret; } -std::tuple<std::shared_ptr<chunk>, tile&> world::operator[](global_coords pt) noexcept +std::tuple<chunk&, tile&> world::operator[](global_coords pt) noexcept { - auto c = operator[](pt.chunk()); - return { c, (*c)[pt.local()] }; + auto& c = operator[](pt.chunk()); + return { c, c[pt.local()] }; } bool world::contains(chunk_coords c) const noexcept @@ -44,9 +39,10 @@ bool world::contains(chunk_coords c) const noexcept void world::clear() { _last_collection = 0; - _last_chunk = std::nullopt; _chunks.clear(); _chunks.rehash(initial_capacity); + auto& [c, _] = _last_chunk; + c = nullptr; } void world::maybe_collect() @@ -60,14 +56,15 @@ void world::collect() for (auto it = _chunks.begin(); it != _chunks.end(); (void)0) { const auto& [_, c] = *it; - if (c->empty()) + if (c.empty()) it = _chunks.erase(it); else ++it; } _last_collection = _chunks.size(); - _last_chunk = std::nullopt; + auto& [c, _] = _last_chunk; + c = nullptr; } } // namespace floormat diff --git a/src/world.hpp b/src/world.hpp index 32c7206a..1b05a824 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -2,13 +2,13 @@ #include "compat/int-hash.hpp" #include "global-coords.hpp" #include "tile.hpp" +#include "chunk.hpp" #include <unordered_map> #include <memory> #include <optional> namespace floormat { -// todo remove shared_ptr struct chunk; struct world final @@ -22,18 +22,18 @@ private: return int_hash((std::size_t)c.y << 16 | (std::size_t)c.x); }; - std::unordered_map<chunk_coords, std::shared_ptr<chunk>, decltype(hasher)> _chunks{initial_capacity, hasher}; - mutable std::optional<std::tuple<std::shared_ptr<chunk>, chunk_coords>> _last_chunk; + std::unordered_map<chunk_coords, chunk, decltype(hasher)> _chunks{initial_capacity, hasher}; + mutable std::tuple<chunk*, chunk_coords>_last_chunk; std::size_t _last_collection = 0; public: explicit world(); template<typename Hash, typename Alloc, typename Pred> - explicit world(std::unordered_map<chunk_coords, std::shared_ptr<chunk>, Hash, Alloc, Pred>&& chunks); + explicit world(std::unordered_map<chunk_coords, chunk, Hash, Alloc, Pred>&& chunks); - std::shared_ptr<chunk> operator[](chunk_coords c) noexcept; - std::tuple<std::shared_ptr<chunk>, tile&> operator[](global_coords pt) noexcept; + chunk& operator[](chunk_coords c) noexcept; + std::tuple<chunk&, tile&> operator[](global_coords pt) noexcept; bool contains(chunk_coords c) const noexcept; void clear(); void collect(); @@ -45,10 +45,11 @@ public: }; template<typename Hash, typename Alloc, typename Pred> -world::world(std::unordered_map<chunk_coords, std::shared_ptr<chunk>, Hash, Alloc, Pred>&& chunks) : - _chunks{chunks.begin(), chunks.end(), - std::max(initial_capacity, std::size_t(1/max_load_factor * 2 * chunks.size())), - hasher} -{} +world::world(std::unordered_map<chunk_coords, chunk, Hash, Alloc, Pred>&& chunks) : + _chunks{std::max(initial_capacity, std::size_t(1/max_load_factor * 2 * chunks.size())), hasher} +{ + for (auto&& [coord, c] : chunks) + operator[](coord) = std::move(c); +} } // namespace floormat |