diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-25 10:58:57 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-25 10:58:57 +0100 |
commit | 83cb9db81f9c0e1e76bf5608cd4a26e50a43a1fa (patch) | |
tree | 8374d28d4df897cf48ee6ae7df3ba8d7f82ce155 | |
parent | 776f0a7b894d99d2621b96de62e1f15e17d049a0 (diff) |
a
-rw-r--r-- | editor/app.hpp | 5 | ||||
-rw-r--r-- | editor/tests-private.hpp | 69 | ||||
-rw-r--r-- | editor/tests.cpp | 102 | ||||
-rw-r--r-- | editor/tests.hpp | 4 | ||||
-rw-r--r-- | editor/tests/path-test.cpp | 118 | ||||
-rw-r--r-- | src/dijkstra.cpp | 2 | ||||
-rw-r--r-- | src/path-search-result.cpp | 2 |
7 files changed, 188 insertions, 114 deletions
diff --git a/editor/app.hpp b/editor/app.hpp index 14a0fcd6..6f21a456 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -25,6 +25,8 @@ GL::Texture2D make_constant_texture(); struct meshes; } // namespace floormat::wireframe +namespace floormat::tests { struct tests_data; } + namespace floormat { struct fm_settings; @@ -37,7 +39,6 @@ struct critter; struct point; class editor; template<typename T> struct shared_ptr_wrapper; -struct tests_data; struct tests_data_; struct cursor_state final @@ -171,7 +172,7 @@ private: void draw_tests_pane(float width); void draw_tests_overlay(); void tests_reset_mode(); - tests_data& tests(); + tests::tests_data& tests(); void reserve_inspector_array(); void add_inspector(popup_target p); diff --git a/editor/tests-private.hpp b/editor/tests-private.hpp index d7854ac4..7967256e 100644 --- a/editor/tests-private.hpp +++ b/editor/tests-private.hpp @@ -5,16 +5,13 @@ #include "src/object-id.hpp" #include "floormat/events.hpp" #include <Corrade/Containers/StringView.h> +#include <memory> #include <vector> -#include <variant> namespace floormat { struct app; } namespace floormat::tests { -template<typename... Ts> struct overloaded : Ts... { using Ts::operator()...; }; -template<typename... Ts> overloaded(Ts...) -> overloaded<Ts...>; - struct base_test { fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(base_test); @@ -34,61 +31,35 @@ protected: base_test(); }; -struct path_test : base_test -{ - bool handle_key(app& a, const key_event& e, bool is_down) override; - bool handle_mouse_click(app& a, const mouse_button_event& e, bool is_down) override; - bool handle_mouse_move(app& a, const mouse_move_event& e) override; - void draw_overlay(app& a) override; - void draw_ui(app& a, float width) override; - void update_pre(app& a) override; - void update_post(app& a) override; - - struct pending_s - { - point from, to; - object_id own_id; - uint32_t max_dist; - Vector2ub own_size; - } pending = {}; - - struct result_s - { - point from; - std::vector<point> path; - } result; +void label_left(StringView label, float width); - bool has_result : 1 = false, has_pending : 1 = false; +enum class Test : uint32_t { + none, path, COUNT, }; -void label_left(StringView label, float width); - -using variant = std::variant<std::monostate, tests::path_test>; +struct tests_data final : tests_data_ +{ + ~tests_data() noexcept override; -} // namespace floormat::tests + void switch_to(Test i); -namespace floormat { + static std::unique_ptr<base_test> make_test_none(); + static std::unique_ptr<base_test> make_test_path(); -struct tests_data final : tests_data_, tests::variant -{ - fm_DECLARE_DELETED_COPY_ASSIGNMENT(tests_data); - tests_data(); - ~tests_data() noexcept override; - using tests::variant::operator=; + std::unique_ptr<base_test> current_test; + Test current_index = Test::none; - struct pair + struct test_tuple { - StringView str; - size_t index; - tests::variant(*ctor)(); + StringView name; + Test t; + std::unique_ptr<base_test>(*ctor)(); }; - static constexpr inline pair fields[] = { - { "None"_s, 0, [] -> tests::variant { return std::monostate{}; } }, - { "Path"_s, 1, [] -> tests::variant { return tests::path_test{}; } }, + static constexpr test_tuple fields[] = { + { "None"_s, Test::none, &tests_data::make_test_none, }, + { "Path"_s, Test::path, &tests_data::make_test_path, }, }; - - void switch_to(size_t i); }; -} // namespace floormat +} // namespace floormat::tests diff --git a/editor/tests.cpp b/editor/tests.cpp index 8d0d72c5..1521fff7 100644 --- a/editor/tests.cpp +++ b/editor/tests.cpp @@ -18,6 +18,8 @@ void label_left(StringView label, float width) ImGui::SetNextItemWidth(-1); } +std::unique_ptr<base_test> tests_data::make_test_none() { return {}; } + } // namespace floormat::tests namespace floormat { @@ -28,18 +30,25 @@ tests_data_::~tests_data_() noexcept = default; tests_data_::tests_data_() = default; tests_data::~tests_data() noexcept = default; -tests_data::tests_data() = default; base_test::~base_test() noexcept = default; base_test::base_test() = default; using namespace floormat::imgui; -void tests_data::switch_to(size_t i) +void tests_data::switch_to(Test i) { - fm_assert(i < std::size(fields)); - const auto& [str, index, ctor] = fields[i]; - *this = ctor(); + fm_assert((size_t)i < std::size(fields)); + current_index = Test::none; + current_test = make_test_none(); + switch (i) + { + default: break; + case Test::none: current_test = make_test_none(); break; + case Test::path: current_test = make_test_path(); break; + } + if (current_test) + current_index = i; } safe_ptr<tests_data_> tests_data_::make() @@ -49,51 +58,40 @@ safe_ptr<tests_data_> tests_data_::make() void app::tests_pre_update() { - std::visit(overloaded { - [](std::monostate) {}, - [&](base_test& x) { return x.update_pre(*this); } - }, tests()); + if (const auto& x = tests().current_test) + x->update_pre(*this); } void app::tests_post_update() { - std::visit(overloaded { - [](std::monostate) {}, - [&](base_test& x) { return x.update_post(*this); } - }, tests()); + if (const auto& x = tests().current_test) + x->update_post(*this); } bool app::tests_handle_mouse_click(const mouse_button_event& e, bool is_down) { update_cursor_tile(cursor.pixel); - return std::visit(overloaded { - [](std::monostate) { return false; }, - [&](base_test& x) { return x.handle_mouse_click(*this, e, is_down); } - }, tests()); + if (const auto& x = tests().current_test) + return x->handle_mouse_click(*this, e, is_down); + else + return false; } bool app::tests_handle_key(const key_event& e, bool is_down) { - switch (e.key) - { - case SDLK_ESCAPE: - tests().switch_to(0); - return true; - default: - return std::visit(overloaded { - [](std::monostate) { return false; }, - [&](base_test& x) { return x.handle_key(*this, e, is_down); } - }, tests()); - } + if (const auto& x = tests().current_test) + return x->handle_key(*this, e, is_down); + else + return false; } bool app::tests_handle_mouse_move(const mouse_move_event& e) { - return std::visit(overloaded { - [](std::monostate) { return false; }, - [&](base_test& x) { return x.handle_mouse_move(*this, e); } - }, tests()); + if (const auto& x = tests().current_test) + return x->handle_mouse_move(*this, e); + else + return false; } tests_data& app::tests() @@ -103,39 +101,35 @@ tests_data& app::tests() void app::tests_reset_mode() { - if (!std::holds_alternative<std::monostate>(tests())) - tests() = std::monostate{}; + tests().switch_to(Test::none); } void app::draw_tests_pane(float width) { ImGui::SeparatorText("Functional tests"); + auto& t = tests(); constexpr int selectable_flags = ImGuiSelectableFlags_SpanAvailWidth; - for (auto [str, i, ctor] : tests_data::fields) - if (ImGui::Selectable(str.data(), i == tests().index(), selectable_flags)) - tests().switch_to(i); - - std::visit(overloaded { - [](std::monostate) {}, - [&](base_test& x) { - auto dpi = M->dpi_scale(); - ImGui::NewLine(); - ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal, 2*dpi.y()); - auto b = push_id("###test-data"); - return x.draw_ui(*this, width); - } - }, tests()); + + for (auto [str, id, ctor] : tests_data::fields) + if (ImGui::Selectable(str.data(), id == t.current_index, selectable_flags)) + if (t.current_index != id) + t.switch_to(id); + + if (t.current_test) + { + auto dpi = M->dpi_scale(); + ImGui::NewLine(); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal, 2*dpi.y()); + auto b = push_id("###test-data"); + t.current_test->draw_ui(*this, width); + } } void app::draw_tests_overlay() { - std::visit(overloaded { - [](std::monostate) {}, - [&](base_test& x) { - return x.draw_overlay(*this); - } - }, tests()); + if (const auto& x = tests().current_test) + x->draw_overlay(*this); } } // namespace floormat diff --git a/editor/tests.hpp b/editor/tests.hpp index b4ee5289..51e81a3c 100644 --- a/editor/tests.hpp +++ b/editor/tests.hpp @@ -1,12 +1,12 @@ #pragma once #include "compat/defs.hpp" +namespace floormat::tests { struct base_test; struct tests_data; } + namespace floormat { template<typename T> class safe_ptr; -struct tests_data; - struct tests_data_ { fm_DECLARE_DELETED_COPY_ASSIGNMENT(tests_data_); diff --git a/editor/tests/path-test.cpp b/editor/tests/path-test.cpp index ca976a38..baeeb11f 100644 --- a/editor/tests/path-test.cpp +++ b/editor/tests/path-test.cpp @@ -8,9 +8,43 @@ #include "../imgui-raii.hpp" #include "src/camera-offset.hpp" #include <Magnum/Math/Functions.h> +#include <magnum/Math/Color.h> namespace floormat::tests { +using namespace floormat::imgui; + +struct path_test : base_test +{ + bool handle_key(app& a, const key_event& e, bool is_down) override; + bool handle_mouse_click(app& a, const mouse_button_event& e, bool is_down) override; + bool handle_mouse_move(app& a, const mouse_move_event& e) override; + void draw_overlay(app& a) override; + void draw_ui(app& a, float width) override; + void update_pre(app& a) override; + void update_post(app& a) override; + + struct pending_s + { + point from, to; + object_id own_id; + uint32_t max_dist; + Vector2ub own_size; + } pending = {}; + + struct result_s + { + point from, to; + std::vector<point> path; + float time; + uint32_t cost, distance; + bool found : 1; + } result; + + bool has_result : 1 = false, has_pending : 1 = false; +}; + + bool path_test::handle_key(app& a, const key_event& e, bool is_down) { (void)a; (void)e; (void)is_down; @@ -116,8 +150,15 @@ void path_test::update_pre(app& a) if (res) { has_result = true; - result.from = pending.from; - result.path = res.path(); + result = { + .from = pending.from, + .to = pending.to, + .path = std::move(res.path()), + .time = res.time(), + .cost = res.cost(), + .distance = res.distance(), + .found = res.is_found(), + }; } } @@ -128,9 +169,76 @@ void path_test::update_post(app& a) void path_test::draw_ui(app& a, float width) { - static uint32_t val; - label_left("foo", 100); - ImGui::InputScalar("##foo", ImGuiDataType_U32, &val); + constexpr ImGuiTableFlags table_flags = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY; + constexpr auto colflags_1 = ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoReorder | ImGuiTableColumnFlags_NoSort; + constexpr auto colflags_0 = colflags_1 | ImGuiTableColumnFlags_WidthFixed; + + char buf[128]; + const auto& res = result; + + if (!has_result) + return; + + auto from_c = Vector3i(res.from.chunk3()), to_c = Vector3i(res.to.chunk3()); + auto from_l = Vector2i(res.from.local()), to_l = Vector2i(res.to.local()); + auto from_p = Vector2i(res.from.offset()), to_p = Vector2i(res.to.offset()); + + constexpr auto print_coord = [](auto&& buf, Vector3i c, Vector2i l, Vector2i p) + { + std::snprintf(buf, std::size(buf), "(%dx%d) <%dx%d> {%dx%d}", c.x(), c.y(), l.x(), l.y(), p.x(), p.y()); + }; + + constexpr auto do_column = [](StringView name) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + text(name); + ImGui::TableNextColumn(); + }; + + if (auto b1 = begin_table("##search_results", 2, table_flags)) + { + ImGui::TableSetupColumn("##name", colflags_0); + ImGui::TableSetupColumn("##value", colflags_1 | ImGuiTableColumnFlags_WidthStretch); + + do_column("from"); + print_coord(buf, from_c, from_l, from_p); + text(buf); + + do_column("to"); + print_coord(buf, to_c, to_l, to_p); + text(buf); + + do_column("found?"); + if (res.found) + { + auto b = push_style_color(ImGuiCol_Text, 0x00ff00ff_rgbaf); + text("yes"); + } + else + { + { + auto b = push_style_color(ImGuiCol_Text, 0xff0000ff_rgbaf); + text("no"); + } + { + auto b = push_style_color(ImGuiCol_Text, 0xffff00ff_rgbaf); + do_column("dist"); + std::snprintf(buf, std::size(buf), "%d", (int)res.distance); + text(buf); + } + } + + do_column("cost"); + std::snprintf(buf, std::size(buf), "%d", (int)res.cost); + text(buf); + + do_column("length"); + std::snprintf(buf, std::size(buf), "%d", (int)res.path.size()); + text(buf); + } } +std::unique_ptr<base_test> tests_data::make_test_path() { return std::make_unique<path_test>(); } + } // namespace floormat::tests diff --git a/src/dijkstra.cpp b/src/dijkstra.cpp index ef980ee6..69711453 100644 --- a/src/dijkstra.cpp +++ b/src/dijkstra.cpp @@ -108,7 +108,7 @@ void set_result_from_idx(path_search_result& result, const std::vector<visited>& path.clear(); const auto& to_node = nodes[idx]; - if (to != to_node.pt) + if (result.is_found() && to != to_node.pt) path.push_back(to); result.set_cost(to_node.dist); diff --git a/src/path-search-result.cpp b/src/path-search-result.cpp index fe420475..50e9173a 100644 --- a/src/path-search-result.cpp +++ b/src/path-search-result.cpp @@ -34,7 +34,7 @@ path_search_result::path_search_result() path_search_result::~path_search_result() noexcept { - if (_node) [[likely]] + if (_node && _node->vec.capacity() > 0) [[likely]] { _node->vec.clear(); _node->_next = std::move(_pool); |