diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/anim-atlas.hpp | 5 | ||||
-rw-r--r-- | src/chunk-collision.cpp | 22 | ||||
-rw-r--r-- | src/chunk-render.cpp | 1 | ||||
-rw-r--r-- | src/chunk-walls.cpp | 1 | ||||
-rw-r--r-- | src/chunk.cpp | 43 | ||||
-rw-r--r-- | src/chunk.hpp | 34 | ||||
-rw-r--r-- | src/critter-script-empty.cpp | 12 | ||||
-rw-r--r-- | src/critter-script-walk.cpp | 20 | ||||
-rw-r--r-- | src/critter-script.hpp | 7 | ||||
-rw-r--r-- | src/critter.cpp | 13 | ||||
-rw-r--r-- | src/critter.hpp | 6 | ||||
-rw-r--r-- | src/ground-atlas.cpp | 4 | ||||
-rw-r--r-- | src/ground-atlas.hpp | 10 | ||||
-rw-r--r-- | src/hole.cpp | 2 | ||||
-rw-r--r-- | src/hole.hpp | 2 | ||||
-rw-r--r-- | src/light.cpp | 2 | ||||
-rw-r--r-- | src/light.hpp | 2 | ||||
-rw-r--r-- | src/object.cpp | 5 | ||||
-rw-r--r-- | src/object.hpp | 18 | ||||
-rw-r--r-- | src/scenery.cpp | 4 | ||||
-rw-r--r-- | src/scenery.hpp | 4 | ||||
-rw-r--r-- | src/script.hpp | 12 | ||||
-rw-r--r-- | src/script.inl | 14 | ||||
-rw-r--r-- | src/tile-image.cpp | 3 | ||||
-rw-r--r-- | src/tile-image.hpp | 8 | ||||
-rw-r--r-- | src/tile.cpp | 14 | ||||
-rw-r--r-- | src/tile.hpp | 17 | ||||
-rw-r--r-- | src/wall-atlas.hpp | 5 | ||||
-rw-r--r-- | src/world.cpp | 64 | ||||
-rw-r--r-- | src/world.hpp | 30 |
30 files changed, 201 insertions, 183 deletions
diff --git a/src/anim-atlas.hpp b/src/anim-atlas.hpp index 2803566f..cf9937ba 100644 --- a/src/anim-atlas.hpp +++ b/src/anim-atlas.hpp @@ -3,6 +3,7 @@ #include "rotation.hpp" #include "anim.hpp" #include "src/quads.hpp" +#include "compat/borrowed-ptr.hpp" #include <array> #include <Corrade/Containers/BitArray.h> #include <Corrade/Containers/String.h> @@ -12,7 +13,7 @@ namespace floormat { -class anim_atlas final +class anim_atlas final : public bptr_base { using texcoords = Quads::texcoords; using quad = Quads::quad; @@ -31,7 +32,7 @@ class anim_atlas final public: anim_atlas() noexcept; anim_atlas(String name, const ImageView2D& tex, anim_def info); - ~anim_atlas() noexcept; + ~anim_atlas() noexcept override; anim_atlas(anim_atlas&&) noexcept; anim_atlas& operator=(anim_atlas&&) noexcept; diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp index a393554e..ec6f4ff2 100644 --- a/src/chunk-collision.cpp +++ b/src/chunk-collision.cpp @@ -41,7 +41,7 @@ bool add_holes_from_chunk(chunk::RTree& rtree, chunk& c, Vector2b chunk_offset) constexpr auto max_bbox_size = Vector2i{0x100}; constexpr auto chunk_min = -iTILE_SIZE2/2 - max_bbox_size/2, chunk_max = TILE_MAX_DIM * iTILE_SIZE2 - iTILE_SIZE2 / 2 + max_bbox_size; - for (const std::shared_ptr<object>& eʹʹ : c.objects()) + for (const bptr<object>& eʹʹ : c.objects()) { auto& eʹ = *eʹʹ; if (eʹ.type() != object_type::hole) [[likely]] @@ -185,7 +185,7 @@ void chunk::ensure_passability() noexcept filter_through_holes(*_rtree, id, min, max, has_holes); } } - for (const std::shared_ptr<object>& eʹ : objects()) + for (const bptr<object>& eʹ : objects()) { if (eʹ->updates_passability()) continue; @@ -215,19 +215,19 @@ bool chunk::_bbox_for_scenery(const object& s, bbox& value) noexcept return _bbox_for_scenery(s, s.coord.local(), s.offset, s.bbox_offset, s.bbox_size, value); } -void chunk::_remove_bbox_static_(const std::shared_ptr<object>& e) +void chunk::_remove_bbox_static_(const bptr<object>& e) { mark_passability_modified(); e->maybe_mark_neighbor_chunks_modified(); } -void chunk::_add_bbox_static_(const std::shared_ptr<object>& e) +void chunk::_add_bbox_static_(const bptr<object>& e) { mark_passability_modified(); e->maybe_mark_neighbor_chunks_modified(); } -void chunk::_remove_bbox_(const std::shared_ptr<object>& e, const bbox& x, bool upd, bool is_dynamic) +void chunk::_remove_bbox_(const bptr<object>& e, const bbox& x, bool upd, bool is_dynamic) { if (!is_dynamic || upd) _remove_bbox_static(e, x); @@ -242,7 +242,7 @@ void chunk::_remove_bbox_dynamic(const bbox& x) //Debug{} << "bbox <<< dynamic" << x.data.pass << x.data.data << x.start << x.end << _rtree->Count(); } -void chunk::_remove_bbox_static(const std::shared_ptr<object>& e, [[maybe_unused]] const bbox& x) +void chunk::_remove_bbox_static(const bptr<object>& e, [[maybe_unused]] const bbox& x) { _remove_bbox_static_(e); //Debug{} << "bbox <<< static " << x.data.pass << x.data.data << x.start << x.end << _rtree->Count(); @@ -255,13 +255,13 @@ void chunk::_add_bbox_dynamic(const bbox& x) //Debug{} << "bbox >>> dynamic" << x.data.pass << x.data.data << x.start << x.end << _rtree->Count(); } -void chunk::_add_bbox_static(const std::shared_ptr<object>& e, [[maybe_unused]]const bbox& x) +void chunk::_add_bbox_static(const bptr<object>& e, [[maybe_unused]]const bbox& x) { _add_bbox_static_(e); //Debug{} << "bbox >>> static " << x.data.pass << x.data.data << x.start << x.end << _rtree->Count(); } -void chunk::_add_bbox_(const std::shared_ptr<object>& e, const bbox& x, bool upd, bool is_dynamic) +void chunk::_add_bbox_(const bptr<object>& e, const bbox& x, bool upd, bool is_dynamic) { if (!is_dynamic || upd) _add_bbox_static(e, x); @@ -270,7 +270,7 @@ void chunk::_add_bbox_(const std::shared_ptr<object>& e, const bbox& x, bool upd } template<bool Dynamic> -void chunk::_replace_bbox_impl(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x1, bool b0, bool b1) +void chunk::_replace_bbox_impl(const bptr<object>& e, const bbox& x0, const bbox& x1, bool b0, bool b1) { if (_pass_modified) return; @@ -313,12 +313,12 @@ void chunk::_replace_bbox_dynamic(const bbox& x0, const bbox& x, bool b0, bool b _replace_bbox_impl<true>(nullptr, x0, x, b0, b); } -void chunk::_replace_bbox_static(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b) +void chunk::_replace_bbox_static(const bptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b) { _replace_bbox_impl<false>(e, x0, x, b0, b); } -void chunk::_replace_bbox_(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b, bool upd, bool is_dynamic) +void chunk::_replace_bbox_(const bptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b, bool upd, bool is_dynamic) { if (!is_dynamic || upd) _replace_bbox_static(e, x0, x, b0, b); diff --git a/src/chunk-render.cpp b/src/chunk-render.cpp index a2e1032a..421d98d2 100644 --- a/src/chunk-render.cpp +++ b/src/chunk-render.cpp @@ -3,6 +3,7 @@ #include "ground-atlas.hpp" #include "quads.hpp" #include "shaders/shader.hpp" +#include "compat/borrowed-ptr.inl" #include <algorithm> #include <Corrade/Containers/Array.h> #include <Corrade/Containers/ArrayViewStl.h> diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp index fb4b6560..b3ed0d8c 100644 --- a/src/chunk-walls.cpp +++ b/src/chunk-walls.cpp @@ -3,6 +3,7 @@ #include "quads.hpp" #include "wall-atlas.hpp" #include "shaders/shader.hpp" +#include "compat/borrowed-ptr.inl" #include <Corrade/Containers/ArrayViewStl.h> #include <Corrade/Containers/Pair.h> #include <Corrade/Containers/Optional.h> diff --git a/src/chunk.cpp b/src/chunk.cpp index 2ecf668b..ac529090 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -4,6 +4,7 @@ #include "log.hpp" #include "RTree.h" #include "compat/non-const.hpp" +#include "ground-atlas.hpp" #include <algorithm> #include <cr/GrowableArray.h> #include <cr/Optional.h> @@ -136,7 +137,7 @@ void chunk::sort_objects() std::sort(_objects.begin(), _objects.end(), object_id_lessp); } -void chunk::add_object_pre(const std::shared_ptr<object>& e) +void chunk::add_object_pre(const bptr<object>& e) { fm_assert(!e->gone); fm_assert(&*e->c == this); @@ -152,7 +153,7 @@ void chunk::add_object_pre(const std::shared_ptr<object>& e) } } -void chunk::add_object_unsorted(const std::shared_ptr<object>& e) +void chunk::add_object_unsorted(const bptr<object>& e) { add_object_pre(e); _objects_sorted = false; @@ -160,7 +161,7 @@ void chunk::add_object_unsorted(const std::shared_ptr<object>& e) arrayAppend(_objects, e); } -size_t chunk::add_objectʹ(const std::shared_ptr<object>& e) +size_t chunk::add_objectʹ(const bptr<object>& e) { fm_assert(_objects_sorted); add_object_pre(e); @@ -172,7 +173,7 @@ size_t chunk::add_objectʹ(const std::shared_ptr<object>& e) return i; } -void chunk::add_object(const std::shared_ptr<object>& e) { (void)add_objectʹ(e); } +void chunk::add_object(const bptr<object>& e) { (void)add_objectʹ(e); } void chunk::on_teardown() // NOLINT(*-make-member-function-const) { @@ -186,26 +187,30 @@ void chunk::remove_object(size_t i) fm_assert(_objects_sorted); fm_debug_assert(i < _objects.size()); - const auto& eʹ = _objects[i]; - auto& e = *eʹ; - fm_assert(e.c == this); - fm_assert(!e.gone); - - const auto dyn = e.is_dynamic(), upd = e.updates_passability(); - if (!dyn) - mark_scenery_modified(); - - if (!_pass_modified) [[likely]] + auto eʹ = _objects[i]; { - if (!dyn || upd) - _remove_bbox_static_(eʹ); - else if (bbox bb; _bbox_for_scenery(e, bb)) - _remove_bbox_dynamic(bb); + auto& e = *eʹ; + fm_assert(e.c == this); + fm_assert(!e.gone); + + const auto dyn = e.is_dynamic(), upd = e.updates_passability(); + if (!dyn) + mark_scenery_modified(); + + if (!_pass_modified) [[likely]] + { + if (!dyn || upd) + _remove_bbox_static_(eʹ); + else if (bbox bb; _bbox_for_scenery(e, bb)) + _remove_bbox_dynamic(bb); + } + } arrayRemove(_objects, i); + //eʹ.destroy(); } -ArrayView<const std::shared_ptr<object>> chunk::objects() const +ArrayView<const bptr<object>> chunk::objects() const { fm_assert(_objects_sorted); return _objects; diff --git a/src/chunk.hpp b/src/chunk.hpp index e429f2de..cf41a970 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -102,7 +102,7 @@ public: void on_teardown(); bool is_teardown() const; - ArrayView<const std::shared_ptr<object>> objects() const; + ArrayView<const bptr<object>> objects() const; void remove_object(size_t i); void sort_objects(); @@ -117,21 +117,21 @@ public: private: struct ground_stuff { - std::array<std::shared_ptr<ground_atlas>, TILE_COUNT> atlases; + std::array<bptr<ground_atlas>, TILE_COUNT> atlases; std::array<uint8_t, TILE_COUNT> indexes = {}; std::array<variant_t, TILE_COUNT> variants = {}; }; struct wall_stuff { - std::array<std::shared_ptr<wall_atlas>, 2*TILE_COUNT> atlases; + std::array<bptr<wall_atlas>, 2*TILE_COUNT> atlases; std::array<variant_t, 2*TILE_COUNT> variants; std::array<uint_fast16_t, max_wall_quad_count> mesh_indexes; }; Pointer<ground_stuff> _ground; Pointer<wall_stuff> _walls; - Array<std::shared_ptr<object>> _objects; + Array<bptr<object>> _objects; class world* _world; GL::Mesh ground_mesh{NoCreate}, wall_mesh{NoCreate}, scenery_mesh{NoCreate}; Pointer<RTree> _rtree; @@ -147,10 +147,10 @@ private: void ensure_scenery_buffers(scenery_scratch_buffers bufs); - void add_object(const std::shared_ptr<object>& e); - void add_object_pre(const std::shared_ptr<object>& e); - [[nodiscard]] size_t add_objectʹ(const std::shared_ptr<object>& e); - void add_object_unsorted(const std::shared_ptr<object>& e); + void add_object(const bptr<object>& e); + void add_object_pre(const bptr<object>& e); + [[nodiscard]] size_t add_objectʹ(const bptr<object>& e); + void add_object_unsorted(const bptr<object>& e); struct bbox final { @@ -164,20 +164,20 @@ private: [[nodiscard]] static bool _bbox_for_scenery(const object& s, local_coords local, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size, bbox& value) noexcept; - void _remove_bbox_(const std::shared_ptr<object>& e, const bbox& x, bool upd, bool is_dynamic); + void _remove_bbox_(const bptr<object>& e, const bbox& x, bool upd, bool is_dynamic); void _remove_bbox_dynamic(const bbox& x); - void _remove_bbox_static(const std::shared_ptr<object>& e, const bbox& x); - void _remove_bbox_static_(const std::shared_ptr<object>& e); + void _remove_bbox_static(const bptr<object>& e, const bbox& x); + void _remove_bbox_static_(const bptr<object>& e); - void _add_bbox_(const std::shared_ptr<object>& e, const bbox& x, bool upd, bool is_dynamic); + void _add_bbox_(const bptr<object>& e, const bbox& x, bool upd, bool is_dynamic); void _add_bbox_dynamic(const bbox& x); - void _add_bbox_static(const std::shared_ptr<object>& e, const bbox& x); - void _add_bbox_static_(const std::shared_ptr<object>& e); + void _add_bbox_static(const bptr<object>& e, const bbox& x); + void _add_bbox_static_(const bptr<object>& e); - template<bool Dynamic> void _replace_bbox_impl(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b); - void _replace_bbox_(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b, bool upd, bool is_dynamic); + template<bool Dynamic> void _replace_bbox_impl(const bptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b); + void _replace_bbox_(const bptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b, bool upd, bool is_dynamic); void _replace_bbox_dynamic(const bbox& x0, const bbox& x, bool b0, bool b); - void _replace_bbox_static(const std::shared_ptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b); + void _replace_bbox_static(const bptr<object>& e, const bbox& x0, const bbox& x, bool b0, bool b); GL::Mesh make_wall_mesh(); diff --git a/src/critter-script-empty.cpp b/src/critter-script-empty.cpp index 73a714ca..7c269aa4 100644 --- a/src/critter-script-empty.cpp +++ b/src/critter-script-empty.cpp @@ -10,9 +10,9 @@ struct empty_critter_script final : critter_script StringView name() const override; const void* id() const override; - void on_init(const std::shared_ptr<critter>& c) override; - void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) override; - void on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason) override; + void on_init(const bptr<critter>& c) override; + void on_update(const bptr<critter>& c, size_t& i, const Ns& dt) override; + void on_destroy(const bptr<critter>& c, script_destroy_reason reason) override; void delete_self() noexcept override; }; @@ -28,9 +28,9 @@ const void* empty_critter_script::id() const return &script_name; } -void empty_critter_script::on_init(const std::shared_ptr<critter>&) {} -void empty_critter_script::on_update(const std::shared_ptr<critter>&, size_t&, const Ns&) {} -void empty_critter_script::on_destroy(const std::shared_ptr<critter>&, script_destroy_reason) {} +void empty_critter_script::on_init(const bptr<critter>&) {} +void empty_critter_script::on_update(const bptr<critter>&, size_t&, const Ns&) {} +void empty_critter_script::on_destroy(const bptr<critter>&, script_destroy_reason) {} void empty_critter_script::delete_self() noexcept { } constinit empty_critter_script empty_script_ = {}; diff --git a/src/critter-script-walk.cpp b/src/critter-script-walk.cpp index a10cf15d..2402fe74 100644 --- a/src/critter-script-walk.cpp +++ b/src/critter-script-walk.cpp @@ -23,16 +23,16 @@ struct walk_script final : critter_script StringView name() const override; const void* id() const override; - void on_init(const std::shared_ptr<critter>& c) override; - void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) override; - void on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason) override; + void on_init(const bptr<critter>& c) override; + void on_update(const bptr<critter>& c, size_t& i, const Ns& dt) override; + void on_destroy(const bptr<critter>& c, script_destroy_reason reason) override; void delete_self() noexcept override; explicit walk_script(point dest); explicit walk_script(psr path); - bool walk_line(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt); - bool walk_path(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt); + bool walk_line(const bptr<critter>& c, size_t& i, const Ns& dt); + bool walk_path(const bptr<critter>& c, size_t& i, const Ns& dt); private: point dest; @@ -43,10 +43,10 @@ private: StringView walk_script::name() const { return "walk"_s; } const void* walk_script::id() const { return &script_name; } -void walk_script::on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason) { c->clear_auto_movement(); } +void walk_script::on_destroy(const bptr<critter>& c, script_destroy_reason) { c->clear_auto_movement(); } void walk_script::delete_self() noexcept { delete this; } -void walk_script::on_init(const std::shared_ptr<critter>& c) +void walk_script::on_init(const bptr<critter>& c) { Debug{} << "| start walking from" << c->position() << "to" << dest; c->moves.AUTO = true; @@ -65,7 +65,7 @@ void walk_script::on_init(const std::shared_ptr<critter>& c) } } -void walk_script::on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) +void walk_script::on_update(const bptr<critter>& c, size_t& i, const Ns& dt) { if (c->maybe_stop_auto_movement()) goto done; @@ -104,14 +104,14 @@ walk_script::walk_script(psr pathʹ) : fm_assert(!path.empty()); } -bool walk_script::walk_line(const std::shared_ptr<critter>& c, size_t& i, const Ns& dtʹ) +bool walk_script::walk_line(const bptr<critter>& c, size_t& i, const Ns& dtʹ) { auto dt = dtʹ; auto res = c->move_toward(i, dt, dest); return res.blocked || c->position() == dest; } -bool walk_script::walk_path(const std::shared_ptr<critter>& c, size_t& i, const Ns& dtʹ) +bool walk_script::walk_path(const bptr<critter>& c, size_t& i, const Ns& dtʹ) { auto dt = dtʹ; while (dt != Ns{}) diff --git a/src/critter-script.hpp b/src/critter-script.hpp index 2b81a939..9f81228b 100644 --- a/src/critter-script.hpp +++ b/src/critter-script.hpp @@ -1,6 +1,5 @@ #pragma once #include "script.hpp" -#include <memory> #include <cr/Pointer.h> namespace floormat { @@ -16,9 +15,9 @@ struct critter_script : base_script constexpr critter_script() noexcept = default; ~critter_script() noexcept override; - virtual void on_init(const std::shared_ptr<critter>& c) = 0; - virtual void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) = 0; - virtual void on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason) = 0; + virtual void on_init(const bptr<critter>& c) = 0; + virtual void on_update(const bptr<critter>& c, size_t& i, const Ns& dt) = 0; + virtual void on_destroy(const bptr<critter>& c, script_destroy_reason reason) = 0; virtual void delete_self() = 0; object_type type() const override; diff --git a/src/critter.cpp b/src/critter.cpp index a05ea06f..b107394d 100644 --- a/src/critter.cpp +++ b/src/critter.cpp @@ -12,6 +12,7 @@ #include "compat/map.hpp" #include "compat/iota.hpp" #include "compat/exception.hpp" +#include "compat/borrowed-ptr.inl" #include <cmath> #include <utility> #include <array> @@ -393,12 +394,12 @@ Vector2 critter::ordinal_offset(Vector2b offset) const return Vector2(offset); } -void critter::update(const std::shared_ptr<object>& ptrʹ, size_t& i, const Ns& dt) +void critter::update(const bptr<object>& ptrʹ, size_t& i, const Ns& dt) { fm_debug_assert(&*ptrʹ == this); check_script_update_1(script.state()); - script->on_update(std::static_pointer_cast<critter>(ptrʹ), i, dt); + script->on_update(static_pointer_cast<critter>(ptrʹ), i, dt); #if 0 // for now, objects can't delete themselves if (check_script_update_2(script.state())) [[unlikely]] return; @@ -566,14 +567,14 @@ critter::~critter() noexcept { } -void critter::init_script(const std::shared_ptr<object>& ptrʹ) +void critter::init_script(const bptr<object>& ptrʹ) { - script.do_initialize(std::static_pointer_cast<critter>(ptrʹ)); + script.do_initialize(static_pointer_cast<critter>(ptrʹ)); } -void critter::destroy_script_pre(const std::shared_ptr<object>& ptrʹ, script_destroy_reason r) +void critter::destroy_script_pre(const bptr<object>& ptrʹ, script_destroy_reason r) { - script.do_destroy_pre(std::static_pointer_cast<critter>(ptrʹ), r); + script.do_destroy_pre(static_pointer_cast<critter>(ptrʹ), r); } void critter::destroy_script_post() diff --git a/src/critter.hpp b/src/critter.hpp index 38b5addf..e95bf065 100644 --- a/src/critter.hpp +++ b/src/critter.hpp @@ -32,7 +32,7 @@ struct critter final : object object_type type() const noexcept override; explicit operator critter_proto() const; - void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override; + void update(const bptr<object>& ptr, size_t& i, const Ns& dt) override; void update_movement(size_t& i, const Ns& dt, rotation r); struct move_result { bool blocked, moved; }; @@ -41,8 +41,8 @@ struct critter final : object Vector2 ordinal_offset(Vector2b offset) const override; float depth_offset() const override; - void init_script(const std::shared_ptr<object>& ptr) override; - void destroy_script_pre(const std::shared_ptr<object>& ptr, script_destroy_reason r) override; + void init_script(const bptr<object>& ptr) override; + void destroy_script_pre(const bptr<object>& ptr, script_destroy_reason r) override; void destroy_script_post() override; void clear_auto_movement(); diff --git a/src/ground-atlas.cpp b/src/ground-atlas.cpp index 726ec557..f78d53be 100644 --- a/src/ground-atlas.cpp +++ b/src/ground-atlas.cpp @@ -47,10 +47,10 @@ auto ground_atlas::make_texcoords(Vector2ui pixel_size, Vector2ub tile_count, si return texcoords_at(p0, sz, pixel_size); } -auto ground_atlas::make_texcoords_array(Vector2ui pixel_size, Vector2ub tile_count) -> std::unique_ptr<const texcoords[]> +auto ground_atlas::make_texcoords_array(Vector2ui pixel_size, Vector2ub tile_count) -> Array<texcoords> { const size_t N = Vector2ui{tile_count}.product(); - auto ptr = std::make_unique<std::array<Vector2, 4>[]>(N); + auto ptr = Array<texcoords>{NoInit, N}; for (auto i = 0uz; i < N; i++) ptr[i] = make_texcoords(pixel_size, tile_count, i); return ptr; diff --git a/src/ground-atlas.hpp b/src/ground-atlas.hpp index 3fc3a177..5ebdad1f 100644 --- a/src/ground-atlas.hpp +++ b/src/ground-atlas.hpp @@ -1,12 +1,14 @@ #pragma once +#include "compat/borrowed-ptr.hpp" #include "src/pass-mode.hpp" #include "src/quads.hpp" #include "src/ground-def.hpp" #include "loader/ground-cell.hpp" #include <array> -#include <memory> +#include <cr/Array.h> #include <Corrade/Containers/Optional.h> #include <Corrade/Containers/String.h> +#include <cr/Pointer.h> #include <Magnum/Magnum.h> #include <Magnum/Math/Vector2.h> #include <Magnum/GL/Texture.h> @@ -15,18 +17,18 @@ namespace floormat { class ground_atlas; -class ground_atlas final +class ground_atlas final : public bptr_base { using quad = Quads::quad; using texcoords = std::array<Vector2, 4>; - static std::unique_ptr<const texcoords[]> make_texcoords_array(Vector2ui pixel_size, Vector2ub tile_count); + static Array<texcoords> make_texcoords_array(Vector2ui pixel_size, Vector2ub tile_count); static texcoords make_texcoords(Vector2ui pixel_size, Vector2ub tile_count, size_t i); static String make_path(StringView name); ground_def _def; String _path; - std::unique_ptr<const texcoords[]> _texcoords; + Array<texcoords> _texcoords; GL::Texture2D _tex; Vector2ui _pixel_size; diff --git a/src/hole.cpp b/src/hole.cpp index 7a50566d..ad29c752 100644 --- a/src/hole.cpp +++ b/src/hole.cpp @@ -57,7 +57,7 @@ hole::~hole() noexcept return; } -void hole::update(const std::shared_ptr<object>&, size_t&, const Ns&) {} +void hole::update(const bptr<object>&, size_t&, const Ns&) {} hole::operator hole_proto() const { diff --git a/src/hole.hpp b/src/hole.hpp index 25db9886..35fd29d9 100644 --- a/src/hole.hpp +++ b/src/hole.hpp @@ -40,7 +40,7 @@ struct hole final : object Vector2 ordinal_offset(Vector2b offset) const override; float depth_offset() const override; object_type type() const noexcept override; - void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override; + void update(const bptr<object>& ptr, size_t& i, const Ns& dt) override; bool is_dynamic() const override; bool updates_passability() const override; bool is_virtual() const override; diff --git a/src/light.cpp b/src/light.cpp index 647368ec..2c5d1a4f 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -70,7 +70,7 @@ light::operator light_proto() const } object_type light::type() const noexcept { return object_type::light; } -void light::update(const std::shared_ptr<object>&, size_t&, const Ns&) {} +void light::update(const bptr<object>&, size_t&, const Ns&) {} bool light::is_dynamic() const { return true; } bool light::is_virtual() const { return true; } diff --git a/src/light.hpp b/src/light.hpp index a6a22fdb..97c18191 100644 --- a/src/light.hpp +++ b/src/light.hpp @@ -35,7 +35,7 @@ struct light final : object Vector2 ordinal_offset(Vector2b offset) const override; float depth_offset() const override; object_type type() const noexcept override; - void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override; + void update(const bptr<object>& ptr, size_t& i, const Ns& dt) override; bool is_dynamic() const override; bool is_virtual() const override; diff --git a/src/object.cpp b/src/object.cpp index 200179e5..7e686aa9 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -10,6 +10,7 @@ #include "compat/exception.hpp" #include "compat/limits.hpp" #include "compat/non-const.hpp" +#include "compat/borrowed-ptr.inl" #include "nanosecond.inl" #include <cmath> #include <algorithm> @@ -363,8 +364,8 @@ bool object::is_dynamic() const { return atlas->info().fps > 0; } bool object::updates_passability() const { return false; } void object::maybe_mark_neighbor_chunks_modified() {} -void object::init_script(const std::shared_ptr<object>&) {} -void object::destroy_script_pre(const std::shared_ptr<object>&, script_destroy_reason) {} +void object::init_script(const bptr<object>&) {} +void object::destroy_script_pre(const bptr<object>&, script_destroy_reason) {} void object::destroy_script_post() {} void object::check_script_update_1(script_lifecycle state) diff --git a/src/object.hpp b/src/object.hpp index d65f6a67..a73f97b1 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -1,5 +1,6 @@ #pragma once #include "compat/defs.hpp" +#include "compat/borrowed-ptr.hpp" #include "src/global-coords.hpp" #include "src/rotation.hpp" #include "src/pass-mode.hpp" @@ -7,7 +8,6 @@ #include "src/object-id.hpp" #include "src/point.hpp" #include "src/script-enums.hpp" -#include <memory> namespace floormat { @@ -18,7 +18,7 @@ struct Ns; struct object_proto { - std::shared_ptr<anim_atlas> atlas; + bptr<anim_atlas> atlas; Vector2b offset, bbox_offset; Vector2ub bbox_size = Vector2ub(tile_size_xy); uint32_t delta = 0; @@ -39,7 +39,7 @@ struct object_proto object_proto(object_proto&&) noexcept; }; -struct object +struct object : bptr_base { fm_DECLARE_DELETED_COPY_ASSIGNMENT(object); fm_DECLARE_DELETED_MOVE_ASSIGNMENT(object); @@ -47,9 +47,9 @@ struct object const object_id id = 0; uint64_t last_frame_no = 0; class chunk* const c; - const std::shared_ptr<anim_atlas> atlas; + const bptr<anim_atlas> atlas; const global_coords coord; - const std::weak_ptr<object> parent; + const bptr<object> parent; const Vector2b offset, bbox_offset; const Vector2ub bbox_size; uint32_t delta = 0; @@ -60,7 +60,7 @@ struct object bool gone : 1 = false; //char _pad[4]; // got 4 bytes left - virtual ~object() noexcept; + virtual ~object() noexcept override; virtual Vector2 ordinal_offset(Vector2b offset) const = 0; virtual float depth_offset() const = 0; @@ -77,7 +77,7 @@ struct object virtual object_type type() const noexcept = 0; virtual bool can_activate(size_t i) const; virtual bool activate(size_t i); - virtual void update(const std::shared_ptr<object>& self, size_t& i, const Ns& dt) = 0; + virtual void update(const bptr<object>& self, size_t& i, const Ns& dt) = 0; void rotate(size_t i, rotation r); bool can_rotate(global_coords coord, rotation new_r, rotation old_r, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size); bool can_move_to(Vector2i delta, global_coords coord, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_aize); @@ -102,8 +102,8 @@ struct object requires std::is_unsigned_v<T> static uint32_t alloc_frame_time(const Ns& dt, T& accum, uint32_t hz, float speed); - virtual void init_script(const std::shared_ptr<object>& ptr); - virtual void destroy_script_pre(const std::shared_ptr<object>& ptr, script_destroy_reason r); + virtual void init_script(const bptr<object>& ptr); + virtual void destroy_script_pre(const bptr<object>& ptr, script_destroy_reason r); virtual void destroy_script_post(); protected: diff --git a/src/scenery.cpp b/src/scenery.cpp index 7e52c08e..4903afac 100644 --- a/src/scenery.cpp +++ b/src/scenery.cpp @@ -45,7 +45,7 @@ scenery::scenery(object_id id, class chunk& c, const scenery_proto& proto) : // ---------- generic_scenery ---------- -void generic_scenery::update(const std::shared_ptr<object>&, size_t&, const Ns&) {} +void generic_scenery::update(const bptr<object>&, size_t&, const Ns&) {} Vector2 generic_scenery::ordinal_offset(Vector2b offset) const { return Vector2(offset); } bool generic_scenery::can_activate(size_t) const { return interactive; } bool generic_scenery::activate(size_t) { return false; } @@ -74,7 +74,7 @@ generic_scenery::generic_scenery(object_id id, class chunk& c, const generic_sce enum scenery_type door_scenery::scenery_type() const { return scenery_type::door; } -void door_scenery::update(const std::shared_ptr<object>&, size_t&, const Ns& dt) +void door_scenery::update(const bptr<object>&, size_t&, const Ns& dt) { if (!atlas || !active) return; diff --git a/src/scenery.hpp b/src/scenery.hpp index 56675a93..65e32c17 100644 --- a/src/scenery.hpp +++ b/src/scenery.hpp @@ -27,7 +27,7 @@ struct generic_scenery final : scenery bool active : 1 = false; bool interactive : 1 = false; - void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override; + void update(const bptr<object>& ptr, size_t& i, const Ns& dt) override; Vector2 ordinal_offset(Vector2b offset) const override; bool can_activate(size_t i) const override; bool activate(size_t i) override; @@ -47,7 +47,7 @@ struct door_scenery final : scenery bool active : 1 = false; bool interactive : 1 = false; - void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override; + void update(const bptr<object>& ptr, size_t& i, const Ns& dt) override; Vector2 ordinal_offset(Vector2b offset) const override; bool can_activate(size_t i) const override; bool activate(size_t i) override; diff --git a/src/script.hpp b/src/script.hpp index 5461a208..82f16484 100644 --- a/src/script.hpp +++ b/src/script.hpp @@ -1,8 +1,8 @@ #pragma once #include "script-enums.hpp" #include "compat/defs.hpp" +#include "compat/borrowed-ptr.hpp" #include "src/object-type.hpp" -#include <memory> namespace floormat { @@ -54,11 +54,11 @@ public: void do_create(S* ptr); void do_create(Pointer<S> ptr); - void do_initialize(const std::shared_ptr<Obj>& obj); - void do_reassign(S* ptr, const std::shared_ptr<Obj>& obj); - void do_reassign(Pointer<S> ptr, const std::shared_ptr<Obj>& obj); - void do_clear(const std::shared_ptr<Obj>& obj); - void do_destroy_pre(const std::shared_ptr<Obj>& obj, script_destroy_reason r); + void do_initialize(const bptr<Obj>& obj); + void do_reassign(S* ptr, const bptr<Obj>& obj); + void do_reassign(Pointer<S> ptr, const bptr<Obj>& obj); + void do_clear(const bptr<Obj>& obj); + void do_destroy_pre(const bptr<Obj>& obj, script_destroy_reason r); void do_finish_destroy(); void do_ensure_torn_down(); void do_error_unwind(); diff --git a/src/script.inl b/src/script.inl index 27a79e31..92b0e1a6 100644 --- a/src/script.inl +++ b/src/script.inl @@ -5,13 +5,11 @@ #include <cr/StringView.h> #include <cr/Pointer.h> -// ReSharper disable CppDFAUnreachableCode - namespace floormat::detail_Script { template<typename S, typename Obj> concept BaseScript = -requires (S& script, const std::shared_ptr<Obj>& obj, size_t& i, const Ns& ns) +requires (S& script, const bptr<Obj>& obj, size_t& i, const Ns& ns) { requires std::is_base_of_v<base_script, S>; script.on_init(obj); @@ -89,7 +87,7 @@ void Script<S, Obj>::do_create(Pointer<S> p) } template <typename S, typename Obj> -void Script<S, Obj>::do_initialize(const std::shared_ptr<Obj>& obj) +void Script<S, Obj>::do_initialize(const bptr<Obj>& obj) { switch (_state) { @@ -108,7 +106,7 @@ void Script<S, Obj>::do_initialize(const std::shared_ptr<Obj>& obj) } template <typename S, typename Obj> -void Script<S, Obj>::do_reassign(S* p, const std::shared_ptr<Obj>& obj) +void Script<S, Obj>::do_reassign(S* p, const bptr<Obj>& obj) { if (!p) [[unlikely]] return do_clear(obj); @@ -121,13 +119,13 @@ void Script<S, Obj>::do_reassign(S* p, const std::shared_ptr<Obj>& obj) } template <typename S, typename Obj> -void Script<S, Obj>::do_reassign(Pointer<S> p, const std::shared_ptr<Obj>& obj) +void Script<S, Obj>::do_reassign(Pointer<S> p, const bptr<Obj>& obj) { return do_reassign(p.release(), obj); } template <typename S, typename Obj> -void Script<S, Obj>::do_clear(const std::shared_ptr<Obj>& obj) +void Script<S, Obj>::do_clear(const bptr<Obj>& obj) { FM_ASSERT_SCRIPT_STATE(script_lifecycle::created); fm_debug_assert(ptr); @@ -137,7 +135,7 @@ void Script<S, Obj>::do_clear(const std::shared_ptr<Obj>& obj) } template <typename S, typename Obj> -void Script<S, Obj>::do_destroy_pre(const std::shared_ptr<Obj>& obj, script_destroy_reason r) +void Script<S, Obj>::do_destroy_pre(const bptr<Obj>& obj, script_destroy_reason r) { FM_ASSERT_SCRIPT_STATE(script_lifecycle::created); _state = script_lifecycle::destroying; diff --git a/src/tile-image.cpp b/src/tile-image.cpp index e2d84461..20ab4098 100644 --- a/src/tile-image.cpp +++ b/src/tile-image.cpp @@ -1,4 +1,5 @@ #include "tile-image.hpp" +#include "compat/borrowed-ptr.inl" namespace floormat { @@ -17,7 +18,7 @@ image_ref_<Atlas, Proto>::image_ref_(const image_ref_<Atlas, Proto>& o) noexcept {} template<typename Atlas, typename Proto> -image_ref_<Atlas, Proto>::image_ref_(std::shared_ptr<Atlas>& atlas, variant_t& variant) noexcept +image_ref_<Atlas, Proto>::image_ref_(bptr<Atlas>& atlas, variant_t& variant) noexcept : atlas{atlas}, variant{variant} {} diff --git a/src/tile-image.hpp b/src/tile-image.hpp index a25b9fed..475b6251 100644 --- a/src/tile-image.hpp +++ b/src/tile-image.hpp @@ -1,6 +1,6 @@ #pragma once #include "tile-defs.hpp" -#include <memory> +#include "compat/borrowed-ptr.hpp" namespace floormat { @@ -10,7 +10,7 @@ class wall_atlas; template<typename Atlas> struct image_proto_ { - std::shared_ptr<Atlas> atlas; + bptr<Atlas> atlas; variant_t variant = 0; bool operator==(const image_proto_<Atlas>& b) const noexcept; @@ -20,10 +20,10 @@ struct image_proto_ template<typename Atlas, typename Proto> struct image_ref_ final { - std::shared_ptr<Atlas>& atlas; + bptr<Atlas>& atlas; variant_t& variant; - image_ref_(std::shared_ptr<Atlas>& atlas, variant_t& variant) noexcept; + image_ref_(bptr<Atlas>& atlas, variant_t& variant) noexcept; image_ref_(const image_ref_&) noexcept; image_ref_& operator=(const Proto& proto) noexcept; operator Proto() const noexcept; diff --git a/src/tile.cpp b/src/tile.cpp index 89e49017..216783f7 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -1,7 +1,7 @@ #include "tile.hpp" #include "tile-constants.hpp" #include "chunk.hpp" -#include "ground-atlas.hpp" +#include "compat/borrowed-ptr.inl" namespace floormat { @@ -24,13 +24,13 @@ wall_image_proto tile_proto::wall_west() const noexcept { return { wall_west_at tile_ref::tile_ref(class chunk& c, uint8_t i) noexcept : _chunk{&c}, i{i} {} -std::shared_ptr<class ground_atlas> tile_ref::ground_atlas() noexcept { return _chunk->_ground ? _chunk->_ground->atlases[i] : nullptr; } -std::shared_ptr<class wall_atlas> tile_ref::wall_north_atlas() noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+0] : nullptr; } -std::shared_ptr<class wall_atlas> tile_ref::wall_west_atlas() noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+1] : nullptr; } +bptr<class ground_atlas> tile_ref::ground_atlas() noexcept { return _chunk->_ground ? _chunk->_ground->atlases[i] : nullptr; } +bptr<class wall_atlas> tile_ref::wall_north_atlas() noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+0] : nullptr; } +bptr<class wall_atlas> tile_ref::wall_west_atlas() noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+1] : nullptr; } -std::shared_ptr<const class ground_atlas> tile_ref::ground_atlas() const noexcept { return _chunk->_ground ? _chunk->_ground->atlases[i] : nullptr; } -std::shared_ptr<const class wall_atlas> tile_ref::wall_north_atlas() const noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+0] : nullptr; } -std::shared_ptr<const class wall_atlas> tile_ref::wall_west_atlas() const noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+1] : nullptr; } +bptr<const class ground_atlas> tile_ref::ground_atlas() const noexcept { return _chunk->_ground ? _chunk->_ground->atlases[i] : nullptr; } +bptr<const class wall_atlas> tile_ref::wall_north_atlas() const noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+0] : nullptr; } +bptr<const class wall_atlas> tile_ref::wall_west_atlas() const noexcept { return _chunk->_walls ? _chunk->_walls->atlases[i*2+1] : nullptr; } tile_image_ref tile_ref::ground() noexcept { _chunk->ensure_alloc_ground(); return {_chunk->_ground->atlases[i], _chunk->_ground->variants[i] }; } wall_image_ref tile_ref::wall_north() noexcept { _chunk->ensure_alloc_walls(); return {_chunk->_walls->atlases[i*2+0], _chunk->_walls->variants[i*2+0] }; } diff --git a/src/tile.hpp b/src/tile.hpp index 43170fe7..c679b5c0 100644 --- a/src/tile.hpp +++ b/src/tile.hpp @@ -1,5 +1,6 @@ #pragma once #include "tile-image.hpp" +#include "compat/borrowed-ptr.hpp" namespace floormat { @@ -8,8 +9,8 @@ class anim_atlas; struct tile_proto final { - std::shared_ptr<class ground_atlas> ground_atlas; - std::shared_ptr<class wall_atlas> wall_north_atlas, wall_west_atlas; + bptr<class ground_atlas> ground_atlas; + bptr<class wall_atlas> wall_north_atlas, wall_west_atlas; variant_t ground_variant = 0, wall_north_variant = 0, wall_west_variant = 0; tile_image_proto ground() const noexcept; @@ -31,13 +32,13 @@ struct tile_ref final wall_image_proto wall_north() const noexcept; wall_image_proto wall_west() const noexcept; - std::shared_ptr<class ground_atlas> ground_atlas() noexcept; - std::shared_ptr<class wall_atlas> wall_north_atlas() noexcept; - std::shared_ptr<class wall_atlas> wall_west_atlas() noexcept; + bptr<class ground_atlas> ground_atlas() noexcept; + bptr<class wall_atlas> wall_north_atlas() noexcept; + bptr<class wall_atlas> wall_west_atlas() noexcept; - std::shared_ptr<const class ground_atlas> ground_atlas() const noexcept; - std::shared_ptr<const class wall_atlas> wall_north_atlas() const noexcept; - std::shared_ptr<const class wall_atlas> wall_west_atlas() const noexcept; + bptr<const class ground_atlas> ground_atlas() const noexcept; + bptr<const class wall_atlas> wall_north_atlas() const noexcept; + bptr<const class wall_atlas> wall_west_atlas() const noexcept; explicit operator tile_proto() const noexcept; diff --git a/src/wall-atlas.hpp b/src/wall-atlas.hpp index 5cf4f244..e0203165 100644 --- a/src/wall-atlas.hpp +++ b/src/wall-atlas.hpp @@ -1,4 +1,5 @@ #pragma once +#include "compat/borrowed-ptr.hpp" #include "src/rotation.hpp" #include "src/pass-mode.hpp" #include "wall-defs.hpp" @@ -106,7 +107,7 @@ struct wall_atlas_def final std::array<Wall::DirArrayIndex, Wall::Direction_COUNT> dir_map); }; -class wall_atlas final +class wall_atlas final : public bptr_base { using Frame = Wall::Frame; using Group = Wall::Group; @@ -129,7 +130,7 @@ class wall_atlas final public: fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(wall_atlas); wall_atlas() noexcept; - ~wall_atlas() noexcept; + ~wall_atlas() noexcept override; wall_atlas(wall_atlas_def def, String path, const ImageView2D& img); void serialize(StringView filename) const; diff --git a/src/world.cpp b/src/world.cpp index 41e43468..935ca6c4 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -5,7 +5,8 @@ #include "scenery.hpp" #include "scenery-proto.hpp" #include "light.hpp" -#include "compat/shared-ptr-wrapper.hpp" +#include "compat/borrowed-ptr.inl" +#include "compat/weak-borrowed-ptr.inl" #include "compat/hash.hpp" #include "compat/exception.hpp" #include "compat/overloaded.hpp" @@ -26,10 +27,9 @@ size_t world::chunk_coords_hasher::operator()(const chunk_coords_& coord) const } namespace floormat { - -struct world::robin_map_wrapper final : tsl::robin_map<object_id, std::weak_ptr<object>, object_id_hasher> +struct world::robin_map_wrapper final : tsl::robin_map<object_id, weak_bptr<object>, object_id_hasher> { - using tsl::robin_map<object_id, std::weak_ptr<object>, object_id_hasher>::robin_map; + using tsl::robin_map<object_id, weak_bptr<object>, object_id_hasher>::robin_map; }; world::world(world&& w) noexcept = default; @@ -51,11 +51,11 @@ world& world::operator=(world&& w) noexcept _script_finalized = false; fm_assert(!w._teardown); fm_assert(!_teardown); - fm_assert(w._unique_id); _last_chunk = {}; _chunks = move(w._chunks); _objects = move(w._objects); w._objects = {}; + fm_assert(w._unique_id); _unique_id = move(w._unique_id); fm_debug_assert(_unique_id); fm_debug_assert(w._unique_id == nullptr); @@ -78,6 +78,7 @@ world::~world() noexcept for (auto& [k, c] : _chunks) c.on_teardown(); _teardown = true; + _objects->clear(); for (auto& [k, c] : _chunks) { c._teardown = true; @@ -88,10 +89,11 @@ world::~world() noexcept } _last_chunk = {}; _chunks.clear(); - _objects->clear(); } -world::world(size_t capacity) : _chunks{capacity} +bool world::unique_id::operator==(const unique_id& other) const { return this == &other; } + +world::world(size_t capacity) : _chunks{capacity}, _unique_id{InPlace} { _chunks.max_load_factor(max_load_factor); _chunks.reserve(initial_capacity); @@ -162,7 +164,7 @@ void world::collect(bool force) fm_debug("world: collected %zu/%zu chunks", len, len0); } -void world::do_make_object(const std::shared_ptr<object>& e, global_coords pos, bool sorted) +void world::do_make_object(const bptr<object>& e, global_coords pos, bool sorted) { fm_debug_assert(e->id != 0); fm_debug_assert(e->c); @@ -186,7 +188,7 @@ void world::erase_object(object_id id) fm_debug_assert(cnt > 0); } -std::shared_ptr<object> world::find_object_(object_id id) +bptr<object> world::find_object_(object_id id) { auto it = _objects->find(id); auto ret = it == _objects->end() ? nullptr : it->second.lock(); @@ -267,19 +269,19 @@ struct world::script_status world::script_status() const return { _script_initialized, _script_finalized }; } -shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id) +bptr<critter> world::ensure_player_character(object_id& id) { return ensure_player_character(id, make_player_proto()); } -shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id_, critter_proto p) +bptr<critter> world::ensure_player_character(object_id& id_, critter_proto p) { if (id_) { - std::shared_ptr<critter> tmp; + bptr<critter> tmp; if (auto C = find_object(id_); C && C->type() == object_type::critter) { - auto ptr = std::static_pointer_cast<critter>(C); + auto ptr = static_pointer_cast<critter>(C); return {ptr}; } } @@ -287,7 +289,7 @@ shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id_, critt auto id = (object_id)-1; - shared_ptr_wrapper<critter> ret; + bptr<critter> ret; for (auto& [coord, c] : chunks()) { @@ -300,7 +302,7 @@ shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id_, critt if (C.playable) { id = std::min(id, C.id); - ret.ptr = std::static_pointer_cast<critter>(eʹ); + ret = static_pointer_cast<critter>(eʹ); } } } @@ -311,18 +313,18 @@ shared_ptr_wrapper<critter> world::ensure_player_character(object_id& id_, critt else { p.playable = true; - ret.ptr = make_object<critter>(make_id(), global_coords{}, move(p)); - id_ = ret.ptr->id; + ret = make_object<critter>(make_id(), global_coords{}, move(p)); + id_ = ret->id; } - fm_debug_assert(ret.ptr); + fm_debug_assert(ret); return ret; } template<typename T> -std::shared_ptr<T> world::find_object(object_id id) +bptr<T> world::find_object(object_id id) { static_assert(std::is_base_of_v<object, T>); - if (std::shared_ptr<object> ptr = find_object_(id); !ptr) + if (bptr<object> ptr = find_object_(id); !ptr) return {}; else if constexpr(std::is_same_v<T, object>) return ptr; @@ -334,7 +336,7 @@ std::shared_ptr<T> world::find_object(object_id id) template<typename T> requires is_strict_base_of<scenery, T> -std::shared_ptr<T> world::find_object(object_id id) +bptr<T> world::find_object(object_id id) { if (auto ptr = find_object<scenery>(id); !ptr) return {}; @@ -344,17 +346,17 @@ std::shared_ptr<T> world::find_object(object_id id) return static_pointer_cast<T>(move(ptr)); } -template std::shared_ptr<object> world::find_object<object>(object_id id); -template std::shared_ptr<critter> world::find_object<critter>(object_id id); -template std::shared_ptr<scenery> world::find_object<scenery>(object_id id); -template std::shared_ptr<light> world::find_object<light>(object_id id); -template std::shared_ptr<generic_scenery> world::find_object<generic_scenery>(object_id id); -template std::shared_ptr<door_scenery> world::find_object<door_scenery>(object_id id); +template bptr<object> world::find_object<object>(object_id id); +template bptr<critter> world::find_object<critter>(object_id id); +template bptr<scenery> world::find_object<scenery>(object_id id); +template bptr<light> world::find_object<light>(object_id id); +template bptr<generic_scenery> world::find_object<generic_scenery>(object_id id); +template bptr<door_scenery> world::find_object<door_scenery>(object_id id); template<bool sorted> -std::shared_ptr<scenery> world::make_scenery(object_id id, global_coords pos, scenery_proto&& proto) +bptr<scenery> world::make_scenery(object_id id, global_coords pos, scenery_proto&& proto) { - using type = std::shared_ptr<scenery>; + using type = bptr<scenery>; return std::visit(overloaded { [&](std::monostate) -> type { @@ -369,7 +371,7 @@ std::shared_ptr<scenery> world::make_scenery(object_id id, global_coords pos, sc }, move(proto.subtype)); } -template std::shared_ptr<scenery> world::make_scenery<false>(object_id id, global_coords pos, scenery_proto&& proto); -template std::shared_ptr<scenery> world::make_scenery<true>(object_id id, global_coords pos, scenery_proto&& proto); +template bptr<scenery> world::make_scenery<false>(object_id id, global_coords pos, scenery_proto&& proto); +template bptr<scenery> world::make_scenery<true>(object_id id, global_coords pos, scenery_proto&& proto); } // namespace floormat diff --git a/src/world.hpp b/src/world.hpp index ecd58e3c..a0c2723a 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -1,17 +1,16 @@ #pragma once #include "compat/safe-ptr.hpp" #include "compat/base-of.hpp" +#include "compat/borrowed-ptr.inl" #include "chunk.hpp" #include "global-coords.hpp" #include "object-type.hpp" #include "scenery-type.hpp" #include "loader/policy.hpp" -#include <memory> #include <unordered_map> namespace floormat { -template<typename T> struct shared_ptr_wrapper; struct object; struct critter; struct critter_proto; @@ -36,12 +35,17 @@ private: chunk_coords_ pos = invalid_coords; } _last_chunk; + struct unique_id : bptr_base + { + bool operator==(const unique_id& other) const; + }; + struct object_id_hasher { size_t operator()(object_id id) const noexcept; }; struct robin_map_wrapper; std::unordered_map<chunk_coords_, chunk, chunk_coords_hasher> _chunks; safe_ptr<robin_map_wrapper> _objects; - std::shared_ptr<char> _unique_id = std::make_shared<char>('A'); + bptr<unique_id> _unique_id; object_id _object_counter = object_counter_init; uint64_t _current_frame = 1; // zero is special for struct object bool _teardown : 1 = false; @@ -50,9 +54,9 @@ private: explicit world(size_t capacity); - void do_make_object(const std::shared_ptr<object>& e, global_coords pos, bool sorted); // todo replace 2nd arg with chunk& + void do_make_object(const bptr<object>& e, global_coords pos, bool sorted); // todo replace 2nd arg with chunk& void erase_object(object_id id); - std::shared_ptr<object> find_object_(object_id id); + bptr<object> find_object_(object_id id); [[noreturn]] static void throw_on_wrong_object_type(object_id id, object_type actual, object_type expected); [[noreturn]] static void throw_on_wrong_scenery_type(object_id id, scenery_type actual, scenery_type expected); @@ -89,19 +93,19 @@ public: T{object_id(), c, std::declval<Xs&&>()...}; std::is_base_of_v<object, T>; } - std::shared_ptr<T> make_object(object_id id, global_coords pos, Xs&&... xs) + bptr<T> make_object(object_id id, global_coords pos, Xs&&... xs) { - auto ret = std::shared_ptr<T>(new T{id, operator[](pos.chunk3()), forward<Xs>(xs)...}); - do_make_object(std::static_pointer_cast<object>(ret), pos, sorted); + auto ret = bptr<T>(new T{id, operator[](pos.chunk3()), forward<Xs>(xs)...}); + do_make_object(ret, pos, sorted); return ret; } - template<bool sorted = true> std::shared_ptr<scenery> make_scenery(object_id id, global_coords pos, scenery_proto&& proto); - template<typename T = object> std::shared_ptr<T> find_object(object_id id); - template<typename T> requires is_strict_base_of<scenery, T> std::shared_ptr<T> find_object(object_id id); + template<bool sorted = true> bptr<scenery> make_scenery(object_id id, global_coords pos, scenery_proto&& proto); + template<typename T = object> bptr<T> find_object(object_id id); + template<typename T> requires is_strict_base_of<scenery, T> bptr<T> find_object(object_id id); - shared_ptr_wrapper<critter> ensure_player_character(object_id& id, critter_proto p); - shared_ptr_wrapper<critter> ensure_player_character(object_id& id); + bptr<critter> ensure_player_character(object_id& id, critter_proto p); + bptr<critter> ensure_player_character(object_id& id); static critter_proto make_player_proto(); struct script_status { bool initialized, finalized; }; |