diff options
-rw-r--r-- | serialize/world-reader.cpp | 20 | ||||
-rw-r--r-- | src/character.cpp | 2 | ||||
-rw-r--r-- | src/character.hpp | 3 | ||||
-rw-r--r-- | src/chunk.cpp | 5 | ||||
-rw-r--r-- | src/chunk.hpp | 5 | ||||
-rw-r--r-- | src/entity.cpp | 31 | ||||
-rw-r--r-- | src/entity.hpp | 7 | ||||
-rw-r--r-- | src/scenery.cpp | 4 | ||||
-rw-r--r-- | src/scenery.hpp | 2 | ||||
-rw-r--r-- | src/world.cpp | 8 | ||||
-rw-r--r-- | src/world.hpp | 8 | ||||
-rw-r--r-- | test/json.cpp | 3 | ||||
-rw-r--r-- | test/tile-iter.cpp | 6 |
13 files changed, 56 insertions, 48 deletions
diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index 83a77ffb..07dc1bbf 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -125,15 +125,15 @@ void reader_state::read_chunks(reader_t& s) std::decay_t<decltype(chunk_magic)> magic; magic << s; if (magic != chunk_magic) - fm_throw("bad chunk magic"_cf); - chunk_coords coord; - coord.x << s; - coord.y << s; - auto& chunk = (*_world)[coord]; + fm_throw("bad c magic"_cf); + chunk_coords ch; + ch.x << s; + ch.y << s; + auto& c = (*_world)[ch]; for (auto i = 0_uz; i < TILE_COUNT; i++) { const tilemeta flags = s.read<tilemeta>(); - tile_ref t = chunk[i]; + tile_ref t = c[i]; using uchar = std::uint8_t; const auto make_atlas = [&]() -> tile_image_proto { auto id = flags & meta_short_atlasid ? atlasid{s.read<uchar>()} : s.read<atlasid>(); @@ -195,12 +195,12 @@ void reader_state::read_chunks(reader_t& s) sc.delta = (std::uint16_t)Math::clamp(int(s.read<float>() * 65535), 0, 65535); } } - - auto e = _world->make_entity<scenery>({ coord, local_coords{i} }, sc); - chunk.add_entity_unsorted(e); + global_coords coord{ch, local_coords{i}}; + auto e = _world->make_entity<scenery>(coord, sc); + c.add_entity_unsorted(e); } } - chunk.sort_entities(); + c.sort_entities(); } } diff --git a/src/character.cpp b/src/character.cpp index a0bfbbd6..7293fddc 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -51,7 +51,7 @@ constexpr auto arrows_to_dir(bool L, bool R, bool U, bool D) } // namespace -character::character(std::uint64_t id, struct world& w, entity_type type) : entity{id, w, type} +character::character(std::uint64_t id, struct chunk& c, entity_type type) : entity{id, c, type} { atlas = loader.anim_atlas("npc-walk", loader.ANIM_PATH); bbox_size = {12, 12}; diff --git a/src/character.hpp b/src/character.hpp index d69b98dc..1733c2dd 100644 --- a/src/character.hpp +++ b/src/character.hpp @@ -18,12 +18,11 @@ struct character final : entity private: int allocate_frame_time(float dt); static Vector2 move_vec(int left_right, int top_bottom); - character(std::uint64_t id, struct world& w, entity_type type); friend struct world; + character(std::uint64_t id, struct chunk& c, entity_type type); Vector2s offset_frac; - bool b_L : 1 = false, b_R : 1 = false, b_U : 1 = false, b_D : 1 = false; }; diff --git a/src/chunk.cpp b/src/chunk.cpp index 6edced05..7f8623dc 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -89,7 +89,10 @@ void chunk::mark_modified() noexcept mark_scenery_modified(); } -chunk::chunk() noexcept = default; +chunk::chunk(struct world& w) noexcept : _world{&w} +{ +} + chunk::~chunk() noexcept { _teardown = true; diff --git a/src/chunk.hpp b/src/chunk.hpp index 9f4e2ebd..83764d87 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -50,7 +50,7 @@ struct chunk final bool empty(bool force = false) const noexcept; - chunk() noexcept; + chunk(struct world& w) noexcept; ~chunk() noexcept; chunk(const chunk&) = delete; chunk& operator=(const chunk&) = delete; @@ -102,6 +102,8 @@ struct chunk final const RTree* rtree() const noexcept; RTree* rtree() noexcept; + struct world& world() noexcept { return *_world; } + template<typename F> requires requires(F fun) { fun(); } void with_scenery_update(entity& e, F&& fun); @@ -129,6 +131,7 @@ private: std::vector<std::array<UnsignedShort, 6>> scenery_indexes; std::vector<std::array<vertex, 4>> scenery_vertexes; + struct world* _world; GL::Mesh ground_mesh{NoCreate}, wall_mesh{NoCreate}, scenery_mesh{NoCreate}; RTree _rtree; diff --git a/src/entity.cpp b/src/entity.cpp index 3cfea061..9f70a5b3 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -13,13 +13,13 @@ entity_proto::~entity_proto() noexcept = default; entity_proto::entity_proto() = default; entity_proto::entity_proto(const entity_proto&) = default; -entity::entity(std::uint64_t id, struct world& w, entity_type type) noexcept : - id{id}, w{w}, type{type} +entity::entity(std::uint64_t id, struct chunk& c, entity_type type) noexcept : + id{id}, c{c}, type{type} { } -entity::entity(std::uint64_t id, struct world& w, entity_type type, const entity_proto& proto) noexcept : - id{id}, w{w}, atlas{proto.atlas}, +entity::entity(std::uint64_t id, struct chunk& c, entity_type type, const entity_proto& proto) noexcept : + id{id}, c{c}, atlas{proto.atlas}, offset{proto.offset}, bbox_offset{proto.bbox_offset}, bbox_size{proto.bbox_size}, delta{proto.delta}, frame{proto.frame}, type{type}, r{proto.r}, pass{proto.pass} @@ -30,17 +30,14 @@ entity::entity(std::uint64_t id, struct world& w, entity_type type, const entity entity::~entity() noexcept { fm_debug_assert(id); - if (w.is_teardown()) [[unlikely]] + if (c._teardown || c._world->_teardown) [[unlikely]] return; - auto& c = chunk(); - if (!c._teardown) [[likely]] - { - if (chunk::bbox bb; c._bbox_for_scenery(*this, bb)) - c._remove_bbox(bb); - auto it = std::find_if(c._entities.cbegin(), c._entities.cend(), [id = id](const auto& x) { return x->id == id; }); - fm_debug_assert(it != c._entities.cend()); - c._entities.erase(it); - } + auto& w = *c._world; + if (chunk::bbox bb; c._bbox_for_scenery(*this, bb)) + c._remove_bbox(bb); + auto it = std::find_if(c._entities.cbegin(), c._entities.cend(), [id = id](const auto& x) { return x->id == id; }); + fm_debug_assert(it != c._entities.cend()); + c._entities.erase(it); w.do_kill_entity(id); } @@ -63,7 +60,7 @@ std::uint32_t entity::ordinal(local_coords xy, Vector2b offset) struct chunk& entity::chunk() const { - return w[coord.chunk()]; + return c; } auto entity::iter() const -> It @@ -84,6 +81,7 @@ bool entity::operator==(const entity_proto& o) const void entity::rotate(It, struct chunk&, rotation new_r) { + auto& w = *c._world; w[coord.chunk()].with_scenery_update(*this, [&]() { bbox_offset = rotate_point(bbox_offset, r, new_r); bbox_size = rotate_size(bbox_size, r, new_r); @@ -116,6 +114,7 @@ Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vect bool entity::can_move_to(Vector2i delta, struct chunk& c) { auto [coord_, offset_] = normalize_coords(coord, offset, delta); + auto& w = *c._world; auto& c_ = coord.chunk() == coord_.chunk() ? c : w[coord_.chunk()]; const auto center = Vector2(coord_.local())*TILE_SIZE2 + Vector2(offset_) + Vector2(bbox_offset), @@ -137,7 +136,7 @@ void entity::move(It it, Vector2i delta, struct chunk& c) { auto e_ = *it; auto& e = *e_; - auto& w = e.w; + auto& w = *c._world; auto& coord = e.coord; auto& offset = e.offset; auto& es = c._entities; diff --git a/src/entity.hpp b/src/entity.hpp index 18c588bd..34aec0af 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -11,6 +11,7 @@ namespace floormat { template<typename T> struct entity_type_; struct anim_atlas; struct world; +struct chunk; enum class entity_type : std::uint8_t { none, character, scenery, @@ -41,7 +42,7 @@ struct entity using It = typename std::vector<std::shared_ptr<entity>>::const_iterator; const std::uint64_t id = 0; - world& w; + struct chunk& c; std::shared_ptr<anim_atlas> atlas; global_coords coord; Vector2b offset, bbox_offset; @@ -73,8 +74,8 @@ struct entity friend struct world; protected: - entity(std::uint64_t id, struct world& w, entity_type type) noexcept; - entity(std::uint64_t id, struct world& w, entity_type type, const entity_proto& proto) noexcept; + entity(std::uint64_t id, struct chunk& c, entity_type type) noexcept; + entity(std::uint64_t id, struct chunk& c, entity_type type, const entity_proto& proto) noexcept; }; } // namespace floormat diff --git a/src/scenery.cpp b/src/scenery.cpp index cf58a8de..8808d7ed 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -92,8 +92,8 @@ bool scenery::operator==(const entity_proto& e0) const closing == s0.closing && interactive == s0.interactive; } -scenery::scenery(std::uint64_t id, struct world& w, entity_type type, const scenery_proto& proto) : - entity{id, w, type}, sc_type{proto.sc_type}, active{proto.active}, +scenery::scenery(std::uint64_t id, struct chunk& c, entity_type type, const scenery_proto& proto) : + entity{id, c, type}, sc_type{proto.sc_type}, active{proto.active}, closing{proto.closing}, interactive{proto.interactive} { fm_assert(type == proto.type); diff --git a/src/scenery.hpp b/src/scenery.hpp index 6f8afadd..dfc0e416 100644 --- a/src/scenery.hpp +++ b/src/scenery.hpp @@ -47,7 +47,7 @@ struct scenery final : entity private: friend struct world; - scenery(std::uint64_t id, struct world& w, entity_type type, const scenery_proto& proto); + scenery(std::uint64_t id, struct chunk& c, entity_type type, const scenery_proto& proto); }; template<> struct entity_type_<scenery> : std::integral_constant<entity_type, entity_type::scenery> {}; diff --git a/src/world.cpp b/src/world.cpp index f50853cf..37b78616 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -32,7 +32,7 @@ chunk& world::operator[](chunk_coords coord) noexcept { auto& [c, coord2] = _last_chunk; if (coord != coord2) - c = &_chunks.try_emplace(coord).first->second; + c = &_chunks.try_emplace(coord, *this).first->second; coord2 = coord; return *c; } @@ -88,14 +88,14 @@ void world::collect(bool force) static constexpr std::uint64_t min_id = 1u << 16; std::uint64_t world::entity_counter = min_id; -void world::do_make_entity(const std::shared_ptr<entity>& e, global_coords pos) +void world::do_make_entity(const std::shared_ptr<entity>& e, chunk& c, global_coords pos) { - fm_debug_assert(e->id > min_id && &e->w == this); + fm_debug_assert(e->id > min_id && &c.world() == this); fm_assert(Vector2ui(e->bbox_size).product() > 0); fm_assert(e->type != entity_type::none); e->coord = pos; _entities[e->id] = e; - operator[](pos.chunk()).add_entity(e); + c.add_entity(e); } void world::do_kill_entity(std::uint64_t id) diff --git a/src/world.hpp b/src/world.hpp index 6781ee3c..5da700e3 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -37,7 +37,7 @@ private: explicit world(std::size_t capacity); - void do_make_entity(const std::shared_ptr<entity>& e, global_coords pos); + void do_make_entity(const std::shared_ptr<entity>& e, chunk& c, global_coords pos); void do_kill_entity(std::uint64_t id); friend struct entity; @@ -67,12 +67,12 @@ public: std::size_t collect_threshold() const noexcept { return _collect_every; } template<typename T, typename... Xs> - requires requires { T{std::uint64_t(), std::declval<world&>(), entity_type(), std::declval<Xs>()...}; } + requires requires(chunk& c) { T{std::uint64_t(), c, entity_type(), std::declval<Xs>()...}; } std::shared_ptr<T> make_entity(global_coords pos, Xs&&... xs) { static_assert(std::is_base_of_v<entity, T>); - auto ret = std::shared_ptr<T>(new T{++entity_counter, *this, entity_type_<T>::value, std::forward<Xs>(xs)...}); - do_make_entity(std::static_pointer_cast<entity>(ret), pos); + auto ret = std::shared_ptr<T>(new T{++entity_counter, operator[](pos.chunk()), entity_type_<T>::value, std::forward<Xs>(xs)...}); + do_make_entity(std::static_pointer_cast<entity>(ret), ret->c, pos); return ret; } diff --git a/test/json.cpp b/test/json.cpp index 60e464f6..349219b1 100644 --- a/test/json.cpp +++ b/test/json.cpp @@ -20,7 +20,8 @@ static chunk make_test_chunk() metal2 = loader.tile_atlas("metal2", {2, 2}, pass_mode::blocked), tiles = loader.tile_atlas("tiles", {8, 5}, pass_mode::pass); constexpr auto N = TILE_MAX_DIM; - chunk c; + world w; + chunk c{w}; for (auto [x, k, pt] : c) { x.ground() = { tiles, variant_t(k % tiles->num_tiles()) }; } diff --git a/test/tile-iter.cpp b/test/tile-iter.cpp index 9d31fd49..7b9eafbf 100644 --- a/test/tile-iter.cpp +++ b/test/tile-iter.cpp @@ -12,7 +12,8 @@ void test_app::test_tile_iter() // NOLINT(readability-function-size) { if (always_false()) { - const chunk c; + world w; + const chunk c{w}; for ([[maybe_unused]] const auto& [x, k, pt] : c) static_assert(std::is_same_v<decltype(x), const tile_proto>); for ([[maybe_unused]] const auto [x, k, pt] : c) @@ -22,7 +23,8 @@ void test_app::test_tile_iter() // NOLINT(readability-function-size) } if (always_false()) { - chunk c; + world w; + chunk c{w}; for ([[maybe_unused]] auto [x, k, pt] : c) static_assert(std::is_same_v<decltype(x), tile_ref>); for ([[maybe_unused]] const auto [x, k, pt] : c) |