diff options
Diffstat (limited to 'src')
-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 |
10 files changed, 40 insertions, 35 deletions
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; } |