Skip to content

Commit

Permalink
Add scoped_modifier_flag
Browse files Browse the repository at this point in the history
  • Loading branch information
tekezo committed Feb 19, 2024
1 parent 4a8f78d commit aa92549
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/share/modifier_flag_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

#include "types.hpp"
#include <array>
#include <set>
#include <thread>
#include <vector>

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;

Expand Down Expand Up @@ -118,6 +120,10 @@ class modifier_flag_manager final {
}
}

const std::vector<active_modifier_flag>& get_active_modifier_flags(void) const {
return active_modifier_flags_;
}

size_t active_modifier_flags_size(void) const {
return active_modifier_flags_.size();
}
Expand Down Expand Up @@ -175,6 +181,29 @@ class modifier_flag_manager final {
return modifiers;
}

std::set<modifier_flag> make_modifier_flags(void) const {
std::set<modifier_flag> 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) {
Expand All @@ -193,4 +222,16 @@ class modifier_flag_manager final {

std::vector<active_modifier_flag> 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<modifier_flag_manager::active_modifier_flag>& value) {
for (const auto& v : value) {
stream << v.to_json() << std::endl;
}
return stream;
}
} // namespace krbn
36 changes: 36 additions & 0 deletions src/share/modifier_flag_manager/active_modifier_flag.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
64 changes: 64 additions & 0 deletions src/share/modifier_flag_manager/scoped_modifier_flag.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

class scoped_modifier_flag final {
public:
scoped_modifier_flag(modifier_flag_manager& modifier_flag_manager,
std::set<modifier_flag> 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<active_modifier_flag>& get_scoped_active_modifier_flags(void) const {
return scoped_active_modifier_flags_;
}

std::vector<active_modifier_flag> get_inverse_active_modifier_flags(void) const {
std::vector<active_modifier_flag> 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<active_modifier_flag> scoped_active_modifier_flags_;
};
181 changes: 181 additions & 0 deletions tests/src/modifier_flag_manager/src/scoped_modifier_flags_test.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#pragma once

#include "modifier_flag_manager.hpp"
#include <boost/ut.hpp>

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>({
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>{
modifier_flag::left_shift,
});

expect(std::set<modifier_flag>({
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(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>{
modifier_flag::left_option,
});

expect(std::set<modifier_flag>({
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(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>{
modifier_flag::left_command,
});

expect(std::set<modifier_flag>({
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(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>({}) == modifier_flag_manager.make_modifier_flags());

{
scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set<modifier_flag>{});

expect(std::set<modifier_flag>({}) == 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>({}) == 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>{modifier_flag::caps_lock});

expect(std::set<modifier_flag>({
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(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>({}) == modifier_flag_manager.make_modifier_flags());

{
scoped_modifier_flag scoped_modifier_flag(modifier_flag_manager, std::set<modifier_flag>{modifier_flag::caps_lock});

expect(std::set<modifier_flag>({
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(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());
}
};
}
Loading

0 comments on commit aa92549

Please sign in to comment.