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;
|
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
|
* \brief Maximum number of subsequent events to swallow
|
||||||
|
@ -101,6 +101,10 @@ namespace modules {
|
|||||||
public:
|
public:
|
||||||
virtual ~module_interface() {}
|
virtual ~module_interface() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module name w/o 'module/' prefix
|
||||||
|
*/
|
||||||
|
virtual string name_raw() const = 0;
|
||||||
virtual string name() const = 0;
|
virtual string name() const = 0;
|
||||||
virtual bool running() const = 0;
|
virtual bool running() const = 0;
|
||||||
|
|
||||||
@ -119,6 +123,7 @@ namespace modules {
|
|||||||
module(const bar_settings bar, string name);
|
module(const bar_settings bar, string name);
|
||||||
~module() noexcept;
|
~module() noexcept;
|
||||||
|
|
||||||
|
string name_raw() const;
|
||||||
string name() const;
|
string name() const;
|
||||||
bool running() const;
|
bool running() const;
|
||||||
void stop();
|
void stop();
|
||||||
@ -148,6 +153,7 @@ namespace modules {
|
|||||||
std::condition_variable m_sleephandler;
|
std::condition_variable m_sleephandler;
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
string m_name_raw;
|
||||||
unique_ptr<builder> m_builder;
|
unique_ptr<builder> m_builder;
|
||||||
unique_ptr<module_formatter> m_formatter;
|
unique_ptr<module_formatter> m_formatter;
|
||||||
vector<thread> m_threads;
|
vector<thread> m_threads;
|
||||||
|
@ -17,6 +17,7 @@ namespace modules {
|
|||||||
, m_log(logger::make())
|
, m_log(logger::make())
|
||||||
, m_conf(config::make())
|
, m_conf(config::make())
|
||||||
, m_name("module/" + name)
|
, m_name("module/" + name)
|
||||||
|
, m_name_raw(name)
|
||||||
, m_builder(make_unique<builder>(bar))
|
, m_builder(make_unique<builder>(bar))
|
||||||
, m_formatter(make_unique<module_formatter>(m_conf, m_name))
|
, m_formatter(make_unique<module_formatter>(m_conf, m_name))
|
||||||
, m_handle_events(m_conf.get(m_name, "handle-events", true)) {}
|
, m_handle_events(m_conf.get(m_name, "handle-events", true)) {}
|
||||||
@ -40,6 +41,11 @@ namespace modules {
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Impl>
|
||||||
|
string module<Impl>::name_raw() const {
|
||||||
|
return m_name_raw;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Impl>
|
template <typename Impl>
|
||||||
bool module<Impl>::running() const {
|
bool module<Impl>::running() const {
|
||||||
return static_cast<bool>(m_enabled);
|
return static_cast<bool>(m_enabled);
|
||||||
|
@ -8,6 +8,11 @@ namespace modules {
|
|||||||
class input_handler {
|
class input_handler {
|
||||||
public:
|
public:
|
||||||
virtual ~input_handler() {}
|
virtual ~input_handler() {}
|
||||||
|
/**
|
||||||
|
* Handle command
|
||||||
|
*
|
||||||
|
* \returns true if the command is supported and false otherwise
|
||||||
|
*/
|
||||||
virtual bool input(string&& cmd) = 0;
|
virtual bool input(string&& cmd) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -143,11 +143,12 @@ bool controller::run(bool writeback, string snapshot_dst) {
|
|||||||
|
|
||||||
size_t started_modules{0};
|
size_t started_modules{0};
|
||||||
for (const auto& module : m_modules) {
|
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);
|
auto evt_handler = dynamic_cast<event_handler_interface*>(&*module);
|
||||||
|
|
||||||
if (inp_handler != nullptr) {
|
if (inp_handler) {
|
||||||
m_inputhandlers.emplace_back(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) {
|
if (evt_handler != nullptr) {
|
||||||
@ -390,32 +391,62 @@ void controller::process_eventqueue() {
|
|||||||
* Process stored input data
|
* Process stored input data
|
||||||
*/
|
*/
|
||||||
void controller::process_inputdata() {
|
void controller::process_inputdata() {
|
||||||
if (!m_inputdata.empty()) {
|
if (m_inputdata.empty()) {
|
||||||
string cmd = m_inputdata;
|
return;
|
||||||
m_inputdata.clear();
|
}
|
||||||
|
|
||||||
for (auto&& handler : m_inputhandlers) {
|
const string cmd = m_inputdata;
|
||||||
if (handler->input(string{cmd})) {
|
m_inputdata.clear();
|
||||||
return;
|
|
||||||
}
|
/*
|
||||||
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
auto handler_name = cmd.substr(1, end_pos - 1);
|
||||||
m_log.info("Uncaught input event, forwarding to shell... (input: %s)", cmd);
|
auto action = cmd.substr(end_pos + 1);
|
||||||
|
|
||||||
if (m_command) {
|
m_log.info("Forwarding data to input handler (name: %s, action: %s) ", handler_name, action);
|
||||||
m_log.warn("Terminating previous shell command");
|
|
||||||
m_command->terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.info("Executing shell command: %s", cmd);
|
auto handler = m_inputhandlers.find(handler_name);
|
||||||
m_command = command_util::make_command<output_policy::IGNORED>(move(cmd));
|
|
||||||
m_command->exec();
|
if (handler == m_inputhandlers.end()) {
|
||||||
m_command.reset();
|
m_log.err("The input handler with name '%s' doesn't exist (input: %s)", handler_name, cmd);
|
||||||
process_update(true);
|
return;
|
||||||
} catch (const application_error& err) {
|
|
||||||
m_log.err("controller: Error while forwarding input to shell -> %s", err.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!handler->second->input(string{action})) {
|
||||||
|
m_log.warn("The '%s' module does not support the '%s' action.", handler_name, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 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");
|
||||||
|
m_command->terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.info("Executing shell command: %s", cmd);
|
||||||
|
m_command = command_util::make_command<output_policy::IGNORED>(move(cmd));
|
||||||
|
m_command->exec();
|
||||||
|
m_command.reset();
|
||||||
|
process_update(true);
|
||||||
|
} catch (const application_error& err) {
|
||||||
|
m_log.err("controller: Error while forwarding input to shell -> %s", err.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user