diff --git a/source/Client.cpp b/source/Client.cpp index f6c7a6e..75243d0 100644 --- a/source/Client.cpp +++ b/source/Client.cpp @@ -27,9 +27,9 @@ using json = nlohmann::json; constexpr std::string_view api_url {"https://api.spotify.com"}; -Client::Client(token_t token_info, const Config& config) +Client::Client(token_t token_info, Config config) : m_token_info(std::move(token_info)) - , m_config(config) + , m_config(std::move(config)) { } diff --git a/source/Client.h b/source/Client.h index a525ae4..dde5c24 100644 --- a/source/Client.h +++ b/source/Client.h @@ -18,7 +18,7 @@ using json = nlohmann::json; class Client { public: - Client(token_t token_info, const Config& config); + Client(token_t token_info, Config config); [[nodiscard]] cpr::Response api_request(std::string_view endpoint); [[nodiscard]] cpr::Response put_api_request(std::string_view endpoint, const cpr::Payload& payload); diff --git a/source/Config.cpp b/source/Config.cpp index 237b6d3..694b0b2 100644 --- a/source/Config.cpp +++ b/source/Config.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -26,9 +27,12 @@ constexpr std::string_view volume_increment_key = "volume_increment"; constexpr std::string_view volume_up_key = "volume_up"; constexpr std::string_view volume_down_key = "volume_down"; constexpr std::string_view batch_delay_key = "batch_delay_ms"; +constexpr std::string_view poll_rate_key = "poll_rate_ms"; constexpr std::chrono::milliseconds default_batch_delay {100}; constexpr uint32_t default_volume_increment = 1; +constexpr std::chrono::milliseconds default_poll_rate {250}; +constexpr std::chrono::milliseconds min_poll_rate {100}; Config::Config() { @@ -89,6 +93,7 @@ void Config::parse_config_file(const std::filesystem::path& path) m_config[volume_increment_key] = default_volume_increment; m_config[batch_delay_key] = default_batch_delay.count(); + m_config[poll_rate_key] = default_poll_rate.count(); new_config_file << m_config; new_config_file.close(); @@ -188,6 +193,11 @@ std::chrono::milliseconds Config::batch_delay() const return std::chrono::milliseconds(m_config.value(batch_delay_key, default_batch_delay.count())); } +std::chrono::milliseconds Config::poll_rate() const +{ + return std::max(std::chrono::milliseconds(m_config.value(poll_rate_key, default_poll_rate.count())), min_poll_rate); +} + void Config::get_user_input(const std::string_view prompt, std::string& input, bool not_empty) { input.clear(); diff --git a/source/Config.h b/source/Config.h index 1b506c0..7b8d708 100644 --- a/source/Config.h +++ b/source/Config.h @@ -33,6 +33,7 @@ class Config keycode get_volume_down() const; volume volume_increment() const; std::chrono::milliseconds batch_delay() const; + std::chrono::milliseconds poll_rate() const; bool is_default_down() const; bool is_default_up() const; diff --git a/source/VolumeController.cpp b/source/VolumeController.cpp index 19a6a36..9c044ab 100644 --- a/source/VolumeController.cpp +++ b/source/VolumeController.cpp @@ -29,6 +29,7 @@ VolumeController::VolumeController(const Config& config, Client& client) , m_volume_up_keycode(config.is_default_up() ? VK_VOLUME_UP : config.get_volume_up()) , m_volume_down_keycode(config.is_default_down() ? VK_VOLUME_DOWN : config.get_volume_down()) , m_client_thread(std::thread(&VolumeController::set_volume_loop, this)) + , m_update_current_volume_thread(std::jthread(&VolumeController::update_current_volume_loop, this)) { } @@ -43,15 +44,10 @@ void VolumeController::set_desktop_device() m_desktop_device_id = desktop; } -[[nodiscard]] volume VolumeController::get_volume() const -{ - return m_volume; -} - void VolumeController::decrease_volume() { { - std::unique_lock const lock(m_volume_mutex); + std::lock_guard const lock(m_volume_mutex); // Assume that the API call will succeed m_volume = m_volume - m_config.volume_increment(); m_volume_queue.push(m_volume); @@ -66,7 +62,7 @@ void VolumeController::decrease_volume() void VolumeController::increase_volume() { { - std::unique_lock const lock(m_volume_mutex); + std::lock_guard const lock(m_volume_mutex); // Assume that the API call will succeed m_volume = m_volume + m_config.volume_increment(); m_volume_queue.push(m_volume); @@ -117,16 +113,6 @@ void VolumeController::print_keys() key_hooks::start_print_vkey(); } -[[nodiscard]] keycode VolumeController::volume_up_keycode() const -{ - return m_volume_up_keycode; -} - -[[nodiscard]] keycode VolumeController::volume_down_keycode() const -{ - return m_volume_down_keycode; -} - void VolumeController::set_volume_loop() { while (true) { @@ -141,4 +127,22 @@ void VolumeController::set_volume_loop() } } +void VolumeController::update_current_volume_loop() +{ + while (true) { + { + std::lock_guard const lock(m_volume_mutex); + if (m_volume_queue.empty()) { + std::optional current_volume = m_client.get_current_playing_volume(); + if (current_volume.has_value()) { + { + m_volume = current_volume.value(); + } + } + } + } + std::this_thread::sleep_for(m_config.poll_rate()); + } +} + } // namespace spotify_volume_controller diff --git a/source/VolumeController.h b/source/VolumeController.h index 23215e9..d0da8db 100644 --- a/source/VolumeController.h +++ b/source/VolumeController.h @@ -50,9 +50,9 @@ class VolumeController void set_desktop_device(); - [[nodiscard]] volume get_volume() const; - [[nodiscard]] keycode volume_up_keycode() const; - [[nodiscard]] keycode volume_down_keycode() const; + [[nodiscard]] volume get_volume() const { return m_volume; } + [[nodiscard]] keycode volume_up_keycode() const { return m_volume_up_keycode; } + [[nodiscard]] keycode volume_down_keycode() const { return m_volume_down_keycode; } void decrease_volume(); void increase_volume(); @@ -63,14 +63,18 @@ class VolumeController void set_volume(volume new_volume); void set_volume_loop(); void set_volume_to_desktop_device_volume(); + void update_current_volume_loop(); volume m_volume; const Config m_config; Client m_client; const keycode m_volume_up_keycode; const keycode m_volume_down_keycode; std::optional m_desktop_device_id; + std::thread m_client_thread; + std::jthread m_update_current_volume_thread; std::jthread m_notify_timer_thread; + std::mutex m_volume_mutex; std::condition_variable m_volume_cv; std::queue m_volume_queue;