diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-10-20 12:33:00 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-10-20 12:33:00 +0200 |
commit | 275cb79a1857fff08ce1b642bbfab6d7377bcaef (patch) | |
tree | b8671ed206fc27d4762779cf64113ef7d9ce8fd9 /editor | |
parent | 5be116ea43231c747f09c4d43a75d45984b54a66 (diff) |
aa
Diffstat (limited to 'editor')
-rw-r--r-- | editor/CMakeLists.txt | 4 | ||||
-rw-r--r-- | editor/app.cpp | 25 | ||||
-rw-r--r-- | editor/app.hpp | 13 | ||||
-rw-r--r-- | editor/camera.cpp | 5 | ||||
-rw-r--r-- | editor/events.cpp | 2 | ||||
-rw-r--r-- | editor/scenery-editor.cpp | 2 | ||||
-rw-r--r-- | editor/tests-private.hpp | 43 | ||||
-rw-r--r-- | editor/tests.cpp | 80 | ||||
-rw-r--r-- | editor/tests/path.cpp | 77 | ||||
-rw-r--r-- | editor/vobj-editor.cpp | 2 |
10 files changed, 205 insertions, 48 deletions
diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 74da3536..5f4f17d3 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -1,6 +1,6 @@ set(self floormat-editor) -file(GLOB sources "*.cpp" CONFIGURE_ARGS) +file(GLOB sources "*.cpp" "tests/*.cpp" CONFIGURE_ARGS) corrade_add_resource(res "../resources.conf") if(MSVC) @@ -23,7 +23,7 @@ if(NOT SDL2_INCLUDE_DIRS) get_target_property(SDL2_INCLUDE_DIRS SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES) endif() endif() -set_property(SOURCE "events.cpp" APPEND PROPERTY INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}") +set_property(SOURCE "events.cpp" "tests.cpp" APPEND PROPERTY INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}") add_executable(${self} dummy.cc) if (FLOORMAT_ASAN) diff --git a/editor/app.cpp b/editor/app.cpp index a2ffc9f4..7c42e98c 100644 --- a/editor/app.cpp +++ b/editor/app.cpp @@ -17,6 +17,17 @@ namespace floormat { +struct Optional<point> cursor_state::point() const +{ + if (tile) + return {InPlaceInit, *tile, *subpixel}; + else + return {}; +} + +floormat_main& app::main() { return *M; } +const cursor_state& app::cursor_state() { return cursor; } + app::app(fm_settings&& opts) : M{floormat_main::create(*this, Utility::move(opts))}, _tests{tests_data_::make()} @@ -40,15 +51,17 @@ void app::reset_world() reset_world(world{}); } -void app::ensure_player_character(world& w) +std::shared_ptr<critter> app::ensure_player_character(world& w) { if (_character_id) if (auto C = w.find_object(_character_id); C && C->type() == object_type::critter) - return; + return std::static_pointer_cast<critter>(C); _character_id = 0; auto id = (object_id)-1; + std::shared_ptr<critter> ret; + for (const auto& [coord, c] : w.chunks()) { for (const auto& e_ : c.objects()) @@ -58,7 +71,10 @@ void app::ensure_player_character(world& w) { const auto& C = static_cast<const critter&>(e); if (C.playable) + { id = std::min(id, C.id); + ret = std::static_pointer_cast<critter>(e_); + } } } } @@ -70,8 +86,11 @@ void app::ensure_player_character(world& w) critter_proto cproto; cproto.name = "Player"_s; cproto.playable = true; - _character_id = w.make_object<critter>(w.make_id(), global_coords{}, cproto)->id; + ret = w.make_object<critter>(w.make_id(), global_coords{}, cproto); + _character_id = ret->id; } + fm_debug_assert(ret); + return ret; } void app::reset_world(struct world&& w_) diff --git a/editor/app.hpp b/editor/app.hpp index d035d1ec..15e9d7a7 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -26,12 +26,15 @@ struct tile_editor; struct fm_settings; struct anim_atlas; struct critter; +struct point; struct cursor_state final { Optional<Vector2i> pixel; Optional<global_coords> tile; Optional<Vector2b> subpixel; bool in_imgui = false; + + struct Optional<point> point() const; }; struct clickable; @@ -60,7 +63,11 @@ struct app final : floormat_app #ifdef _WIN32 static void set_dpi_aware(); #endif - object_id object_at_cursor(); + object_id get_object_colliding_with_cursor(); + floormat_main& main(); + const struct cursor_state& cursor_state(); + clickable* find_clickable_scenery(const Optional<Vector2i>& pixel); + std::shared_ptr<critter> ensure_player_character(world& w); private: using key_set = enum_bitset<key, key_COUNT>; @@ -82,7 +89,6 @@ private: void update_character(float dt); void reset_world(); void reset_world(struct world&& w); - void ensure_player_character(world& w); void draw() override; @@ -106,7 +112,6 @@ private: void do_camera(float dt, const key_set& cmds, int mods); void reset_camera_offset(); - clickable* find_clickable_scenery(const Optional<Vector2i>& pixel); void do_quicksave(); void do_quickload(); @@ -173,7 +178,7 @@ private: std::array<int, key_set::COUNT> key_modifiers = {}; std::vector<popup_target> inspectors; object_id _character_id = 0; - cursor_state cursor; + struct cursor_state cursor; popup_target _popup_target; Optional<chunk_coords_> tested_light_chunk; diff --git a/editor/camera.cpp b/editor/camera.cpp index 42b81c82..674c5e23 100644 --- a/editor/camera.cpp +++ b/editor/camera.cpp @@ -60,11 +60,8 @@ void app::reset_camera_offset() update_cursor_tile(cursor.pixel); } -object_id app::object_at_cursor() +object_id app::get_object_colliding_with_cursor() { - auto [z_min, z_max, z_cur, only] = get_z_bounds(); - if (only) - z_min = z_max = z_cur; const auto [minx, maxx, miny, maxy] = M->get_draw_bounds(); const auto sz = M->window_size(); auto& world = M->world(); diff --git a/editor/events.cpp b/editor/events.cpp index 64f544e4..83039bcb 100644 --- a/editor/events.cpp +++ b/editor/events.cpp @@ -190,7 +190,7 @@ void app::on_key_up_down(const key_event& event, bool is_down) noexcept static_assert(key_GLOBAL >= key_NO_REPEAT); if (x == key_COUNT && (is_down ? _imgui.handleKeyPressEvent(e) : _imgui.handleKeyReleaseEvent(e)) || - x == key_COUNT && _editor.mode() == editor_mode::tests && tests_handle_key(event)) + (x == key_COUNT || x == key_escape) && _editor.mode() == editor_mode::tests && tests_handle_key(event)) clear_non_global_keys(); else if (x >= key_NO_REPEAT) is_down && !event.is_repeated ? do_key(x, mods) : void(); diff --git a/editor/scenery-editor.cpp b/editor/scenery-editor.cpp index 511e5b6a..d338cdcb 100644 --- a/editor/scenery-editor.cpp +++ b/editor/scenery-editor.cpp @@ -86,7 +86,7 @@ void scenery_editor::place_tile(world& w, global_coords pos, const scenery_& s, { auto [c, t] = w[pos]; const auto& es = c.objects(); -start: while (auto id = a.object_at_cursor()) +start: while (auto id = a.get_object_colliding_with_cursor()) { for (auto i = es.size()-1; i != (size_t)-1; i--) { diff --git a/editor/tests-private.hpp b/editor/tests-private.hpp index 01a15a33..5c229696 100644 --- a/editor/tests-private.hpp +++ b/editor/tests-private.hpp @@ -1,17 +1,46 @@ #pragma once -#include "compat/defs.hpp" #include "tests.hpp" +#include "compat/defs.hpp" #include "src/point.hpp" +#include "floormat/events.hpp" +#include <Corrade/Containers/StringView.h> #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 path_test +struct base_test { + fm_DECLARE_DEFAULT_MOVE_ASSIGNMENT_(base_test); + fm_DECLARE_DELETED_COPY_ASSIGNMENT(base_test); + + virtual bool handle_key(app& a, const key_event& e) = 0; + virtual bool handle_mouse_click(app& a, const mouse_button_event& e) = 0; + virtual bool handle_mouse_move(app& a, const mouse_move_event& e) = 0; + virtual void draw_overlay(app& a) = 0; + virtual void update_pre(app& a) = 0; + virtual void update_post(app& a) = 0; + + virtual ~base_test() noexcept; + +protected: + base_test(); +}; + +struct path_test : base_test +{ + bool handle_key(app& a, const key_event& e) override; + bool handle_mouse_click(app& a, const mouse_button_event& e) override; + bool handle_mouse_move(app& a, const mouse_move_event& e) override; + void draw_overlay(app& a) override; + void update_pre(app& a) override; + void update_post(app& a) override; + point from; std::vector<point> path; bool active = false; @@ -29,8 +58,14 @@ struct tests_data final : tests_data_, tests::variant tests_data(); ~tests_data() noexcept override; using tests::variant::operator=; - //tests::variant& operator*(); - //tests::variant* operator->(); + + struct pair { StringView str; size_t index; }; + + static constexpr inline pair fields[] = { + { "Path"_s, 1 }, + }; + + void switch_to(size_t i); }; } // namespace floormat diff --git a/editor/tests.cpp b/editor/tests.cpp index 04489ddc..706c15eb 100644 --- a/editor/tests.cpp +++ b/editor/tests.cpp @@ -2,11 +2,11 @@ #include "app.hpp" #include "floormat/events.hpp" #include "imgui-raii.hpp" +#include <SDL_keycode.h> namespace floormat { using namespace floormat::tests; -using namespace floormat::imgui; tests_data_::~tests_data_() noexcept = default; tests_data_::tests_data_() = default; @@ -14,6 +14,22 @@ 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) +{ + constexpr auto size = std::variant_size_v<tests::variant>; + fm_assert(i < size); + switch (i) + { + case 0: *this = std::monostate{}; break; + case 1: *this = path_test{}; break; + } +} + Pointer<tests_data_> tests_data_::make() { return Pointer<tests_data>{InPlaceInit}; @@ -21,51 +37,51 @@ Pointer<tests_data_> tests_data_::make() void app::tests_pre_update() { + std::visit(overloaded { + [](std::monostate) {}, + [&](base_test& x) { return x.update_pre(*this); } + }, tests()); } void app::tests_post_update() { + std::visit(overloaded { + [](std::monostate) {}, + [&](base_test& x) { return x.update_post(*this); } + }, tests()); } bool app::tests_handle_mouse_click(const mouse_button_event& e) { update_cursor_tile(cursor.pixel); - auto& var = tests(); - if (e.button == mouse_button_left) - { - std::visit(overloaded { - [](std::monostate) {}, - [&](path_test& t) { - // todo - } - }, var); - - return true; - } - else if (e.button == mouse_button_right) - { - bool ret = false; - std::visit(overloaded { - [](std::monostate) {}, - [&](path_test& t) { - ret = t.active; - t = {}; - }, - }, var); - return ret; - } - return false; + return std::visit(overloaded { + [](std::monostate) { return false; }, + [&](base_test& x) { return x.handle_mouse_click(*this, e); } + }, tests()); } bool app::tests_handle_key(const key_event& e) { - return false; + 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); } + }, tests()); + } } bool app::tests_handle_mouse_move(const mouse_move_event& e) { - return false; + return std::visit(overloaded { + [](std::monostate) { return false; }, + [&](base_test& x) { return x.handle_mouse_move(*this, e); } + }, tests()); } tests_data& app::tests() @@ -81,10 +97,18 @@ void app::tests_reset_mode() void app::draw_tests_pane() { + constexpr int selectable_flags = ImGuiSelectableFlags_SpanAvailWidth; + for (auto [str, i] : tests_data::fields) + if (ImGui::Selectable(str.data(), i == tests().index(), selectable_flags)) + tests().switch_to(i); } void app::draw_tests_overlay() { + std::visit(overloaded { + [](std::monostate) {}, + [&](base_test& x) { return x.draw_overlay(*this); } + }, tests()); } } // namespace floormat diff --git a/editor/tests/path.cpp b/editor/tests/path.cpp new file mode 100644 index 00000000..3b015e27 --- /dev/null +++ b/editor/tests/path.cpp @@ -0,0 +1,77 @@ +#include "../tests-private.hpp" +#include "../app.hpp" +#include "floormat/main.hpp" +#include "src/path-search.hpp" +#include "src/critter.hpp" + +namespace floormat::tests { + +bool path_test::handle_key(app& a, const key_event& e) +{ + return false; +} + +bool path_test::handle_mouse_click(app& a, const mouse_button_event& e) +{ + switch (e.button) + { + case mouse_button_left: { + auto& M = a.main(); + auto& w = M.world(); + auto& astar = M.astar(); + auto C = a.ensure_player_character(w); + if (auto pt = a.cursor_state().point()) + { + constexpr auto chunk_size = iTILE_SIZE2 * TILE_MAX_DIM; + auto pt0 = C->position(); + auto vec = (pt->coord() - pt0.coord()) * iTILE_SIZE2 * 2 + chunk_size * 3; + auto dist = (uint32_t)vec.length(); + auto res = astar.Dijkstra(w, *pt, pt0, C->id, dist, C->bbox_size, 1); + if (res) + { + active = true; + from = pt0; + path = res.path(); + } + else + { + active = false; + from = {}; + path = {}; + } + } + return true; + } + case mouse_button_right: + if (active) + { + *this = {}; + return true; + } + return false; + default: + return false; + } +} + +bool path_test::handle_mouse_move(app& a, const mouse_move_event& e) +{ + return false; +} + +void path_test::draw_overlay(app& a) +{ + +} + +void path_test::update_pre(app& a) +{ + +} + +void path_test::update_post(app& a) +{ + +} + +} // namespace floormat::tests diff --git a/editor/vobj-editor.cpp b/editor/vobj-editor.cpp index 4d3f3f03..e5046e61 100644 --- a/editor/vobj-editor.cpp +++ b/editor/vobj-editor.cpp @@ -46,7 +46,7 @@ void vobj_editor::place_tile(world& w, global_coords pos, const vobj_* x, struct { auto [c, t] = w[pos]; const auto& es = c.objects(); -start: while (auto id = a.object_at_cursor()) +start: while (auto id = a.get_object_colliding_with_cursor()) { for (auto i = es.size()-1; i != (size_t)-1; i--) { |