#pragma once #include #include #include "common.hpp" POLYBAR_NS /** * Runs any libuv function with an integer error code return value and throws an * exception on error. */ #define UV(fun, ...) \ int res = fun(__VA_ARGS__); \ if (res < 0) { \ throw std::runtime_error("libuv error for '" #fun "': "s + uv_strerror(res)); \ } template struct cb_helper { std::function func; static void callback(H* context, Args... args) { const auto unpackedThis = static_cast(context->data); return unpackedThis->func(std::forward(args)...); } }; struct SignalHandle { SignalHandle(uv_loop_t* loop, std::function fun) { handle = std::make_unique(); UV(uv_signal_init, loop, handle.get()); cb = cb_helper{fun}; handle->data = &cb; }; std::unique_ptr handle; cb_helper cb; }; class eventloop { public: eventloop(); ~eventloop(); void run(); void stop(); /** * TODO make protected */ uv_loop_t* get() const { return m_loop.get(); } void signal_handler(int signum, std::function fun) { auto handle = std::make_unique(get(), fun); UV(uv_signal_start, handle->handle.get(), &handle->cb.callback, signum); m_sig_handles.push_back(std::move(handle)); } protected: template static void generic_cb(H* handle, Args&&... args) { (static_cast(handle->data).*F)(std::forward(args)...); } private: std::unique_ptr m_loop{nullptr}; vector> m_sig_handles; }; POLYBAR_NS_END