2016-10-29 00:48:51 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <moodycamel/blockingconcurrentqueue.h>
|
2016-12-14 21:30:41 -05:00
|
|
|
|
2016-11-20 17:04:31 -05:00
|
|
|
#include <chrono>
|
2016-12-09 03:02:47 -05:00
|
|
|
#include <condition_variable>
|
|
|
|
#include <mutex>
|
|
|
|
#include <thread>
|
2016-10-29 00:48:51 -04:00
|
|
|
|
|
|
|
#include "common.hpp"
|
2016-12-05 14:41:00 -05:00
|
|
|
#include "events/signal_emitter.hpp"
|
|
|
|
#include "events/signal_fwd.hpp"
|
|
|
|
#include "events/signal_receiver.hpp"
|
2016-12-09 03:02:47 -05:00
|
|
|
#include "utils/concurrency.hpp"
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-09 03:02:47 -05:00
|
|
|
// fwd
|
|
|
|
namespace modules {
|
|
|
|
struct module_interface;
|
|
|
|
}
|
|
|
|
enum class alignment : uint8_t;
|
|
|
|
class config;
|
|
|
|
class logger;
|
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
using namespace signals::eventloop;
|
|
|
|
|
2016-10-29 00:48:51 -04:00
|
|
|
using module_t = unique_ptr<modules::module_interface>;
|
2016-12-09 03:02:47 -05:00
|
|
|
using modulemap_t = std::map<alignment, vector<module_t>>;
|
|
|
|
|
2016-12-13 23:42:46 -05:00
|
|
|
namespace chrono = std::chrono;
|
2016-12-09 03:02:47 -05:00
|
|
|
using namespace std::chrono_literals;
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit, process_input, process_check,
|
|
|
|
enqueue_event, enqueue_quit, enqueue_update, enqueue_input, enqueue_check> {
|
2016-10-29 00:48:51 -04:00
|
|
|
public:
|
2016-12-05 14:41:00 -05:00
|
|
|
enum class event_type : uint8_t {
|
|
|
|
NONE = 0,
|
|
|
|
UPDATE,
|
|
|
|
CHECK,
|
|
|
|
INPUT,
|
|
|
|
QUIT,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct event {
|
|
|
|
uint8_t type{static_cast<uint8_t>(event_type::NONE)};
|
|
|
|
bool flag{false};
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename EventType>
|
|
|
|
using queue_t = moodycamel::BlockingConcurrentQueue<EventType>;
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
public:
|
2016-12-09 03:40:46 -05:00
|
|
|
using make_type = unique_ptr<eventloop>;
|
|
|
|
static make_type make();
|
2016-12-09 03:02:47 -05:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
explicit eventloop(signal_emitter& emitter, const logger& logger, const config& config);
|
2016-12-01 02:41:49 -05:00
|
|
|
~eventloop();
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-11-25 15:20:50 -05:00
|
|
|
void start();
|
2016-11-02 15:22:45 -04:00
|
|
|
void stop();
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
bool enqueue(event&& evt);
|
2016-12-14 21:30:41 -05:00
|
|
|
bool enqueue(string&& input_data);
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-11-02 15:22:45 -04:00
|
|
|
void add_module(const alignment pos, module_t&& module);
|
2016-11-25 15:20:50 -05:00
|
|
|
const modulemap_t& modules() const;
|
|
|
|
size_t module_count() const;
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-09 03:02:47 -05:00
|
|
|
static event make_quit_evt(bool reload = false);
|
|
|
|
static event make_update_evt(bool force = false);
|
|
|
|
static event make_input_evt();
|
|
|
|
static event make_check_evt();
|
2016-12-03 16:54:58 -05:00
|
|
|
|
2016-10-29 00:48:51 -04:00
|
|
|
protected:
|
2016-11-25 15:20:50 -05:00
|
|
|
void dispatch_modules();
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-13 23:42:46 -05:00
|
|
|
void handle_inputdata();
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
bool on(const process_input& evt);
|
|
|
|
bool on(const process_check& evt);
|
|
|
|
bool on(const process_quit& evt);
|
|
|
|
|
|
|
|
bool on(const enqueue_event& evt);
|
|
|
|
bool on(const enqueue_quit& evt);
|
|
|
|
bool on(const enqueue_update& evt);
|
|
|
|
bool on(const enqueue_input& evt);
|
|
|
|
bool on(const enqueue_check& evt);
|
2016-10-29 00:48:51 -04:00
|
|
|
|
|
|
|
private:
|
2016-12-05 14:41:00 -05:00
|
|
|
signal_emitter& m_sig;
|
2016-10-29 00:48:51 -04:00
|
|
|
const logger& m_log;
|
2016-11-25 15:20:50 -05:00
|
|
|
const config& m_conf;
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-11-25 15:20:50 -05:00
|
|
|
/**
|
|
|
|
* @brief Event queue
|
|
|
|
*/
|
2016-12-05 14:41:00 -05:00
|
|
|
queue_t<event> m_queue;
|
|
|
|
|
2016-11-25 15:20:50 -05:00
|
|
|
/**
|
|
|
|
* @brief Loaded modules
|
|
|
|
*/
|
2016-10-29 00:48:51 -04:00
|
|
|
modulemap_t m_modules;
|
2016-11-25 15:20:50 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flag to indicate current run state
|
|
|
|
*/
|
2016-12-15 03:29:14 -05:00
|
|
|
stateflag m_running{};
|
2016-10-29 00:48:51 -04:00
|
|
|
|
2016-11-25 15:20:50 -05:00
|
|
|
/**
|
|
|
|
* @brief Time to wait for subsequent events
|
|
|
|
*/
|
2016-12-13 23:42:46 -05:00
|
|
|
chrono::milliseconds m_swallow_update{10ms};
|
2016-11-25 15:20:50 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Maximum amount of subsequent events to swallow within timeframe
|
|
|
|
*/
|
2016-12-13 23:42:46 -05:00
|
|
|
size_t m_swallow_limit{5U};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Time to throttle input events
|
|
|
|
*/
|
2016-12-14 01:46:37 -05:00
|
|
|
chrono::milliseconds m_swallow_input{30ms};
|
2016-12-13 23:42:46 -05:00
|
|
|
|
|
|
|
/**
|
2016-12-14 13:04:33 -05:00
|
|
|
* @brief Time of last handled input event
|
2016-12-13 23:42:46 -05:00
|
|
|
*/
|
2016-12-14 13:04:33 -05:00
|
|
|
chrono::time_point<chrono::system_clock, chrono::milliseconds> m_lastinput;
|
2016-12-13 23:42:46 -05:00
|
|
|
|
|
|
|
/**
|
2016-12-14 13:04:33 -05:00
|
|
|
* @brief Mutex used to guard input data
|
2016-12-13 23:42:46 -05:00
|
|
|
*/
|
2016-12-15 03:29:14 -05:00
|
|
|
std::mutex m_inputlock{};
|
2016-12-13 23:42:46 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Input data
|
|
|
|
*/
|
|
|
|
string m_inputdata;
|
2016-10-29 00:48:51 -04:00
|
|
|
};
|
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS_END
|