summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/anim-atlas.hpp5
-rw-r--r--src/chunk-collision.cpp22
-rw-r--r--src/chunk-render.cpp1
-rw-r--r--src/chunk-walls.cpp1
-rw-r--r--src/chunk.cpp43
-rw-r--r--src/chunk.hpp34
-rw-r--r--src/critter-script-empty.cpp12
-rw-r--r--src/critter-script-walk.cpp20
-rw-r--r--src/critter-script.hpp7
-rw-r--r--src/critter.cpp13
-rw-r--r--src/critter.hpp6
-rw-r--r--src/ground-atlas.cpp4
-rw-r--r--src/ground-atlas.hpp10
-rw-r--r--src/hole.cpp2
-rw-r--r--src/hole.hpp2
-rw-r--r--src/light.cpp2
-rw-r--r--src/light.hpp2
-rw-r--r--src/object.cpp5
-rw-r--r--src/object.hpp18
-rw-r--r--src/scenery.cpp4
-rw-r--r--src/scenery.hpp4
-rw-r--r--src/script.hpp12
-rw-r--r--src/script.inl14
-rw-r--r--src/tile-image.cpp3
-rw-r--r--src/tile-image.hpp8
-rw-r--r--src/tile.cpp14
-rw-r--r--src/tile.hpp17
-rw-r--r--src/wall-atlas.hpp5
-rw-r--r--src/world.cpp64
-rw-r--r--src/world.hpp30
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; };