From 00fe003eb208c4539dbe47cb272afa0dc9c3806f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 4 Feb 2020 01:07:30 +0700 Subject: [PATCH] basic touchable event classes --- .../enduro2d/high/components/touchable.hpp | 112 ++++++++++++++---- .../scripts/emmy/components/touchable.lua | 62 +++++++++- .../high_binds/components/touchable_binds.cpp | 82 +++++++++---- .../enduro2d/high/components/spine_player.cpp | 2 +- .../enduro2d/high/components/touchable.cpp | 56 +-------- sources/enduro2d/high/starter.cpp | 6 +- .../enduro2d/high/systems/gizmos_system.cpp | 6 +- .../enduro2d/high/systems/script_system.cpp | 28 +++++ 8 files changed, 240 insertions(+), 114 deletions(-) diff --git a/headers/enduro2d/high/components/touchable.hpp b/headers/enduro2d/high/components/touchable.hpp index 5933ebce..e2152e19 100644 --- a/headers/enduro2d/high/components/touchable.hpp +++ b/headers/enduro2d/high/components/touchable.hpp @@ -8,12 +8,20 @@ #include "_components.hpp" +namespace e2d::touchable_events +{ + class input_evt; + class mouse_evt; + class touch_evt; + + using event = std::variant; +} + namespace e2d { class touchable final { - public: - class touched final {}; - class under_mouse final {}; public: touchable() = default; @@ -23,12 +31,12 @@ namespace e2d [[nodiscard]] bool bubbling() const noexcept; [[nodiscard]] bool capturing() const noexcept; private: - enum flag_masks : u32 { + enum flag_masks : u8 { fm_bubbling = 1u << 0, fm_capturing = 1u << 1, }; private: - u32 flags_{ + std::underlying_type_t flags_{ fm_bubbling | fm_capturing}; }; @@ -51,26 +59,12 @@ namespace e2d }; template <> - class factory_loader final : factory_loader<> { + class factory_loader> final : factory_loader<> { public: static const char* schema_source; bool operator()( - touchable::touched& component, - const fill_context& ctx) const; - - bool operator()( - asset_dependencies& dependencies, - const collect_context& ctx) const; - }; - - template <> - class factory_loader final : factory_loader<> { - public: - static const char* schema_source; - - bool operator()( - touchable::under_mouse& component, + events& component, const fill_context& ctx) const; bool operator()( @@ -90,6 +84,82 @@ namespace e2d }; } +namespace e2d::touchable_events +{ + class input_evt { + public: + input_evt(gobject target, bool bubbling, bool capturing) + : target_(target) + , bubbling_(bubbling) + , capturing_(capturing) {} + + [[nodiscard]] gobject target() const noexcept { + return target_; + } + + [[nodiscard]] bool bubbling() const noexcept { + return bubbling_; + } + + [[nodiscard]] bool capturing() const noexcept { + return capturing_; + } + private: + gobject target_; + bool bubbling_ = true; + bool capturing_ = true; + }; + + class mouse_evt final : public input_evt { + public: + ENUM_HPP_CLASS_DECL(types, u8, + (pressed) + (released)) + public: + mouse_evt(gobject target, types type, mouse_button button) + : input_evt(target, true, true) + , type_(type) + , button_(button) {} + + [[nodiscard]] types type() const noexcept { + return type_; + } + + [[nodiscard]] mouse_button button() const noexcept { + return button_; + } + private: + types type_ = types::pressed; + mouse_button button_ = mouse_button::left; + }; + + class touch_evt final : public input_evt { + public: + ENUM_HPP_CLASS_DECL(types, u8, + (pressed) + (released)) + public: + touch_evt(gobject target, types type, u32 finger) + : input_evt(target, true, true) + , type_(type) + , finger_(finger) {} + + [[nodiscard]] types type() const noexcept { + return type_; + } + + [[nodiscard]] u32 finger() const noexcept { + return finger_; + } + private: + types type_ = types::pressed; + u32 finger_ = 0u; + }; +} + +ENUM_HPP_REGISTER_TRAITS(e2d::touchable_events::mouse_evt::types) +ENUM_HPP_REGISTER_TRAITS(e2d::touchable_events::touch_evt::types) + namespace e2d { inline touchable& touchable::bubbling(bool value) noexcept { diff --git a/samples/bin/library/scripts/emmy/components/touchable.lua b/samples/bin/library/scripts/emmy/components/touchable.lua index 8848de52..49a4e8da 100644 --- a/samples/bin/library/scripts/emmy/components/touchable.lua +++ b/samples/bin/library/scripts/emmy/components/touchable.lua @@ -6,12 +6,6 @@ local touchable = { ---@type boolean disabled = false, - ---@type boolean - touched = false, - - ---@type boolean - under_mouse = false, - ---@type boolean bubbling = true, @@ -27,5 +21,61 @@ function touchable.enable(self) end ---@param self touchable function touchable.disable(self) end +-- ----------------------------------------------------------------------------- +-- +-- events +-- +-- ----------------------------------------------------------------------------- + +-- +-- input_evt +-- + +---@class touchable_input_evt +touchable.input_evt = { + ---@type gobject + target = nil, + + ---@type boolean + bubbling = true, + + ---@type boolean + capturing = true +} + +-- +-- mouse_evt +-- + +---@class touchable_mouse_evt : touchable_input_evt +touchable.mouse_evt = { + ---@type string + type = "pressed", + + ---@type string + button = "left" +} + +-- +-- touch_evt +-- + +---@class touchable_touch_evt : touchable_input_evt +touchable.touch_evt = { + ---@type string + type = "pressed", + + ---@type integer + finger = 0 +} + +---@alias touchable_event touchable_mouse_evt | touchable_touch_evt + +-- ----------------------------------------------------------------------------- +-- +-- globals +-- +-- ----------------------------------------------------------------------------- + ---@type touchable _G.touchable = _G.touchable or touchable diff --git a/sources/enduro2d/high/bindings/high_binds/components/touchable_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/touchable_binds.cpp index ea6c4863..4aa66205 100644 --- a/sources/enduro2d/high/bindings/high_binds/components/touchable_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/components/touchable_binds.cpp @@ -50,32 +50,6 @@ namespace e2d::bindings::high } ), - "touched", sol::property( - [](const gcomponent& c) -> bool { - return c.owner().component().exists(); - }, - [](gcomponent& c, bool yesno){ - if ( yesno ) { - c.owner().component().ensure(); - } else { - c.owner().component().remove(); - } - } - ), - - "under_mouse", sol::property( - [](const gcomponent& c) -> bool { - return c.owner().component().exists(); - }, - [](gcomponent& c, bool yesno){ - if ( yesno ) { - c.owner().component().ensure(); - } else { - c.owner().component().remove(); - } - } - ), - "bubbling", sol::property( [](const gcomponent& c) -> bool { return c->bubbling(); @@ -92,5 +66,61 @@ namespace e2d::bindings::high c->capturing(v); }) ); + + // + // events + // + + l["touchable"].get_or_create() + .new_usertype("input_evt", + sol::no_constructor, + + "target", sol::property( + [](const touchable_events::input_evt& c) -> gobject { + return c.target(); + }), + + "bubbling", sol::property( + [](const touchable_events::input_evt& c) -> bool { + return c.bubbling(); + }), + + "capturing", sol::property( + [](const touchable_events::input_evt& c) -> bool { + return c.capturing(); + }) + ); + + l["touchable"].get_or_create() + .new_usertype("mouse_evt", + sol::no_constructor, + sol::base_classes, sol::bases(), + + "type", sol::property( + [](const touchable_events::mouse_evt& c) -> str { + return str(enum_hpp::to_string_or_throw(c.type())); + }), + + "button", sol::property( + [](const touchable_events::mouse_evt& c) -> str { + return str(enum_hpp::to_string_or_throw(c.button())); + }) + ); + + l["touchable"].get_or_create() + .new_usertype("touch_evt", + sol::no_constructor, + sol::base_classes, sol::bases(), + + "type", sol::property( + [](const touchable_events::touch_evt& c) -> str { + return str(enum_hpp::to_string_or_throw(c.type())); + }), + + "finger", sol::property( + [](const touchable_events::touch_evt& c) -> u32 { + return c.finger(); + }) + ); } } diff --git a/sources/enduro2d/high/components/spine_player.cpp b/sources/enduro2d/high/components/spine_player.cpp index e03457c0..95c89902 100644 --- a/sources/enduro2d/high/components/spine_player.cpp +++ b/sources/enduro2d/high/components/spine_player.cpp @@ -698,7 +698,7 @@ namespace e2d "required" : [], "additionalProperties" : false, "properties" : { - "commands" : { "$ref": "#/definitions/events" } + "events" : { "$ref": "#/definitions/events" } }, "definitions" : { "events" : { diff --git a/sources/enduro2d/high/components/touchable.cpp b/sources/enduro2d/high/components/touchable.cpp index 0373a1d5..7fe8547f 100644 --- a/sources/enduro2d/high/components/touchable.cpp +++ b/sources/enduro2d/high/components/touchable.cpp @@ -54,48 +54,22 @@ namespace e2d namespace e2d { - const char* factory_loader::schema_source = R"json({ + const char* factory_loader>::schema_source = R"json({ "type" : "object", "required" : [], "additionalProperties" : false, "properties" : {} })json"; - bool factory_loader::operator()( - touchable::touched& component, + bool factory_loader>::operator()( + events& component, const fill_context& ctx) const { E2D_UNUSED(component, ctx); return true; } - bool factory_loader::operator()( - asset_dependencies& dependencies, - const collect_context& ctx) const - { - E2D_UNUSED(dependencies, ctx); - return true; - } -} - -namespace e2d -{ - const char* factory_loader::schema_source = R"json({ - "type" : "object", - "required" : [], - "additionalProperties" : false, - "properties" : {} - })json"; - - bool factory_loader::operator()( - touchable::under_mouse& component, - const fill_context& ctx) const - { - E2D_UNUSED(component, ctx); - return true; - } - - bool factory_loader::operator()( + bool factory_loader>::operator()( asset_dependencies& dependencies, const collect_context& ctx) const { @@ -109,28 +83,6 @@ namespace e2d const char* component_inspector::title = ICON_FA_FINGERPRINT " touchable"; void component_inspector::operator()(gcomponent& c) const { - if ( bool touched = c.owner().component().exists(); - ImGui::Checkbox("touched", &touched) ) - { - if ( touched ) { - c.owner().component().ensure(); - } else { - c.owner().component().remove(); - } - } - - ImGui::SameLine(); - - if ( bool under_mouse = c.owner().component().exists(); - ImGui::Checkbox("under_mouse", &under_mouse) ) - { - if ( under_mouse ) { - c.owner().component().ensure(); - } else { - c.owner().component().remove(); - } - } - if ( bool bubbling = c->bubbling(); ImGui::Checkbox("bubbling", &bubbling) ) { diff --git a/sources/enduro2d/high/starter.cpp b/sources/enduro2d/high/starter.cpp index 58e771f4..53b699d1 100644 --- a/sources/enduro2d/high/starter.cpp +++ b/sources/enduro2d/high/starter.cpp @@ -261,8 +261,7 @@ namespace e2d .register_component>("spine_player.commands") .register_component("sprite_renderer") .register_component("touchable") - .register_component("touchable.touched") - .register_component("touchable.under_mouse") + .register_component>("touchable.events") ; safe_module_initialize() @@ -287,8 +286,7 @@ namespace e2d //.register_component>("spine_player.commands") .register_component("sprite_renderer") .register_component("touchable") - //.register_component("touchable.touched") - //.register_component("touchable.under_mouse") + //.register_component>("touchable.events") ; safe_module_initialize(); diff --git a/sources/enduro2d/high/systems/gizmos_system.cpp b/sources/enduro2d/high/systems/gizmos_system.cpp index 361746b5..d24339c1 100644 --- a/sources/enduro2d/high/systems/gizmos_system.cpp +++ b/sources/enduro2d/high/systems/gizmos_system.cpp @@ -31,10 +31,8 @@ namespace return false; } - const camera& cam = cam_e.get_component(); - if ( cam.target() ) { - return false; - } + const camera& cam = + cam_e.get_component(); camera_vp_ = cam.view() * diff --git a/sources/enduro2d/high/systems/script_system.cpp b/sources/enduro2d/high/systems/script_system.cpp index b3d6d718..bf2389bf 100644 --- a/sources/enduro2d/high/systems/script_system.cpp +++ b/sources/enduro2d/high/systems/script_system.cpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace { @@ -77,6 +78,32 @@ namespace } }, !ecs::exists>()); } + + void process_touchable_events(ecs::registry& owner) { + systems::for_extracted_components, behaviour, actor>(owner, + [](ecs::entity e, const events& es, behaviour& b, actor& a){ + if ( !a.node() || !a.node()->owner() ) { + return; + } + for ( const touchable_events::event& evt : es.get() ) { + behaviours::call_result r = behaviours::call_result::success; + std::visit(utils::overloaded { + [](std::monostate){}, + [&b,&a,&r](const touchable_events::mouse_evt& e){ + r = behaviours::call_meta_method( + b, "on_event", a.node()->owner(), "touchable.mouse_evt", e); + }, + [&b,&a,&r](const touchable_events::touch_evt& e){ + r = behaviours::call_meta_method( + b, "on_event", a.node()->owner(), "touchable.touch_evt", e); + } + }, evt); + if ( r == behaviours::call_result::failed ) { + e.assign_component>(); + } + } + }, !ecs::exists>()); + } } namespace e2d @@ -111,6 +138,7 @@ namespace e2d void process_events(ecs::registry& owner) { process_spine_player_events(owner); + process_touchable_events(owner); } };