diff --git a/src/core/grabber/include/grabber/device_grabber.hpp b/src/core/grabber/include/grabber/device_grabber.hpp index 4ed957796..7017e561c 100644 --- a/src/core/grabber/include/grabber/device_grabber.hpp +++ b/src/core/grabber/include/grabber/device_grabber.hpp @@ -470,7 +470,7 @@ class device_grabber final : public pqrs::dispatcher::extra::dispatcher_client { if (hid_manager_) { hid_manager_->async_set_device_matched_delay( - profile.get_parameters().get_delay_milliseconds_before_open_device()); + profile.get_parameters()->get_delay_milliseconds_before_open_device()); hid_manager_->async_start(); } diff --git a/src/lib/libkrbn/src/libkrbn_configuration.cpp b/src/lib/libkrbn/src/libkrbn_configuration.cpp index aff85a81d..5d3535abf 100644 --- a/src/lib/libkrbn/src/libkrbn_configuration.cpp +++ b/src/lib/libkrbn/src/libkrbn_configuration.cpp @@ -213,13 +213,13 @@ void libkrbn_core_configuration_erase_profile(size_t index) { int libkrbn_core_configuration_get_selected_profile_parameters_delay_milliseconds_before_open_device(void) { auto c = get_current_core_configuration(); - auto count = c->get_selected_profile().get_parameters().get_delay_milliseconds_before_open_device().count(); + auto count = c->get_selected_profile().get_parameters()->get_delay_milliseconds_before_open_device().count(); return static_cast(count); } void libkrbn_core_configuration_set_selected_profile_parameters_delay_milliseconds_before_open_device(int value) { auto c = get_current_core_configuration(); - c->get_selected_profile().get_parameters().set_delay_milliseconds_before_open_device( + c->get_selected_profile().get_parameters()->set_delay_milliseconds_before_open_device( std::chrono::milliseconds(value)); } diff --git a/src/share/core_configuration/configuration_json_helper.hpp b/src/share/core_configuration/configuration_json_helper.hpp index 2a72b3ea1..60115b444 100644 --- a/src/share/core_configuration/configuration_json_helper.hpp +++ b/src/share/core_configuration/configuration_json_helper.hpp @@ -179,9 +179,16 @@ class object_t final : public base_t { void update_value(const nlohmann::json& json, error_handling error_handling) override { - if (auto v = pqrs::json::find_object(json, key_)) { - value_ = std::make_shared(v->value(), + auto it = json.find(key_); + if (it == std::end(json)) { + return; + } + + try { + value_ = std::make_shared(*it, error_handling); + } catch (pqrs::json::unmarshal_error& e) { + throw pqrs::json::unmarshal_error(fmt::format("`{0}` error: {1}", key_, e.what())); } } diff --git a/src/share/core_configuration/details/global_configuration.hpp b/src/share/core_configuration/details/global_configuration.hpp index 0a3d6a8e1..85f73bcc5 100644 --- a/src/share/core_configuration/details/global_configuration.hpp +++ b/src/share/core_configuration/details/global_configuration.hpp @@ -50,42 +50,42 @@ class global_configuration final { return j; } - bool get_check_for_updates_on_startup(void) const { + const bool& get_check_for_updates_on_startup(void) const { return check_for_updates_on_startup_; } void set_check_for_updates_on_startup(bool value) { check_for_updates_on_startup_ = value; } - bool get_show_in_menu_bar(void) const { + const bool& get_show_in_menu_bar(void) const { return show_in_menu_bar_; } void set_show_in_menu_bar(bool value) { show_in_menu_bar_ = value; } - bool get_show_profile_name_in_menu_bar(void) const { + const bool& get_show_profile_name_in_menu_bar(void) const { return show_profile_name_in_menu_bar_; } void set_show_profile_name_in_menu_bar(bool value) { show_profile_name_in_menu_bar_ = value; } - bool get_enable_notification_window(void) const { + const bool& get_enable_notification_window(void) const { return enable_notification_window_; } void set_enable_notification_window(bool value) { enable_notification_window_ = value; } - bool get_ask_for_confirmation_before_quitting(void) const { + const bool& get_ask_for_confirmation_before_quitting(void) const { return ask_for_confirmation_before_quitting_; } void set_ask_for_confirmation_before_quitting(bool value) { ask_for_confirmation_before_quitting_ = value; } - bool get_unsafe_ui(void) const { + const bool& get_unsafe_ui(void) const { return unsafe_ui_; } void set_unsafe_ui(bool value) { diff --git a/src/share/core_configuration/details/machine_specific.hpp b/src/share/core_configuration/details/machine_specific.hpp index 76d7563ae..7cb15fe61 100644 --- a/src/share/core_configuration/details/machine_specific.hpp +++ b/src/share/core_configuration/details/machine_specific.hpp @@ -33,7 +33,7 @@ class machine_specific final { return j; } - bool get_enable_multitouch_extension(void) const { + const bool& get_enable_multitouch_extension(void) const { return enable_multitouch_extension_; } void set_enable_multitouch_extension(bool value) { diff --git a/src/share/core_configuration/details/profile.hpp b/src/share/core_configuration/details/profile.hpp index d39dd3bb6..b91f18f5b 100644 --- a/src/share/core_configuration/details/profile.hpp +++ b/src/share/core_configuration/details/profile.hpp @@ -20,8 +20,12 @@ class profile final { : json_(json), error_handling_(error_handling), selected_(false), + parameters_(std::make_shared()), simple_modifications_(std::make_shared()), fn_function_keys_(std::make_shared()) { + helper_values_.push_back_object("parameters", + parameters_); + helper_values_.push_back_array("devices", devices_); @@ -50,13 +54,6 @@ class profile final { selected_ = value.get(); - } else if (key == "parameters") { - try { - parameters_ = value.get(); - } catch (const pqrs::json::unmarshal_error& e) { - throw pqrs::json::unmarshal_error(fmt::format("`{0}` error: {1}", key, e.what())); - } - } else if (key == "simple_modifications") { try { simple_modifications_->update(value); @@ -149,7 +146,6 @@ class profile final { j["name"] = name_; j["selected"] = selected_; - j["parameters"] = parameters_; { auto jj = simple_modifications_->to_json(nlohmann::json::array()); @@ -191,14 +187,10 @@ class profile final { selected_ = value; } - const details::parameters& get_parameters(void) const { + gsl::not_null> get_parameters(void) const { return parameters_; } - details::parameters& get_parameters(void) { - return const_cast(static_cast(*this).get_parameters()); - } - gsl::not_null> get_simple_modifications(void) const { return simple_modifications_; } @@ -273,7 +265,7 @@ class profile final { error_handling error_handling_; std::string name_; bool selected_; - details::parameters parameters_; + gsl::not_null> parameters_; gsl::not_null> simple_modifications_; gsl::not_null> fn_function_keys_; details::complex_modifications complex_modifications_; diff --git a/src/share/core_configuration/details/profile/device.hpp b/src/share/core_configuration/details/profile/device.hpp index 2347de533..81c231557 100644 --- a/src/share/core_configuration/details/profile/device.hpp +++ b/src/share/core_configuration/details/profile/device.hpp @@ -282,7 +282,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { return identifiers_; } - bool get_ignore(void) const { + const bool& get_ignore(void) const { return ignore_; } void set_ignore(bool value) { @@ -291,7 +291,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_manipulate_caps_lock_led(void) const { + const bool& get_manipulate_caps_lock_led(void) const { return manipulate_caps_lock_led_; } void set_manipulate_caps_lock_led(bool value) { @@ -300,7 +300,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_treat_as_built_in_keyboard(void) const { + const bool& get_treat_as_built_in_keyboard(void) const { return treat_as_built_in_keyboard_; } void set_treat_as_built_in_keyboard(bool value) { @@ -309,7 +309,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_disable_built_in_keyboard_if_exists(void) const { + const bool& get_disable_built_in_keyboard_if_exists(void) const { return disable_built_in_keyboard_if_exists_; } void set_disable_built_in_keyboard_if_exists(bool value) { @@ -318,7 +318,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_flip_x(void) const { + const bool& get_mouse_flip_x(void) const { return mouse_flip_x_; } void set_mouse_flip_x(bool value) { @@ -327,7 +327,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_flip_y(void) const { + const bool& get_mouse_flip_y(void) const { return mouse_flip_y_; } void set_mouse_flip_y(bool value) { @@ -336,7 +336,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_flip_vertical_wheel(void) const { + const bool& get_mouse_flip_vertical_wheel(void) const { return mouse_flip_vertical_wheel_; } void set_mouse_flip_vertical_wheel(bool value) { @@ -345,7 +345,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_flip_horizontal_wheel(void) const { + const bool& get_mouse_flip_horizontal_wheel(void) const { return mouse_flip_horizontal_wheel_; } void set_mouse_flip_horizontal_wheel(bool value) { @@ -354,7 +354,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_swap_xy(void) const { + const bool& get_mouse_swap_xy(void) const { return mouse_swap_xy_; } void set_mouse_swap_xy(bool value) { @@ -363,7 +363,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_swap_wheels(void) const { + const bool& get_mouse_swap_wheels(void) const { return mouse_swap_wheels_; } void set_mouse_swap_wheels(bool value) { @@ -372,7 +372,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_discard_x(void) const { + const bool& get_mouse_discard_x(void) const { return mouse_discard_x_; } void set_mouse_discard_x(bool value) { @@ -381,7 +381,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_discard_y(void) const { + const bool& get_mouse_discard_y(void) const { return mouse_discard_y_; } void set_mouse_discard_y(bool value) { @@ -390,7 +390,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_discard_vertical_wheel(void) const { + const bool& get_mouse_discard_vertical_wheel(void) const { return mouse_discard_vertical_wheel_; } void set_mouse_discard_vertical_wheel(bool value) { @@ -399,7 +399,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_mouse_discard_horizontal_wheel(void) const { + const bool& get_mouse_discard_horizontal_wheel(void) const { return mouse_discard_horizontal_wheel_; } void set_mouse_discard_horizontal_wheel(bool value) { @@ -408,7 +408,7 @@ if (abs(cos(radian)) <= abs(sin(radian))) { coordinate_between_properties(); } - bool get_game_pad_swap_sticks(void) const { + const bool& get_game_pad_swap_sticks(void) const { return game_pad_swap_sticks_; } void set_game_pad_swap_sticks(bool value) { diff --git a/src/share/core_configuration/details/profile/parameters.hpp b/src/share/core_configuration/details/profile/parameters.hpp index 3a1a9d013..a2ad31f19 100644 --- a/src/share/core_configuration/details/profile/parameters.hpp +++ b/src/share/core_configuration/details/profile/parameters.hpp @@ -1,5 +1,6 @@ #pragma once +#include "../../configuration_json_helper.hpp" #include "types.hpp" namespace krbn { @@ -7,19 +8,34 @@ namespace core_configuration { namespace details { class parameters final { public: - parameters(void) : json_(nlohmann::json::object()), - delay_milliseconds_before_open_device_(1000) { + parameters(const parameters&) = delete; + + parameters(void) + : parameters(nlohmann::json::object(), + krbn::core_configuration::error_handling::loose) { } - const nlohmann::json& get_json(void) const { - return json_; + parameters(const nlohmann::json& json, + error_handling error_handling) + : json_(json) { + helper_values_.push_back_value("delay_milliseconds_before_open_device", + delay_milliseconds_before_open_device_, + std::chrono::milliseconds(1000)); + + pqrs::json::requires_object(json, "json"); + + helper_values_.update_value(json, error_handling); } - void set_json(const nlohmann::json& value) { - json_ = value; + nlohmann::json to_json(void) const { + auto j = json_; + + helper_values_.update_json(j); + + return j; } - std::chrono::milliseconds get_delay_milliseconds_before_open_device(void) const { + const std::chrono::milliseconds& get_delay_milliseconds_before_open_device(void) const { return delay_milliseconds_before_open_device_; } @@ -34,30 +50,8 @@ class parameters final { private: nlohmann::json json_; std::chrono::milliseconds delay_milliseconds_before_open_device_; + configuration_json_helper::helper_values helper_values_; }; - -inline void to_json(nlohmann::json& json, const parameters& value) { - json = value.get_json(); - json["delay_milliseconds_before_open_device"] = value.get_delay_milliseconds_before_open_device().count(); -} - -inline void from_json(const nlohmann::json& json, parameters& value) { - pqrs::json::requires_object(json, "json"); - - for (const auto& [k, v] : json.items()) { - if (k == "delay_milliseconds_before_open_device") { - pqrs::json::requires_number(v, "`" + k + "`"); - - value.set_delay_milliseconds_before_open_device(std::chrono::milliseconds(v.get())); - - } else { - // Allow unknown keys in order to be able to load - // newer version of karabiner.json with older Karabiner-Elements. - } - } - - value.set_json(json); -} } // namespace details } // namespace core_configuration } // namespace krbn diff --git a/tests/src/core_configuration/json/to_json_default.json b/tests/src/core_configuration/json/to_json_default.json index af7d2e682..29a11aedc 100644 --- a/tests/src/core_configuration/json/to_json_default.json +++ b/tests/src/core_configuration/json/to_json_default.json @@ -12,9 +12,6 @@ } }, "name": "Default profile", - "parameters": { - "delay_milliseconds_before_open_device": 1000 - }, "selected": true, "virtual_hid_keyboard": { "country_code": 0, diff --git a/tests/src/core_configuration/json/to_json_example.json b/tests/src/core_configuration/json/to_json_example.json index 07baa10bd..af8459727 100644 --- a/tests/src/core_configuration/json/to_json_example.json +++ b/tests/src/core_configuration/json/to_json_example.json @@ -261,9 +261,6 @@ "rules": [] }, "name": "Empty", - "parameters": { - "delay_milliseconds_before_open_device": 1000 - }, "selected": false, "virtual_hid_keyboard": { "country_code": 0, @@ -295,9 +292,6 @@ } ], "name": "fn_function_keys v1", - "parameters": { - "delay_milliseconds_before_open_device": 1000 - }, "selected": false, "virtual_hid_keyboard": { "country_code": 0, @@ -317,9 +311,6 @@ "rules": [] }, "name": "simple_modifications v2", - "parameters": { - "delay_milliseconds_before_open_device": 1000 - }, "selected": false, "simple_modifications": [ { diff --git a/tests/src/core_configuration/src/core_configuration_test.hpp b/tests/src/core_configuration/src/core_configuration_test.hpp index f64061494..57bb3e839 100644 --- a/tests/src/core_configuration/src/core_configuration_test.hpp +++ b/tests/src/core_configuration/src/core_configuration_test.hpp @@ -685,9 +685,6 @@ void run_core_configuration_test(void) { })}, {"name", ""}, {"selected", false}, - {"parameters", nlohmann::json::object({ - {"delay_milliseconds_before_open_device", 1000}, - })}, {"virtual_hid_keyboard", get_default_virtual_hid_keyboard_json()}, }); expect(empty_profile.to_json() == expected) << UT_SHOW_LINE; @@ -728,7 +725,7 @@ void run_core_configuration_test(void) { profile.set_name("profile 1"); profile.set_selected(true); - profile.get_parameters().set_delay_milliseconds_before_open_device(std::chrono::milliseconds(500)); + profile.get_parameters()->set_delay_milliseconds_before_open_device(std::chrono::milliseconds(500)); profile.get_simple_modifications()->push_back_pair(); // { diff --git a/tests/src/core_configuration/src/errors_test.hpp b/tests/src/core_configuration/src/errors_test.hpp index 0c231afdc..7eb0a50a3 100644 --- a/tests/src/core_configuration/src/errors_test.hpp +++ b/tests/src/core_configuration/src/errors_test.hpp @@ -14,7 +14,8 @@ void handle_json(const nlohmann::json& json) { krbn::core_configuration::details::device(json.at("input"), krbn::core_configuration::error_handling::strict); } else if (c == "parameters") { - json.at("input").get(); + krbn::core_configuration::details::parameters(json.at("input"), + krbn::core_configuration::error_handling::strict); } else if (c == "profile") { krbn::core_configuration::details::profile(json.at("input"), krbn::core_configuration::error_handling::strict);