From aa92549b6dbea89231690bb961da0f23f6d6f19f Mon Sep 17 00:00:00 2001 From: Takayama Fumihiko Date: Mon, 19 Feb 2024 09:16:46 +0900 Subject: [PATCH] Add scoped_modifier_flag --- src/share/modifier_flag_manager.hpp | 41 ++++ .../active_modifier_flag.hpp | 36 ++++ .../scoped_modifier_flag.hpp | 64 +++++++ .../src/scoped_modifier_flags_test.hpp | 181 ++++++++++++++++++ tests/src/modifier_flag_manager/src/test.cpp | 26 +++ 5 files changed, 348 insertions(+) create mode 100644 src/share/modifier_flag_manager/scoped_modifier_flag.hpp create mode 100644 tests/src/modifier_flag_manager/src/scoped_modifier_flags_test.hpp diff --git a/src/share/modifier_flag_manager.hpp b/src/share/modifier_flag_manager.hpp index 0d6aaf857..4daeaac51 100644 --- a/src/share/modifier_flag_manager.hpp +++ b/src/share/modifier_flag_manager.hpp @@ -2,6 +2,7 @@ #include "types.hpp" #include +#include #include #include @@ -9,6 +10,7 @@ namespace krbn { class modifier_flag_manager final { public: #include "modifier_flag_manager/active_modifier_flag.hpp" +#include "modifier_flag_manager/scoped_modifier_flag.hpp" modifier_flag_manager(const modifier_flag_manager&) = delete; @@ -118,6 +120,10 @@ class modifier_flag_manager final { } } + const std::vector& get_active_modifier_flags(void) const { + return active_modifier_flags_; + } + size_t active_modifier_flags_size(void) const { return active_modifier_flags_.size(); } @@ -175,6 +181,29 @@ class modifier_flag_manager final { return modifiers; } + std::set make_modifier_flags(void) const { + std::set modifier_flags; + + for (const auto& m : { + modifier_flag::caps_lock, + modifier_flag::left_control, + modifier_flag::left_shift, + modifier_flag::left_option, + modifier_flag::left_command, + modifier_flag::right_control, + modifier_flag::right_shift, + modifier_flag::right_option, + modifier_flag::right_command, + modifier_flag::fn, + }) { + if (is_pressed(m)) { + modifier_flags.insert(m); + } + } + + return modifier_flags; + } + private: void erase_pairs(void) { for (size_t i1 = 0; i1 < active_modifier_flags_.size(); ++i1) { @@ -193,4 +222,16 @@ class modifier_flag_manager final { std::vector active_modifier_flags_; }; + +inline std::ostream& operator<<(std::ostream& stream, const modifier_flag_manager::active_modifier_flag& value) { + stream << value.to_json(); + return stream; +} + +inline std::ostream& operator<<(std::ostream& stream, const std::vector& value) { + for (const auto& v : value) { + stream << v.to_json() << std::endl; + } + return stream; +} } // namespace krbn diff --git a/src/share/modifier_flag_manager/active_modifier_flag.hpp b/src/share/modifier_flag_manager/active_modifier_flag.hpp index f300eea5a..9a4c0dba8 100644 --- a/src/share/modifier_flag_manager/active_modifier_flag.hpp +++ b/src/share/modifier_flag_manager/active_modifier_flag.hpp @@ -148,6 +148,42 @@ class active_modifier_flag final { constexpr auto operator<=>(const active_modifier_flag&) const = default; + nlohmann::json to_json(void) const { + nlohmann::json json; + + switch (type_) { + case type::increase: + json["type"] = "increase"; + break; + case type::decrease: + json["type"] = "decrease"; + break; + case type::increase_lock: + json["type"] = "increase_lock"; + break; + case type::decrease_lock: + json["type"] = "decrease_lock"; + break; + case type::increase_led_lock: + json["type"] = "increase_led_lock"; + break; + case type::decrease_led_lock: + json["type"] = "decrease_led_lock"; + break; + case type::increase_sticky: + json["type"] = "increase_sticky"; + break; + case type::decrease_sticky: + json["type"] = "decrease_sticky"; + break; + } + + json["modifier_flag"] = modifier_flag_; + json["device_id"] = device_id_; + + return json; + } + private: type type_; modifier_flag modifier_flag_; diff --git a/src/share/modifier_flag_manager/scoped_modifier_flag.hpp b/src/share/modifier_flag_manager/scoped_modifier_flag.hpp new file mode 100644 index 000000000..7a261fc53 --- /dev/null +++ b/src/share/modifier_flag_manager/scoped_modifier_flag.hpp @@ -0,0 +1,64 @@ +#pragma once + +class scoped_modifier_flag final { +public: + scoped_modifier_flag(modifier_flag_manager& modifier_flag_manager, + std::set modifier_flags) + : modifier_flag_manager_(modifier_flag_manager) { + for (const auto& m : { + modifier_flag::caps_lock, + modifier_flag::left_control, + modifier_flag::left_shift, + modifier_flag::left_option, + modifier_flag::left_command, + modifier_flag::right_control, + modifier_flag::right_shift, + modifier_flag::right_option, + modifier_flag::right_command, + modifier_flag::fn, + }) { + if (modifier_flags.contains(m)) { + while (!modifier_flag_manager_.is_pressed(m)) { + active_modifier_flag f(active_modifier_flag::type::increase, m, device_id(0)); + modifier_flag_manager_.push_back_active_modifier_flag(f); + scoped_active_modifier_flags_.push_back(f); + } + } else { + if (modifier_flag_manager_.is_pressed(m)) { + auto copy = modifier_flag_manager_.get_active_modifier_flags(); + for (const auto& f : copy) { + if (f.get_modifier_flag() == m) { + active_modifier_flag inverse(f.get_inverse_type(), f.get_modifier_flag(), device_id(0)); + modifier_flag_manager_.push_back_active_modifier_flag(inverse); + scoped_active_modifier_flags_.push_back(inverse); + } + } + } + } + } + } + + ~scoped_modifier_flag(void) { + for (const auto& f : get_inverse_active_modifier_flags()) { + modifier_flag_manager_.push_back_active_modifier_flag(f); + } + } + + const std::vector& get_scoped_active_modifier_flags(void) const { + return scoped_active_modifier_flags_; + } + + std::vector get_inverse_active_modifier_flags(void) const { + std::vector flags; + + for (const auto& f : scoped_active_modifier_flags_) { + flags.push_back(active_modifier_flag(f.get_inverse_type(), f.get_modifier_flag(), f.get_device_id())); + } + + return flags; + } + +private: + modifier_flag_manager& modifier_flag_manager_; + std::vector scoped_active_modifier_flags_; +}; diff --git a/tests/src/modifier_flag_manager/src/scoped_modifier_flags_test.hpp b/tests/src/modifier_flag_manager/src/scoped_modifier_flags_test.hpp new file mode 100644 index 000000000..c06edb3a7 --- /dev/null +++ b/tests/src/modifier_flag_manager/src/scoped_modifier_flags_test.hpp @@ -0,0 +1,181 @@ +#pragma once + +#include "modifier_flag_manager.hpp" +#include + +void run_scoped_modifier_flags_test(void) { + using namespace boost::ut; + using namespace boost::ut::literals; + + "modifier_flag_manager::scoped_modifier_flags"_test = [] { + using namespace krbn; + typedef modifier_flag_manager::active_modifier_flag active_modifier_flag; + typedef modifier_flag_manager::scoped_modifier_flag scoped_modifier_flag; + + { + modifier_flag_manager modifier_flag_manager; + + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_command, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::increase_lock, modifier_flag::left_command, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::increase_sticky, modifier_flag::left_command, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::decrease, modifier_flag::left_option, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::decrease_lock, modifier_flag::left_option, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::decrease_sticky, modifier_flag::left_option, device_id(1))); + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::increase_led_lock, modifier_flag::caps_lock, device_id(1))); + + auto active_modifier_flags = modifier_flag_manager.get_active_modifier_flags(); + + expect(std::set({ + modifier_flag::caps_lock, + modifier_flag::left_command, + }) == modifier_flag_manager.make_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{ + modifier_flag::left_shift, + }); + + expect(std::set({ + modifier_flag::left_shift, + }) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({ + active_modifier_flag(active_modifier_flag::type::decrease_led_lock, modifier_flag::caps_lock, device_id(0)), + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_shift, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease, modifier_flag::left_command, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease_lock, modifier_flag::left_command, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease_sticky, modifier_flag::left_command, device_id(0)), + }) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{ + modifier_flag::left_option, + }); + + expect(std::set({ + modifier_flag::left_option, + }) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({ + active_modifier_flag(active_modifier_flag::type::decrease_led_lock, modifier_flag::caps_lock, device_id(0)), + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_option, device_id(0)), + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_option, device_id(0)), + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_option, device_id(0)), + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::left_option, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease, modifier_flag::left_command, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease_lock, modifier_flag::left_command, device_id(0)), + active_modifier_flag(active_modifier_flag::type::decrease_sticky, modifier_flag::left_command, device_id(0)), + }) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{ + modifier_flag::left_command, + }); + + expect(std::set({ + modifier_flag::left_command, + }) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({ + active_modifier_flag(active_modifier_flag::type::decrease_led_lock, modifier_flag::caps_lock, device_id(0)), + }) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + } + + // + // Tests for type::decrease_led_lock + // + + { + modifier_flag_manager modifier_flag_manager; + + modifier_flag_manager.push_back_active_modifier_flag(active_modifier_flag(active_modifier_flag::type::decrease_led_lock, modifier_flag::caps_lock, device_id(1))); + + auto active_modifier_flags = modifier_flag_manager.get_active_modifier_flags(); + + expect(std::set({}) == modifier_flag_manager.make_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{}); + + expect(std::set({}) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({}) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{modifier_flag::caps_lock}); + + expect(std::set({ + modifier_flag::caps_lock, + }) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({ + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::caps_lock, device_id(0)), + }) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + } + + // + // Increase caps_lock by type::increase + // + + { + modifier_flag_manager modifier_flag_manager; + + auto active_modifier_flags = modifier_flag_manager.get_active_modifier_flags(); + + expect(std::set({}) == modifier_flag_manager.make_modifier_flags()); + + { + scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set{modifier_flag::caps_lock}); + + expect(std::set({ + modifier_flag::caps_lock, + }) == modifier_flag_manager.make_modifier_flags()); + + std::cout << std::endl + << scoped_modifier_flag.get_scoped_active_modifier_flags() + << std::endl; + + expect(std::vector({ + active_modifier_flag(active_modifier_flag::type::increase, modifier_flag::caps_lock, device_id(0)), + }) == scoped_modifier_flag.get_scoped_active_modifier_flags()); + } + + expect(active_modifier_flags == modifier_flag_manager.get_active_modifier_flags()); + } + }; +} diff --git a/tests/src/modifier_flag_manager/src/test.cpp b/tests/src/modifier_flag_manager/src/test.cpp index 2cd6969de..0b2fbd094 100644 --- a/tests/src/modifier_flag_manager/src/test.cpp +++ b/tests/src/modifier_flag_manager/src/test.cpp @@ -1,4 +1,5 @@ #include "modifier_flag_manager.hpp" +#include "scoped_modifier_flags_test.hpp" #include namespace { @@ -65,6 +66,9 @@ krbn::modifier_flag_manager::active_modifier_flag right_shift_1(krbn::modifier_f krbn::modifier_flag_manager::active_modifier_flag right_command_1(krbn::modifier_flag_manager::active_modifier_flag::type::increase, krbn::modifier_flag::right_command, krbn::device_id(1)); +krbn::modifier_flag_manager::active_modifier_flag fn_1(krbn::modifier_flag_manager::active_modifier_flag::type::increase, + krbn::modifier_flag::fn, + krbn::device_id(1)); } // namespace int main(void) { @@ -355,5 +359,27 @@ int main(void) { } }; + "modifier_flag_manager::make_modifier_flags"_test = [] { + { + krbn::modifier_flag_manager modifier_flag_manager; + + expect(std::set({}) == modifier_flag_manager.make_modifier_flags()); + + modifier_flag_manager.push_back_active_modifier_flag(led_lock_caps_lock); + modifier_flag_manager.push_back_active_modifier_flag(left_shift_1); + modifier_flag_manager.push_back_active_modifier_flag(right_command_1); + modifier_flag_manager.push_back_active_modifier_flag(fn_1); + + expect(std::set({ + krbn::modifier_flag::caps_lock, + krbn::modifier_flag::left_shift, + krbn::modifier_flag::right_command, + krbn::modifier_flag::fn, + }) == modifier_flag_manager.make_modifier_flags()); + } + }; + + run_scoped_modifier_flags_test(); + return 0; }