aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/command.hpp17
-rw-r--r--src/commander.hpp21
-rw-r--r--src/control_connection.hpp29
-rw-r--r--src/control_interface.cpp8
-rw-r--r--src/control_interface.hpp33
-rw-r--r--src/deferred_failure.hpp7
-rw-r--r--src/environment.hpp23
-rw-r--r--src/expected.hpp9
-rw-r--r--src/filesystem.hpp23
-rw-r--r--src/keyed.hpp9
-rw-r--r--src/logging.hpp17
-rw-r--r--src/message.hpp48
-rw-r--r--src/optional.hpp24
-rw-r--r--src/setting.hpp8
-rw-r--r--src/type_wrapper.hpp21
-rw-r--r--src/wallpaper.hpp9
-rw-r--r--src/xdg.hpp6
17 files changed, 284 insertions, 28 deletions
diff --git a/src/command.hpp b/src/command.hpp
index 37afaae..afc6a6f 100644
--- a/src/command.hpp
+++ b/src/command.hpp
@@ -9,21 +9,36 @@
namespace wanda
{
+ /**
+ * @brief An enum to describe different command IDs
+ */
enum struct command_id : char
{
- change,
+ change, //< Change the wallpaper
};
+ /**
+ * @brief A simple type to represent commands transported through the control connection
+ */
struct command
{
command_id const id;
std::vector<std::string> const arguments;
+ /**
+ * @brief Convert the command to a message for transmission to a remote endpoint
+ */
std::optional<wanda::message> message() const;
};
+ /**
+ * @brief Extract a command from a message
+ */
std::optional<command> make_command(message message);
+ /**
+ * @brief A simple factory to create a "Change wallpaper" command
+ */
command make_change_command();
} // namespace wanda
diff --git a/src/commander.hpp b/src/commander.hpp
index 131022d..42a2ab6 100644
--- a/src/commander.hpp
+++ b/src/commander.hpp
@@ -15,8 +15,15 @@
namespace wanda
{
+ /**
+ * @brief The remote control client
+ *
+ */
struct commander : wanda::control_connection::listener
{
+ /**
+ * @brief The interface to be implemented by remote control listeners
+ */
struct listener
{
virtual void on_connected(commander & commander){};
@@ -24,10 +31,24 @@ namespace wanda
virtual void on_error(commander & commander, std::string error){};
};
+ /**
+ * @brief Construct a new commander
+ */
commander(asio::io_service & service, std::filesystem::path socket, listener & listener);
+ /**
+ * @brief Start communication with the remote daemon endpoint
+ */
void start();
+
+ /**
+ * @brief Stop communication with the remote daemon endpoint
+ */
void stop();
+
+ /**
+ * @brief Send a command to the remote daemon endpoint
+ */
void send(command command);
void on_error(control_connection::pointer connection, std::error_code error) override;
diff --git a/src/control_connection.hpp b/src/control_connection.hpp
index 8ed60f0..9e3ad62 100644
--- a/src/control_connection.hpp
+++ b/src/control_connection.hpp
@@ -15,11 +15,17 @@
namespace wanda
{
+ /**
+ * @brief A connection to a remote control endpoint
+ */
struct control_connection : keyed<control_connection>, std::enable_shared_from_this<control_connection>
{
using protocol = asio::local::stream_protocol;
using pointer = std::shared_ptr<control_connection>;
+ /**
+ * @brief The interface to be implemented by the control interface listener
+ */
struct listener
{
virtual void on_close(pointer connection) {}
@@ -27,18 +33,21 @@ namespace wanda
virtual void on_error(pointer connection, std::error_code) {}
};
+ /**
+ * @brief A enum to describe different connection states
+ */
enum struct state : std::underlying_type_t<std::byte>
{
- unknown,
- fresh,
- established,
+ unknown, //< Connection is in an unknown state
+ fresh, //< Connection is freshly created but not established
+ established, //< Connection has been established
};
/**
* @internal
* @brief Construct a new control connection object
*
- * @param socket The socket connected to the remote control endpoint
+ * @note This constructor is keyed on a private key type so it can only be constructed using the #wanda::make_connection factory
*/
control_connection(key, protocol::socket socket);
@@ -66,10 +75,19 @@ namespace wanda
*/
void close();
+ /**
+ * @brief Send the given message to the remote endpoint
+ */
void send(message message);
+ /**
+ * @brief Set the connection state to the provided state
+ */
void update(state state);
+ /**
+ * @brief Get the current connection state
+ */
state current_state() const;
private:
@@ -86,6 +104,9 @@ namespace wanda
state m_state{};
};
+ /**
+ * @brief Create a new control connection
+ */
control_connection::pointer make_control_connection(control_connection::protocol::socket && socket);
} // namespace wanda
diff --git a/src/control_interface.cpp b/src/control_interface.cpp
index ff96cd3..81e10cf 100644
--- a/src/control_interface.cpp
+++ b/src/control_interface.cpp
@@ -139,15 +139,15 @@ namespace wanda
}
}
- control_interface::pointer make_interface(asio::io_service & service, std::filesystem::path file, control_interface::listener & listener)
+ control_interface::pointer make_interface(asio::io_service & service, std::filesystem::path socket, control_interface::listener & listener)
{
- if (std::filesystem::exists(file))
+ if (std::filesystem::exists(socket))
{
- get_logger()->error("file '{}' exists", file.native());
+ get_logger()->error("socket '{}' exists", socket.native());
return {};
}
- control_interface::protocol::endpoint endpoint{file.string()};
+ control_interface::protocol::endpoint endpoint{socket.string()};
return std::make_shared<control_interface>(control_interface::key{}, service, std::move(endpoint), listener);
}
diff --git a/src/control_interface.hpp b/src/control_interface.hpp
index 82cc2af..3d11fdf 100644
--- a/src/control_interface.hpp
+++ b/src/control_interface.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file environment.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_CONTROL_INTERFACE_HPP
#define WANDA_CONTROL_INTERFACE_HPP
@@ -19,6 +25,9 @@
namespace wanda
{
+ /**
+ * @brief An RAII type to delete a socket file upon destruction
+ */
struct socket_deleter
{
~socket_deleter();
@@ -26,19 +35,38 @@ namespace wanda
std::filesystem::path path;
};
+ /**
+ * @brief The daemon control interface
+ */
struct control_interface : control_connection::listener, keyed<control_interface>, std::enable_shared_from_this<control_interface>
{
using protocol = asio::local::stream_protocol;
using pointer = std::shared_ptr<control_interface>;
+ /**
+ * @brief The interface to be implemented by the control interface listener
+ */
struct listener
{
virtual void on_received(control_interface & interface, command command){};
};
+ /**
+ * @internal
+ * @brief Construct a new control interface object
+ *
+ * @note This constructor is keyed on a private key type so it can only be constructed using the #wanda::make_interface factory
+ */
control_interface(key, asio::io_service & service, protocol::endpoint endpoint, listener & listener);
+ /**
+ * @brief Start handling of controller connections
+ */
std::error_code start();
+
+ /**
+ * @brief Stop the control interface
+ */
std::error_code shutdown();
void on_close(control_connection::pointer connection) override;
@@ -58,7 +86,10 @@ namespace wanda
std::set<control_connection::pointer> m_connections;
};
- control_interface::pointer make_interface(asio::io_service & service, std::filesystem::path file, control_interface::listener & listener);
+ /**
+ * @brief A factory to create new #control_interface instances
+ */
+ control_interface::pointer make_interface(asio::io_service & service, std::filesystem::path socket, control_interface::listener & listener);
} // namespace wanda
diff --git a/src/deferred_failure.hpp b/src/deferred_failure.hpp
index 8039286..5db26f6 100644
--- a/src/deferred_failure.hpp
+++ b/src/deferred_failure.hpp
@@ -1,7 +1,7 @@
/**
- * @file deferred_failure.hpp
+ * @file deferred_failure.hpp
* @author Felix Morgner (felix.morgner@gmail.com)
- * @since 1.0.0
+ * @since 1.0.0
*/
#ifndef WANDA_DEFERRED_FAILURE_HPP
@@ -11,6 +11,9 @@
namespace
{
+ /**
+ * @brief A helper type to defer static_assert failures
+ */
template<typename...>
using deferred_failure = std::false_type;
} // namespace
diff --git a/src/environment.hpp b/src/environment.hpp
index 1b5bd80..5a702a8 100644
--- a/src/environment.hpp
+++ b/src/environment.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file environment.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_ENVIRONMENT_HPP
#define WANDA_ENVIRONMENT_HPP
@@ -8,6 +14,9 @@
namespace wanda
{
+ /**
+ * @brief A type to provide access to the runtime environment
+ */
struct environment
{
using map_type = std::map<std::string, std::string>;
@@ -16,9 +25,23 @@ namespace wanda
using reference = map_type::reference;
using const_reference = map_type::const_reference;
+ /**
+ * @brief Construct a new environment from the given string array
+ */
explicit environment(char const * const * env = ::environ);
+ /**
+ * @brief Get the value of the given variable
+ *
+ * @return A mutable reference to the value of the given environment variable
+ */
std::string & operator[](std::string const & variable);
+
+ /**
+ * @brief Get the value of the given variable
+ *
+ * @return An immutable reference to the value of the given environment variable
+ */
std::string const & operator[](std::string const & variable) const;
iterator begin();
diff --git a/src/expected.hpp b/src/expected.hpp
index 4555d92..fff0d81 100644
--- a/src/expected.hpp
+++ b/src/expected.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file expected.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_EXPECTED_HPP
#define WANDA_EXPECTED_HPP
@@ -7,6 +13,9 @@
namespace wanda
{
+ /**
+ * @brief A type to represent the error case of a computation based on #wanda::expected
+ */
template<typename ErrorType>
struct unexpected
{
diff --git a/src/filesystem.hpp b/src/filesystem.hpp
index 5b2334a..1975bc5 100644
--- a/src/filesystem.hpp
+++ b/src/filesystem.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file filesystem.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_FILESYSTEM_HPP
#define WANDA_FILESYSTEM_HPP
@@ -8,27 +14,26 @@
namespace wanda
{
/**
- * @brief Covenience alias for path lists
- */
+ * @brief Covenience alias for path lists
+ */
using path_list = std::vector<std::filesystem::path>;
/**
- * @brief The default scan filter, allowing only regular files to pass
- */
+ * @brief The default scan filter, allowing only regular files to pass
+ */
constexpr inline auto default_filter = [](std::filesystem::path const & path) {
return is_regular_file(path);
};
/**
- * @brief Scan the given folder for files
- */
+ * @brief Scan the given folder for files
+ */
std::optional<path_list> scan(std::filesystem::path folder, bool(filter)(std::filesystem::path const &) = default_filter);
/**
- * @brief Pick a random path from the given list
- */
+ * @brief Pick a random path from the given list
+ */
std::filesystem::path random_pick(path_list const & paths);
-
} // namespace wanda
#endif \ No newline at end of file
diff --git a/src/keyed.hpp b/src/keyed.hpp
index d8b22b8..58f17ad 100644
--- a/src/keyed.hpp
+++ b/src/keyed.hpp
@@ -1,8 +1,17 @@
+/**
+ * @file keyed.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_KEYED_HPP
#define WANDA_KEYED_HPP
namespace wanda
{
+ /**
+ * @brief A tag type to prevent construction of a type without a factory
+ */
template<typename Derived>
struct keyed
{
diff --git a/src/logging.hpp b/src/logging.hpp
index 46432b8..b3c1665 100644
--- a/src/logging.hpp
+++ b/src/logging.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file logging.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_LOGGING_HPP
#define WANDA_LOGGING_HPP
@@ -8,10 +14,21 @@
namespace wanda
{
+ /**
+ * @brief A covenience alias to represent a handle for a logger
+ */
using logger_ptr = std::shared_ptr<spdlog::logger>;
+ /**
+ * @brief Initialize the shared logger
+ *
+ * @note The logger will only ever be initialized once, even if this function is called multiple times
+ */
void initialize_logger(spdlog::sink_ptr sink = std::make_shared<spdlog::sinks::null_sink_st>());
+ /**
+ * @brief Get the shared logger
+ */
logger_ptr get_logger();
} // namespace wanda
diff --git a/src/message.hpp b/src/message.hpp
index 86a455c..866408f 100644
--- a/src/message.hpp
+++ b/src/message.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file message.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_MESSAGE_HPP
#define WANDA_MESSAGE_HPP
@@ -10,26 +16,66 @@ namespace wanda
{
inline namespace v1
{
+ /**
+ * @brief The version argument for the hello message reflecting the current version
+ */
auto constexpr message_argument_hello = "1.0.0";
- }
+ } // namespace v1
+ /**
+ * @brief A tag to mark messages originating from the controller
+ */
auto constexpr message_source_controller = "C";
+
+ /**
+ * @brief A tag to mark messages originating from the daemon
+ */
auto constexpr message_source_daemon = "D";
+ /**
+ * @brief The command of the hello message
+ */
auto constexpr message_command_hello = "HELLO";
+ /**
+ * @brief A control protocol message, consisting of a @p source, @p command, and @p arguments
+ */
struct message
{
+ /**
+ * @brief Serialize this message into a string
+ */
explicit operator std::string() const;
+ /**
+ * @brief Get the size of the message as if it was serialized
+ */
std::size_t size() const;
+ /**
+ * @brief The source of the message
+ */
std::string source;
+
+ /**
+ * @brief The command of the message
+ */
std::string command;
+
+ /**
+ * @brief The arguments of the message command
+ */
std::optional<std::string> argument;
};
+ /**
+ * @brief Deserialize a message from the given stream
+ */
std::istream & operator>>(std::istream & in, message & message);
+
+ /**
+ * @brief Serialize a message to the given stream
+ */
std::ostream & operator<<(std::ostream & out, message const & message);
} // namespace wanda
diff --git a/src/optional.hpp b/src/optional.hpp
index 3c964db..da3774c 100644
--- a/src/optional.hpp
+++ b/src/optional.hpp
@@ -1,7 +1,7 @@
/**
- * @file optional.hpp
+ * @file optional.hpp
* @author Felix Morgner (felix.morgner@gmail.com)
- * @since 1.0.0
+ * @since 1.0.0
*/
#ifndef WANDA_OPTIONAL_HPP
@@ -11,13 +11,26 @@
namespace wanda::std_ext
{
+ /**
+ * @brief A type to represent a computation that could fail
+ */
struct failable
{
+ /**
+ * @brief A factory to create a successful computation
+ */
constexpr static auto success() { return failable{false}; }
+
+ /**
+ * @brief A factory to create a failed computation
+ */
constexpr static auto failure() { return failable{true}; }
+ /**
+ * @brief Execute the given handler if the computation failed
+ */
template<typename Handler>
- constexpr auto operator||(Handler handler) const
+ constexpr void operator||(Handler handler) const
{
if (m_failed)
{
@@ -31,6 +44,11 @@ namespace wanda::std_ext
bool const m_failed;
};
+ /**
+ * @brief Unwrap the given optional object, if present, and pass it to the handler
+ *
+ * @return A successful computation iff. the object was present, a failed computation otherwise.
+ */
template<typename ObjectType, typename HandlerType>
auto with(std::optional<ObjectType> && object, HandlerType handler)
{
diff --git a/src/setting.hpp b/src/setting.hpp
index 997109a..b681e05 100644
--- a/src/setting.hpp
+++ b/src/setting.hpp
@@ -52,8 +52,16 @@ namespace wanda
{
using value_type = std::variant<std::monostate, bool, std::int32_t, std::int64_t, std::uint32_t, std::uint64_t, double, std::string, std::vector<std::string>>;
+ /**
+ * @brief Get the value of the settings entry
+ */
value_type operator*() const;
+ /**
+ * @brief Assign the given @p value to the settings entry
+ *
+ * @returns @p true iff. the value could be successfully assigned
+ */
template<typename Type>
bool operator=(Type value)
{
diff --git a/src/type_wrapper.hpp b/src/type_wrapper.hpp
index f147d67..12684cb 100644
--- a/src/type_wrapper.hpp
+++ b/src/type_wrapper.hpp
@@ -1,7 +1,7 @@
/**
- * @file type_wrapper.hpp
+ * @file type_wrapper.hpp
* @author Felix Morgner (felix.morgner@gmail.com)
- * @since 1.0.0
+ * @since 1.0.0
*/
#ifndef WANDA_TYPE_WRAPPER_HPP
@@ -11,20 +11,35 @@
namespace wanda
{
+ /**
+ * @brief A type to create a distinct type based on an existing type
+ *
+ * @tparam InnerType The type to wrap
+ * @tparam TagType A tag type to identify the distinct type
+ */
template<typename InnerType, typename TagType>
struct type_wrapper
{
+ /**
+ * @brief Construct a new type wrapper object
+ */
explicit type_wrapper(InnerType value)
: m_value{std::move(value)}
{
}
+ /**
+ * @brief Retrieve the wrapped value with its original type
+ */
constexpr explicit operator InnerType const &() const { return get(); }
+ /**
+ * @brief Retrieve the wrapped value with its original type
+ */
constexpr InnerType const & get() const { return m_value; }
private:
- InnerType const m_value;
+ InnerType m_value;
};
} // namespace wanda
diff --git a/src/wallpaper.hpp b/src/wallpaper.hpp
index 988ab78..0cad473 100644
--- a/src/wallpaper.hpp
+++ b/src/wallpaper.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file wallpaper.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_WALLPAPER_HPP
#define WANDA_WALLPAPER_HPP
@@ -9,6 +15,9 @@
namespace wanda
{
+ /**
+ * @brief Set the wallpaper to the file specified by the given path
+ */
void set_wallpaper(std::filesystem::path wallpaper);
} // namespace wanda
diff --git a/src/xdg.hpp b/src/xdg.hpp
index 8010b7b..94dbf9b 100644
--- a/src/xdg.hpp
+++ b/src/xdg.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file xdg.hpp
+ * @author Felix Morgner (felix.morgner@gmail.com)
+ * @since 1.0.0
+ */
+
#ifndef WANDA_XDG_HPP
#define WANDA_XDG_HPP