From 63ec195c36dc331cd77df721d45449a642e8a546 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 1 Dec 2018 19:59:51 +0100 Subject: wandad: implement command handler for change --- src/command.cpp | 10 ++++++++++ src/command.hpp | 3 +++ src/commander.cpp | 6 ++++++ src/commander.hpp | 1 + src/control_interface.cpp | 14 ++++++++++---- src/control_interface.hpp | 13 ++++++++++--- src/wallpaper.hpp | 2 +- src/wandac.cpp | 1 + src/wandad.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ 9 files changed, 80 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/command.cpp b/src/command.cpp index 092d69d..05784b3 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -30,4 +30,14 @@ std::optional command::message() const return wanda::message{"C", command, argument_string}; } +std::optional make_command(message message) +{ + if(message.command == "CHANGE") + { + return {{command_id::change}}; + } + + return std::nullopt; +} + } // namespace wanda \ No newline at end of file diff --git a/src/command.hpp b/src/command.hpp index f4d7b31..54bf02d 100644 --- a/src/command.hpp +++ b/src/command.hpp @@ -21,6 +21,9 @@ struct command std::optional message() const; }; + +std::optional make_command(message message); + } // namespace wanda #endif \ No newline at end of file diff --git a/src/commander.cpp b/src/commander.cpp index 83f3943..e2bf8c7 100644 --- a/src/commander.cpp +++ b/src/commander.cpp @@ -34,6 +34,12 @@ void commander::start() }); } +void commander::stop() +{ + m_logger->info("closing control connection"); + m_connection->close(); +} + void commander::send(command command) { using namespace wanda::std_ext; diff --git a/src/commander.hpp b/src/commander.hpp index 57041a0..980573f 100644 --- a/src/commander.hpp +++ b/src/commander.hpp @@ -29,6 +29,7 @@ struct commander : wanda::control_connection::listener commander(asio::io_service &service, std::filesystem::path socket, listener & listener, std::shared_ptr logger); void start(); + void stop(); void send(command command); void on_error(control_connection::pointer connection, std::error_code error) override; diff --git a/src/control_interface.cpp b/src/control_interface.cpp index b8ca58e..0a98553 100644 --- a/src/control_interface.cpp +++ b/src/control_interface.cpp @@ -1,4 +1,5 @@ #include "control_interface.hpp" +#include "optional.hpp" #include @@ -25,12 +26,13 @@ socket_deleter::~socket_deleter() // 'control_interface' implementation -control_interface::control_interface(control_interface::key key, asio::io_service &service, control_interface::protocol::endpoint endpoint, std::shared_ptr logger) +control_interface::control_interface(control_interface::key key, asio::io_service &service, control_interface::protocol::endpoint endpoint, listener & listener, std::shared_ptr logger) : keyed{key}, m_service{service}, m_endpoint{std::move(endpoint)}, m_socket{m_service}, m_acceptor{m_service}, + m_listener{listener}, m_logger{logger} { } @@ -105,6 +107,8 @@ void control_interface::on_close(control_connection::pointer connection) void control_interface::on_received(control_connection::pointer connection, message message) { + using namespace wanda::std_ext; + if (m_connections.find(connection) == m_connections.cend()) { m_logger->error("received message from an unknown connection"); @@ -129,11 +133,13 @@ void control_interface::on_received(control_connection::pointer connection, mess } else { - m_logger->warn("ignoring unknown message '{}'", message); + with(make_command(message), [&](auto const & command){ + m_listener.on_received(*this, command); + }) || [&] { m_logger->warn("ignoring unknown message '{}'", message); }; } } -control_interface::pointer make_interface(asio::io_service &service, std::filesystem::path file, std::shared_ptr logger) +control_interface::pointer make_interface(asio::io_service &service, std::filesystem::path file, control_interface::listener & listener, std::shared_ptr logger) { if (std::filesystem::exists(file)) { @@ -142,7 +148,7 @@ control_interface::pointer make_interface(asio::io_service &service, std::filesy } control_interface::protocol::endpoint endpoint{file.string()}; - return std::make_shared(control_interface::key{}, service, std::move(endpoint), logger); + return std::make_shared(control_interface::key{}, service, std::move(endpoint), listener, logger); } } // namespace wanda \ No newline at end of file diff --git a/src/control_interface.hpp b/src/control_interface.hpp index 35f7f4f..2ac32be 100644 --- a/src/control_interface.hpp +++ b/src/control_interface.hpp @@ -1,6 +1,7 @@ #ifndef WANDA_CONTROL_INTERFACE_HPP #define WANDA_CONTROL_INTERFACE_HPP +#include "command.hpp" #include "control_connection.hpp" #include "keyed.hpp" @@ -32,7 +33,12 @@ struct control_interface : control_connection::listener, keyed; - control_interface(key, asio::io_service &service, protocol::endpoint endpoint, std::shared_ptr logger); + struct listener + { + virtual void on_received(control_interface & interface, command command) { }; + }; + + control_interface(key, asio::io_service &service, protocol::endpoint endpoint, listener & listener, std::shared_ptr logger); std::error_code start(); std::error_code shutdown(); @@ -43,18 +49,19 @@ struct control_interface : control_connection::listener, keyed logger); + friend pointer make_interface(asio::io_service &service, std::filesystem::path file, control_interface::listener & listener, std::shared_ptr logger); asio::io_service &m_service; protocol::endpoint m_endpoint; protocol::socket m_socket; protocol::acceptor m_acceptor; + listener & m_listener; socket_deleter m_deleter{m_endpoint.path()}; std::set m_connections; std::shared_ptr m_logger; }; -control_interface::pointer make_interface(asio::io_service &service, std::filesystem::path file, std::shared_ptr logger); +control_interface::pointer make_interface(asio::io_service &service, std::filesystem::path file, control_interface::listener & listener, std::shared_ptr logger); } // namespace wanda diff --git a/src/wallpaper.hpp b/src/wallpaper.hpp index 5dbd5d0..8017d65 100644 --- a/src/wallpaper.hpp +++ b/src/wallpaper.hpp @@ -10,7 +10,7 @@ namespace wanda { -void set_wallpaper(std::filesystem::path wallpaper, std::shared_ptr logger = spdlog::create("null")); +void set_wallpaper(std::filesystem::path wallpaper, std::shared_ptr logger); } // wanda diff --git a/src/wandac.cpp b/src/wandac.cpp index e2da2a1..0f1d15d 100644 --- a/src/wandac.cpp +++ b/src/wandac.cpp @@ -61,6 +61,7 @@ struct listener : wanda::commander::listener if (m_cli.command == "change") { commander.send({wanda::command_id::change}); + commander.stop(); } } diff --git a/src/wandad.cpp b/src/wandad.cpp index af2e3f2..6008b57 100644 --- a/src/wandad.cpp +++ b/src/wandad.cpp @@ -1,3 +1,4 @@ +#include "command.hpp" #include "control_interface.hpp" #include "environment.hpp" #include "filesystem.hpp" @@ -32,6 +33,35 @@ constexpr auto image_filter = [](auto const &path) { return extensions.find(path.extension()) != extensions.cend(); }; +struct listener : wanda::control_interface::listener +{ + listener(std::vector const &wallpapers, std::shared_ptr logger) + : m_wallpapers{wallpapers}, + m_logger{logger} + { + } + + void on_received(wanda::control_interface &interface, wanda::command command) override + { + switch (command.id) + { + case wanda::command_id::change: + { + auto wallpaper = wanda::random_pick(m_wallpapers); + m_logger->info("changing wallpaper to '{}'", wallpaper.native()); + wanda::set_wallpaper(wallpaper, m_logger); + break; + } + default: + m_logger->error("received unknown command '{}'", static_cast(command.id)); + } + } + +private: + std::vector const &m_wallpapers; + std::shared_ptr m_logger; +}; + } // namespace int main() @@ -42,16 +72,14 @@ int main() log->info("wanda is starting up"); with(wanda::scan({"/usr/share/backgrounds"}, image_filter), [&](auto const &list) { - auto wallpaper = wanda::random_pick(list); - wanda::set_wallpaper(wallpaper); - auto service = asio::io_service{}; auto socket_path = wanda::xdg_path_for(wanda::xdg_directory::runtime_dir, wanda::environment{}) / ".wanda_interface"; log->info("starting control interface on '{}'", socket_path.native()); - auto interface = wanda::make_interface(service, socket_path, log); + auto listener = ::listener{list, log}; + auto interface = wanda::make_interface(service, socket_path, listener, log); - if(!interface) + if (!interface) { log->error("failed to start control interface"); return; @@ -71,6 +99,10 @@ int main() } }); + auto wallpaper = wanda::random_pick(list); + wanda::set_wallpaper(wallpaper, log); + service.run(); - }) || [&] { log->error("wallpaper directory does not exist"); }; + }) || + [&] { log->error("wallpaper directory does not exist"); }; } -- cgit v1.2.3