From 3b2e2ed05b593f2fdd8ec7153bddb6cd8dd1e246 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 17 Oct 2022 10:24:37 +0200 Subject: a --- src/world.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 10 deletions(-) (limited to 'src/world.cpp') diff --git a/src/world.cpp b/src/world.cpp index 63209bf7..56025587 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,19 +1,93 @@ #include "world.hpp" +#include "chunk.hpp" namespace floormat { -static_assert(sizeof(decltype(local_coords::x))*8 == 8); -static_assert(sizeof(decltype(chunk_coords::x))*8 == 16); -static_assert(std::is_same_v); -static_assert(std::is_same_v); +struct chunk_pointer_maker final +{ + operator std::shared_ptr() const { return std::make_shared(); } +}; -static_assert(std::is_same_v); +world::world() +{ + _chunks.max_load_factor(max_load_factor); +} -static_assert(global_coords{{-1, -1}, {}} != global_coords{}); -static_assert(global_coords{15, 15}.chunk() == global_coords{}.chunk()); -static_assert(global_coords{15, 16}.chunk() != global_coords{}.chunk()); -static_assert(global_coords{(1 + (1<<15)) << 4 | 3, (2 + (1<<15)) << 4 | 4} == global_coords{{1, 2}, {3, 4}}); +std::shared_ptr world::operator[](chunk_coords c) noexcept +{ + auto [it, inserted] = _chunks.try_emplace(c, chunk_pointer_maker{}); + maybe_collect(); return it->second; +} +std::shared_ptr world::maybe_chunk(chunk_coords c) const noexcept +{ + if (const auto it = _chunks.find(c); it != _chunks.cend()) + return it->second; + else + return nullptr; +} -} // namespace floormat +std::shared_ptr world::maybe_chunk(chunk_coords c) noexcept +{ + return std::const_pointer_cast(const_cast(*this).maybe_chunk(c)); +} + +bool world::contains(chunk_coords c) const noexcept +{ + return _chunks.find(c) != _chunks.cend(); +} + +void world::clear() +{ + _last_collection = 0; + _chunks.rehash(initial_capacity); +} + +void world::maybe_collect() +{ + if (_last_collection + collect_every > _chunks.size()) + collect(); +} + +void world::collect() +{ + for (auto it = _chunks.begin(); it != _chunks.end(); (void)0) + { + const auto& [k, c] = *it; + if (c->empty()) + it = _chunks.erase(it); + else + it++; + } + _last_collection = _chunks.size(); +} +std::size_t world::hasher::operator()(chunk_coords c) const noexcept +{ + void _really_unreachable(); + + std::size_t x = (std::size_t)c.y << 16 | (std::size_t)c.x; + if constexpr(sizeof(std::size_t) == 4) + { + // by Chris Wellons + x ^= x >> 15; + x *= 0x2c1b3c6dU; + x ^= x >> 12; + x *= 0x297a2d39U; + x ^= x >> 15; + } + else if constexpr(sizeof(std::size_t) == 8) + { + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9U; + x ^= x >> 27; + x *= 0x94d049bb133111ebU; + x ^= x >> 31; + } + else + _really_unreachable(); + + return x; +} + +} // namespace floormat -- cgit v1.2.3