summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--serialize/world-reader.cpp20
-rw-r--r--src/character.cpp2
-rw-r--r--src/character.hpp3
-rw-r--r--src/chunk.cpp5
-rw-r--r--src/chunk.hpp5
-rw-r--r--src/entity.cpp31
-rw-r--r--src/entity.hpp7
-rw-r--r--src/scenery.cpp4
-rw-r--r--src/scenery.hpp2
-rw-r--r--src/world.cpp8
-rw-r--r--src/world.hpp8
-rw-r--r--test/json.cpp3
-rw-r--r--test/tile-iter.cpp6
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)