Skip to content

Commit 785293f

Browse files
committed
b
1 parent a5acc70 commit 785293f

24 files changed

+201
-91
lines changed

bench/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct bench_app final : private FM_APPLICATION
2222
int argc;
2323
char** argv;
2424
};
25-
bench_app::~bench_app() { loader_::destroy(); }
25+
bench_app::~bench_app() { loader.destroy(); }
2626

2727
int argc_ = 0; // NOLINT
2828

@@ -52,6 +52,6 @@ int main(int argc, char** argv)
5252
{ auto app = bench_app{argc, argv};
5353
status = app.exec();
5454
}
55-
loader_::destroy();
55+
loader.destroy();
5656
return status;
5757
}

compat/safe-ptr.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#pragma once
2+
#include "compat/assert.hpp"
3+
#include "compat/defs.hpp"
4+
#include <type_traits>
5+
#include <Corrade/Tags.h>
6+
#include <Corrade/Utility/Move.h>
7+
8+
namespace floormat {
9+
10+
template<typename T>
11+
class safe_ptr final
12+
{
13+
T* ptr;
14+
15+
public:
16+
template<typename... Ts>
17+
requires requires (Ts&&... xs) {
18+
new T{Utility::forward<Ts>(xs)...};
19+
}
20+
safe_ptr(InPlaceInitT, Ts&&... args) noexcept:
21+
ptr{new T{Utility::forward<Ts>(args)...}}
22+
{}
23+
24+
explicit safe_ptr(T*&& ptr) noexcept: ptr{ptr}
25+
{
26+
fm_assert(ptr != nullptr);
27+
}
28+
29+
~safe_ptr() noexcept
30+
{
31+
if (ptr)
32+
delete ptr;
33+
ptr = (T*)-0xbadbabe;
34+
}
35+
36+
explicit safe_ptr(safe_ptr&& other) noexcept: ptr{other.ptr}
37+
{
38+
other.ptr = nullptr;
39+
}
40+
41+
safe_ptr& operator=(safe_ptr&& other) noexcept
42+
{
43+
fm_assert(this != &other);
44+
if (ptr)
45+
delete ptr;
46+
ptr = other.ptr;
47+
other.ptr = nullptr;
48+
return *this;
49+
}
50+
51+
fm_DECLARE_DELETED_COPY_ASSIGNMENT(safe_ptr);
52+
53+
//explicit operator bool() const noexcept { return ptr != nullptr; }
54+
55+
const T& operator*() const noexcept { return *ptr; }
56+
T& operator*() noexcept { return *ptr; }
57+
const T* operator->() const noexcept { return ptr; }
58+
T* operator->() noexcept { return ptr; }
59+
};
60+
61+
} // namespace floormat

compat/shared-ptr-wrapper.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
#include <memory>
3+
4+
namespace floormat {
5+
6+
template<typename T>
7+
struct shared_ptr_wrapper final
8+
{
9+
std::shared_ptr<T> ptr;
10+
};
11+
12+
} // namespace floormat

editor/app.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "app.hpp"
22
#include "compat/assert.hpp"
33
#include "compat/sysexits.hpp"
4+
#include "compat/shared-ptr-wrapper.hpp"
45
#include "editor.hpp"
56
#include "src/anim-atlas.hpp"
67
#include "src/critter.hpp"
@@ -28,16 +29,22 @@ floormat_main& app::main() { return *M; }
2829
const cursor_state& app::cursor_state() { return cursor; }
2930

3031

31-
std::shared_ptr<critter> app::ensure_player_character(world& w)
32+
shared_ptr_wrapper<critter> app::ensure_player_character(world& w)
3233
{
3334
if (_character_id)
35+
{
36+
std::shared_ptr<critter> tmp;
3437
if (auto C = w.find_object(_character_id); C && C->type() == object_type::critter)
35-
return std::static_pointer_cast<critter>(C);
38+
{
39+
auto ptr = std::static_pointer_cast<critter>(C);
40+
return {ptr};
41+
}
42+
}
3643
_character_id = 0;
3744

3845
auto id = (object_id)-1;
3946

40-
std::shared_ptr<critter> ret;
47+
shared_ptr_wrapper<critter> ret;
4148

4249
for (const auto& [coord, c] : w.chunks())
4350
{
@@ -50,7 +57,7 @@ std::shared_ptr<critter> app::ensure_player_character(world& w)
5057
if (C.playable)
5158
{
5259
id = std::min(id, C.id);
53-
ret = std::static_pointer_cast<critter>(e_);
60+
ret.ptr = std::static_pointer_cast<critter>(e_);
5461
}
5562
}
5663
}
@@ -63,11 +70,11 @@ std::shared_ptr<critter> app::ensure_player_character(world& w)
6370
critter_proto cproto;
6471
cproto.name = "Player"_s;
6572
cproto.playable = true;
66-
ret = w.make_object<critter>(w.make_id(), global_coords{}, cproto);
67-
_character_id = ret->id;
73+
ret.ptr = w.make_object<critter>(w.make_id(), global_coords{}, cproto);
74+
_character_id = ret.ptr->id;
6875
}
69-
fm_debug_assert(ret);
70-
return ret;
76+
fm_debug_assert(ret.ptr);
77+
return shared_ptr_wrapper<critter>{ret};
7178
}
7279

7380
void app::reset_world(class world&& w_)
@@ -176,15 +183,13 @@ int app::run_from_argv(const int argc, const char* const* const argv)
176183
opts.argv = argv;
177184
opts.argc = argc;
178185

179-
Pointer<struct floormat_main> main;
180-
Pointer<struct app> app_ptr{new app{Utility::move(opts)}};
181-
auto& app = *app_ptr;
182-
{
183-
ret = app.exec();
184-
main = Utility::move(app.M);
185-
(void)main;
186-
}
187-
loader_::destroy();
186+
struct app* A = new app{Utility::move(opts)};
187+
floormat_main* M = A->M;
188+
fm_assert(M != nullptr);
189+
ret = A->exec();
190+
loader.destroy();
191+
delete A;
192+
delete M;
188193
return ret;
189194
}
190195

editor/app.hpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#pragma once
22
#include "compat/defs.hpp"
33
#include "compat/enum-bitset-fwd.hpp"
4+
#include "compat/safe-ptr.hpp"
45
#include "floormat/app.hpp"
56
#include "keys.hpp"
67
#include "src/global-coords.hpp"
78
#include "src/object-id.hpp"
89
#include "editor-enums.hpp"
910
#include "tests.hpp"
10-
#include <memory>
1111
#include <Corrade/Containers/Array.h>
1212
#include <Corrade/Containers/StaticArray.h>
1313
#include <Corrade/Containers/Pointer.h>
@@ -37,6 +37,7 @@ class anim_atlas;
3737
struct critter;
3838
struct point;
3939
class editor;
40+
template<typename T> struct shared_ptr_wrapper;
4041

4142
struct cursor_state final
4243
{
@@ -78,7 +79,7 @@ struct app final : floormat_app
7879
floormat_main& main();
7980
const struct cursor_state& cursor_state();
8081
clickable* find_clickable_scenery(const Optional<Vector2i>& pixel);
81-
std::shared_ptr<critter> ensure_player_character(world& w);
82+
shared_ptr_wrapper<critter> ensure_player_character(world& w);
8283

8384
private:
8485
app(fm_settings&& opts);
@@ -176,12 +177,12 @@ struct app final : floormat_app
176177
void erase_inspector(size_t index, ptrdiff_t count = 1);
177178
void kill_inspectors();
178179

179-
Pointer<floormat_main> M;
180-
Pointer<ImGuiIntegration::Context> _imgui;
181-
Pointer<floormat::wireframe::meshes> _wireframe;
182-
Pointer<tests_data_> _tests;
183-
Pointer<editor> _editor;
184-
Pointer<key_set> keys_;
180+
floormat_main* M;
181+
safe_ptr<ImGuiIntegration::Context> _imgui;
182+
safe_ptr<floormat::wireframe::meshes> _wireframe;
183+
safe_ptr<tests_data_> _tests;
184+
safe_ptr<editor> _editor;
185+
safe_ptr<key_set> keys_;
185186
StaticArray<key_COUNT, int> key_modifiers{ValueInit};
186187
Array<popup_target> inspectors;
187188
object_id _character_id = 0;

editor/ctor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ namespace floormat {
1010

1111
app::app(fm_settings&& opts) :
1212
M{floormat_main::create(*this, Utility::move(opts))},
13+
_imgui{InPlaceInit, NoCreate},
1314
_wireframe{InPlaceInit},
1415
_tests{tests_data_::make()},
1516
_editor{InPlaceInit, this},
16-
keys_{InPlaceInit, 0}
17+
keys_{InPlaceInit, 0u}
1718
{
1819
reset_world();
1920
auto& w = M->world();

editor/imgui.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ bool popup_target::operator==(const popup_target&) const = default;
2121

2222
void app::init_imgui(Vector2i size)
2323
{
24-
if (!_imgui) [[unlikely]]
24+
if (!_imgui->context()) [[unlikely]]
2525
{
26-
_imgui = Pointer<ImGuiIntegration::Context>{InPlaceInit, NoCreate};
26+
_imgui = safe_ptr<ImGuiIntegration::Context>{InPlaceInit, NoCreate};
2727
*_imgui = ImGuiIntegration::Context{Vector2{size}, size, size};
2828
fm_assert(_imgui->context());
2929
}
@@ -392,7 +392,7 @@ void app::do_popup_menu()
392392

393393
void app::kill_popups(bool hard)
394394
{
395-
const bool imgui = _imgui != nullptr;
395+
const bool imgui = _imgui->context() != nullptr;
396396

397397
if (imgui)
398398
fm_assert(_imgui->context());
@@ -403,13 +403,13 @@ void app::kill_popups(bool hard)
403403
if (hard)
404404
tested_light_chunk = {};
405405

406-
if (_imgui)
406+
if (_imgui->context())
407407
ImGui::CloseCurrentPopup();
408408

409409
if (hard)
410410
kill_inspectors();
411411

412-
if (_imgui)
412+
if (_imgui->context())
413413
ImGui::FocusWindow(nullptr);
414414
}
415415

editor/tests.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "tests-private.hpp"
2+
#include "compat/safe-ptr.hpp"
23
#include "app.hpp"
34
#include "floormat/events.hpp"
45
#include "imgui-raii.hpp"
@@ -31,9 +32,9 @@ void tests_data::switch_to(size_t i)
3132
}
3233
}
3334

34-
Pointer<tests_data_> tests_data_::make()
35+
safe_ptr<tests_data_> tests_data_::make()
3536
{
36-
return Pointer<tests_data>{InPlaceInit};
37+
return safe_ptr<tests_data_>{new tests_data};
3738
}
3839

3940
void app::tests_pre_update()

editor/tests.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33

44
namespace floormat {
55

6+
template<typename T> class safe_ptr;
7+
68
struct tests_data;
79

810
struct tests_data_
911
{
1012
fm_DECLARE_DELETED_COPY_ASSIGNMENT(tests_data_);
1113

1214
virtual ~tests_data_() noexcept;
13-
static Pointer<tests_data_> make();
15+
[[nodiscard]] static safe_ptr<tests_data_> make();
1416

1517
protected:
1618
tests_data_();

editor/tests/path-test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "../tests-private.hpp"
22
#include "../app.hpp"
3+
#include "compat/shared-ptr-wrapper.hpp"
34
#include "floormat/main.hpp"
45
#include "src/path-search.hpp"
56
#include "src/critter.hpp"
@@ -26,7 +27,7 @@ bool path_test::handle_mouse_click(app& a, const mouse_button_event& e, bool is_
2627
case mouse_button_left: {
2728
auto& M = a.main();
2829
auto& w = M.world();
29-
auto C = a.ensure_player_character(w);
30+
auto C = a.ensure_player_character(w).ptr;
3031
if (auto pt = a.cursor_state().point())
3132
{
3233
constexpr auto chunk_size = iTILE_SIZE2 * TILE_MAX_DIM;

external/corrade

floormat/main.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Magnum::Platform { class Sdl2Application; }
99

1010
namespace floormat {
1111

12+
template<typename T> class safe_ptr;
1213
struct fm_settings;
1314
struct floormat_app;
1415
struct tile_shader;

loader/impl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ struct loader_impl final : loader_
2222
{
2323
explicit loader_impl();
2424
~loader_impl() override;
25-
2625
// >-----> system >----->
2726
String original_working_directory;
2827

2928
void set_application_working_directory();
3029
StringView startup_directory() noexcept override;
3130
static void system_init();
31+
void destroy() override;
3232
static bool chdir(StringView pathname);
3333

3434
// >-----> plugins >----->

loader/loader.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
#include "impl.hpp"
2+
#include "ground-info.hpp"
3+
#include "wall-info.hpp"
4+
#include "scenery.hpp"
25

3-
namespace floormat {
4-
5-
using loader_detail::loader_impl;
6+
namespace floormat::loader_detail {
67

7-
void loader_::destroy()
8+
void loader_impl::destroy()
89
{
9-
loader.~loader_();
10-
new (&loader) loader_impl();
10+
wall_atlas_map.clear();
11+
wall_atlas_array.clear();
12+
invalid_wall_atlas = nullptr;
13+
missing_wall_atlases.clear();
14+
15+
ground_atlas_map.clear();
16+
ground_atlas_array.clear();
17+
invalid_ground_atlas = nullptr;
18+
missing_ground_atlases.clear();
19+
20+
anim_atlas_map.clear();
21+
anim_atlases.clear();
22+
sceneries_map.clear();
23+
sceneries_array.clear();
24+
vobj_atlas_map.clear();
25+
vobjs.clear();
1126
}
1227

28+
} // namespace floormat::loader_detail
29+
30+
namespace floormat {
31+
32+
using loader_detail::loader_impl;
33+
1334
loader_& loader_::default_loader() noexcept
1435
{
1536
static loader_impl loader_singleton{};

0 commit comments

Comments
 (0)