basic touchable event classes

This commit is contained in:
2020-02-04 01:07:30 +07:00
parent 1e28f05c07
commit 00fe003eb2
8 changed files with 240 additions and 114 deletions

View File

@@ -8,12 +8,20 @@
#include "_components.hpp"
namespace e2d::touchable_events
{
class input_evt;
class mouse_evt;
class touch_evt;
using event = std::variant<std::monostate,
mouse_evt,
touch_evt>;
}
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<flag_masks> flags_{
fm_bubbling |
fm_capturing};
};
@@ -51,26 +59,12 @@ namespace e2d
};
template <>
class factory_loader<touchable::touched> final : factory_loader<> {
class factory_loader<events<touchable_events::event>> 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<touchable::under_mouse> final : factory_loader<> {
public:
static const char* schema_source;
bool operator()(
touchable::under_mouse& component,
events<touchable_events::event>& 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 {

View File

@@ -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

View File

@@ -50,32 +50,6 @@ namespace e2d::bindings::high
}
),
"touched", sol::property(
[](const gcomponent<touchable>& c) -> bool {
return c.owner().component<touchable::touched>().exists();
},
[](gcomponent<touchable>& c, bool yesno){
if ( yesno ) {
c.owner().component<touchable::touched>().ensure();
} else {
c.owner().component<touchable::touched>().remove();
}
}
),
"under_mouse", sol::property(
[](const gcomponent<touchable>& c) -> bool {
return c.owner().component<touchable::under_mouse>().exists();
},
[](gcomponent<touchable>& c, bool yesno){
if ( yesno ) {
c.owner().component<touchable::under_mouse>().ensure();
} else {
c.owner().component<touchable::under_mouse>().remove();
}
}
),
"bubbling", sol::property(
[](const gcomponent<touchable>& c) -> bool {
return c->bubbling();
@@ -92,5 +66,61 @@ namespace e2d::bindings::high
c->capturing(v);
})
);
//
// events
//
l["touchable"].get_or_create<sol::table>()
.new_usertype<touchable_events::input_evt>("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<sol::table>()
.new_usertype<touchable_events::mouse_evt>("mouse_evt",
sol::no_constructor,
sol::base_classes, sol::bases<touchable_events::input_evt>(),
"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<sol::table>()
.new_usertype<touchable_events::touch_evt>("touch_evt",
sol::no_constructor,
sol::base_classes, sol::bases<touchable_events::input_evt>(),
"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();
})
);
}
}

View File

@@ -698,7 +698,7 @@ namespace e2d
"required" : [],
"additionalProperties" : false,
"properties" : {
"commands" : { "$ref": "#/definitions/events" }
"events" : { "$ref": "#/definitions/events" }
},
"definitions" : {
"events" : {

View File

@@ -54,48 +54,22 @@ namespace e2d
namespace e2d
{
const char* factory_loader<touchable::touched>::schema_source = R"json({
const char* factory_loader<events<touchable_events::event>>::schema_source = R"json({
"type" : "object",
"required" : [],
"additionalProperties" : false,
"properties" : {}
})json";
bool factory_loader<touchable::touched>::operator()(
touchable::touched& component,
bool factory_loader<events<touchable_events::event>>::operator()(
events<touchable_events::event>& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
return true;
}
bool factory_loader<touchable::touched>::operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const
{
E2D_UNUSED(dependencies, ctx);
return true;
}
}
namespace e2d
{
const char* factory_loader<touchable::under_mouse>::schema_source = R"json({
"type" : "object",
"required" : [],
"additionalProperties" : false,
"properties" : {}
})json";
bool factory_loader<touchable::under_mouse>::operator()(
touchable::under_mouse& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
return true;
}
bool factory_loader<touchable::under_mouse>::operator()(
bool factory_loader<events<touchable_events::event>>::operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const
{
@@ -109,28 +83,6 @@ namespace e2d
const char* component_inspector<touchable>::title = ICON_FA_FINGERPRINT " touchable";
void component_inspector<touchable>::operator()(gcomponent<touchable>& c) const {
if ( bool touched = c.owner().component<touchable::touched>().exists();
ImGui::Checkbox("touched", &touched) )
{
if ( touched ) {
c.owner().component<touchable::touched>().ensure();
} else {
c.owner().component<touchable::touched>().remove();
}
}
ImGui::SameLine();
if ( bool under_mouse = c.owner().component<touchable::under_mouse>().exists();
ImGui::Checkbox("under_mouse", &under_mouse) )
{
if ( under_mouse ) {
c.owner().component<touchable::under_mouse>().ensure();
} else {
c.owner().component<touchable::under_mouse>().remove();
}
}
if ( bool bubbling = c->bubbling();
ImGui::Checkbox("bubbling", &bubbling) )
{

View File

@@ -261,8 +261,7 @@ namespace e2d
.register_component<commands<spine_player_commands::command>>("spine_player.commands")
.register_component<sprite_renderer>("sprite_renderer")
.register_component<touchable>("touchable")
.register_component<touchable::touched>("touchable.touched")
.register_component<touchable::under_mouse>("touchable.under_mouse")
.register_component<events<touchable_events::event>>("touchable.events")
;
safe_module_initialize<inspector>()
@@ -287,8 +286,7 @@ namespace e2d
//.register_component<commands<spine_player_commands::command>>("spine_player.commands")
.register_component<sprite_renderer>("sprite_renderer")
.register_component<touchable>("touchable")
//.register_component<touchable::touched>("touchable.touched")
//.register_component<touchable::under_mouse>("touchable.under_mouse")
//.register_component<events<touchable_events::event>>("touchable.events")
;
safe_module_initialize<luasol>();

View File

@@ -31,10 +31,8 @@ namespace
return false;
}
const camera& cam = cam_e.get_component<camera>();
if ( cam.target() ) {
return false;
}
const camera& cam =
cam_e.get_component<camera>();
camera_vp_ =
cam.view() *

View File

@@ -17,6 +17,7 @@
#include <enduro2d/high/components/disabled.hpp>
#include <enduro2d/high/components/events.hpp>
#include <enduro2d/high/components/spine_player.hpp>
#include <enduro2d/high/components/touchable.hpp>
namespace
{
@@ -77,6 +78,32 @@ namespace
}
}, !ecs::exists<disabled<behaviour>>());
}
void process_touchable_events(ecs::registry& owner) {
systems::for_extracted_components<events<touchable_events::event>, behaviour, actor>(owner,
[](ecs::entity e, const events<touchable_events::event>& 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<disabled<behaviour>>();
}
}
}, !ecs::exists<disabled<behaviour>>());
}
}
namespace e2d
@@ -111,6 +138,7 @@ namespace e2d
void process_events(ecs::registry& owner) {
process_spine_player_events(owner);
process_touchable_events(owner);
}
};