fix: Use module name in action string
Action strings now have the form '#MODULE#ACTION' For example to trigger the action 'toggle' in the 'module/date' module one would now use '%{A1:#date#toggle:}' With this action strings can now be uniquely assigned to one module. Fixes #1172
This commit is contained in:
parent
22d0f0a38c
commit
a287fb5e8c
@ -117,9 +117,12 @@ class controller
|
||||
modulemap_t m_blocks;
|
||||
|
||||
/**
|
||||
* \brief Module input handlers
|
||||
* \brief Input handlers modules
|
||||
*
|
||||
* Maps the name of the input handler (module name) to the corresponding input
|
||||
* handler
|
||||
*/
|
||||
vector<modules::input_handler*> m_inputhandlers;
|
||||
std::map<string, shared_ptr<modules::input_handler>> m_inputhandlers;
|
||||
|
||||
/**
|
||||
* \brief Maximum number of subsequent events to swallow
|
||||
|
@ -101,6 +101,10 @@ namespace modules {
|
||||
public:
|
||||
virtual ~module_interface() {}
|
||||
|
||||
/**
|
||||
* Module name w/o 'module/' prefix
|
||||
*/
|
||||
virtual string name_raw() const = 0;
|
||||
virtual string name() const = 0;
|
||||
virtual bool running() const = 0;
|
||||
|
||||
@ -119,6 +123,7 @@ namespace modules {
|
||||
module(const bar_settings bar, string name);
|
||||
~module() noexcept;
|
||||
|
||||
string name_raw() const;
|
||||
string name() const;
|
||||
bool running() const;
|
||||
void stop();
|
||||
@ -148,6 +153,7 @@ namespace modules {
|
||||
std::condition_variable m_sleephandler;
|
||||
|
||||
string m_name;
|
||||
string m_name_raw;
|
||||
unique_ptr<builder> m_builder;
|
||||
unique_ptr<module_formatter> m_formatter;
|
||||
vector<thread> m_threads;
|
||||
|
@ -17,6 +17,7 @@ namespace modules {
|
||||
, m_log(logger::make())
|
||||
, m_conf(config::make())
|
||||
, m_name("module/" + name)
|
||||
, m_name_raw(name)
|
||||
, m_builder(make_unique<builder>(bar))
|
||||
, m_formatter(make_unique<module_formatter>(m_conf, m_name))
|
||||
, m_handle_events(m_conf.get(m_name, "handle-events", true)) {}
|
||||
@ -40,6 +41,11 @@ namespace modules {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
string module<Impl>::name_raw() const {
|
||||
return m_name_raw;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
bool module<Impl>::running() const {
|
||||
return static_cast<bool>(m_enabled);
|
||||
|
@ -8,6 +8,11 @@ namespace modules {
|
||||
class input_handler {
|
||||
public:
|
||||
virtual ~input_handler() {}
|
||||
/**
|
||||
* Handle command
|
||||
*
|
||||
* \returns true if the command is supported and false otherwise
|
||||
*/
|
||||
virtual bool input(string&& cmd) = 0;
|
||||
};
|
||||
}
|
||||
|
@ -143,11 +143,12 @@ bool controller::run(bool writeback, string snapshot_dst) {
|
||||
|
||||
size_t started_modules{0};
|
||||
for (const auto& module : m_modules) {
|
||||
auto inp_handler = dynamic_cast<input_handler*>(&*module);
|
||||
auto inp_handler = std::dynamic_pointer_cast<input_handler>(module);
|
||||
auto evt_handler = dynamic_cast<event_handler_interface*>(&*module);
|
||||
|
||||
if (inp_handler != nullptr) {
|
||||
m_inputhandlers.emplace_back(inp_handler);
|
||||
if (inp_handler) {
|
||||
m_log.trace("Registering module %s as input handler", module->name_raw());
|
||||
m_inputhandlers.emplace(module->name_raw(), inp_handler);
|
||||
}
|
||||
|
||||
if (evt_handler != nullptr) {
|
||||
@ -390,18 +391,49 @@ void controller::process_eventqueue() {
|
||||
* Process stored input data
|
||||
*/
|
||||
void controller::process_inputdata() {
|
||||
if (!m_inputdata.empty()) {
|
||||
string cmd = m_inputdata;
|
||||
m_inputdata.clear();
|
||||
|
||||
for (auto&& handler : m_inputhandlers) {
|
||||
if (handler->input(string{cmd})) {
|
||||
if (m_inputdata.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const string cmd = m_inputdata;
|
||||
m_inputdata.clear();
|
||||
|
||||
/*
|
||||
* Module inputs have the following form (w/o the quotes): "#NAME#INPUT"
|
||||
* where 'NAME' is the name of the module (for which '#' is a forbidden
|
||||
* character) and 'INPUT' is the input that is sent to the module
|
||||
*/
|
||||
if (cmd.front() == '#') {
|
||||
// Find the second delimiter '#'
|
||||
auto end_pos = cmd.find('#', 1);
|
||||
|
||||
if (end_pos == string::npos) {
|
||||
m_log.err("Invalid action string (input: %s)", cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
auto handler_name = cmd.substr(1, end_pos - 1);
|
||||
auto action = cmd.substr(end_pos + 1);
|
||||
|
||||
m_log.info("Forwarding data to input handler (name: %s, action: %s) ", handler_name, action);
|
||||
|
||||
auto handler = m_inputhandlers.find(handler_name);
|
||||
|
||||
if (handler == m_inputhandlers.end()) {
|
||||
m_log.err("The input handler with name '%s' doesn't exist (input: %s)", handler_name, cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!handler->second->input(string{action})) {
|
||||
m_log.warn("The '%s' module does not support the '%s' action.", handler_name, action);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
m_log.info("Uncaught input event, forwarding to shell... (input: %s)", cmd);
|
||||
// Run input as command if it's not an input for a module
|
||||
m_log.info("Forwarding command to shell... (input: %s)", cmd);
|
||||
|
||||
if (m_command) {
|
||||
m_log.warn("Terminating previous shell command");
|
||||
@ -417,7 +449,6 @@ void controller::process_inputdata() {
|
||||
m_log.err("controller: Error while forwarding input to shell -> %s", err.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process eventqueue update event
|
||||
|
Loading…
Reference in New Issue
Block a user