# HG changeset patch # User David Demelier # Date 1472069051 -7200 # Node ID e0f58cfbd45ac986a7291042422e2c4c08f345ce # Parent 7b54db12be5113740b4a485a5461bdb506d37626 Irccdctl: separate event/messages signals diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/client.cpp --- a/lib/irccd/client.cpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/client.cpp Wed Aug 24 22:04:11 2016 +0200 @@ -64,7 +64,7 @@ class Client::ReadyState : public Client::State { private: - void parse(Client &cnx, const std::string &message) + void parse(Client &client, const std::string &message) { try { auto json = nlohmann::json::parse(message); @@ -72,7 +72,10 @@ if (!json.is_object()) return; - cnx.onMessage(json); + if (json.count("event") > 0) + client.onEvent(json); + else + client.onMessage(json); } catch (const std::exception &) { } } diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/client.hpp --- a/lib/irccd/client.hpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/client.hpp Wed Aug 24 22:04:11 2016 +0200 @@ -97,6 +97,14 @@ Signal onConnect; /** + * onEvent + * -------------------------------------------------------------- + * + * An event has been received. + */ + Signal onEvent; + + /** * onMessage * --------------------------------------------------------------- * diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/cmd-watch.cpp --- a/lib/irccd/cmd-watch.cpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/cmd-watch.cpp Wed Aug 24 22:04:11 2016 +0200 @@ -217,7 +217,7 @@ while (ctl.client().isConnected()) { try { - auto object = ctl.next(); + auto object = ctl.waitEvent(); auto event = object.find("event"); if (event == object.end() || !event->is_string()) diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/irccdctl.cpp --- a/lib/irccd/irccdctl.cpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/irccdctl.cpp Wed Aug 24 22:04:11 2016 +0200 @@ -380,23 +380,23 @@ return result; } -nlohmann::json Irccdctl::next(const std::string id) +nlohmann::json Irccdctl::waitMessage(const std::string id) { ElapsedTimer timer; - while (m_input.empty() && m_connection->isConnected() && timer.elapsed() < m_timeout) + while (m_messages.empty() && m_connection->isConnected() && timer.elapsed() < m_timeout) m_connection->poll(); - if (m_input.empty()) + if (m_messages.empty()) return nlohmann::json(); nlohmann::json value; if (id == "") { - value = m_input[0]; - m_input.erase(m_input.begin()); + value = m_messages[0]; + m_messages.erase(m_messages.begin()); } else { - auto it = std::find_if(m_input.begin(), m_input.end(), [&] (const auto &v) { + auto it = std::find_if(m_messages.begin(), m_messages.end(), [&] (const auto &v) { auto rt = v.find("response"); if (v.count("error") > 0 || (rt != v.end() && rt->is_string() && *rt == id)) @@ -406,9 +406,9 @@ }); // Remove the previous messages. - if (it != m_input.end()) { + if (it != m_messages.end()) { value = *it; - m_input.erase(m_input.begin(), it); + m_messages.erase(m_messages.begin(), it); } } @@ -420,6 +420,22 @@ return value; } +nlohmann::json Irccdctl::waitEvent() +{ + ElapsedTimer timer; + + while (m_events.empty() && m_connection->isConnected() && timer.elapsed() < m_timeout) + m_connection->poll(); + + if (m_events.empty()) + return nullptr; + + auto first = m_events.front(); + m_events.erase(m_events.begin()); + + return first; +} + void Irccdctl::exec(const Command &cmd, std::vector args) { // 1. Build options from command line arguments. @@ -466,7 +482,7 @@ m_connection->request(request); // 6. Parse the result. - cmd.result(*this, next(cmd.name())); + cmd.result(*this, waitMessage(cmd.name())); } void Irccdctl::exec(const Alias &alias, std::vector argsCopy) @@ -585,8 +601,11 @@ << info.minor << "." << info.patch << std::endl; }); + m_connection->onEvent.connect([this] (auto msg) { + m_events.push_back(std::move(msg)); + }); m_connection->onMessage.connect([this] (auto msg) { - m_input.push_back(std::move(msg)); + m_messages.push_back(std::move(msg)); }); m_connection->connect(m_address); diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/irccdctl.hpp --- a/lib/irccd/irccdctl.hpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/irccdctl.hpp Wed Aug 24 22:04:11 2016 +0200 @@ -63,7 +63,8 @@ std::map m_aliases; // Incoming data. - std::vector m_input; + std::vector m_events; + std::vector m_messages; void usage() const; void help() const; @@ -114,7 +115,7 @@ } /** - * Get the next response with the given id. + * Get the next message response with the given id. * * If the response id is not provided, get the next incoming message. * @@ -125,7 +126,14 @@ * \return the next message * \warning this may skip previous events */ - IRCCD_EXPORT nlohmann::json next(const std::string id = ""); + IRCCD_EXPORT nlohmann::json waitMessage(const std::string id = ""); + + /** + * Get the next pending even within the internal timeout. + * + * \return the next event or empty if not available + */ + IRCCD_EXPORT nlohmann::json waitEvent(); /** * Execute the given command and wait for its result. diff -r 7b54db12be51 -r e0f58cfbd45a lib/irccd/server.cpp --- a/lib/irccd/server.cpp Tue Aug 23 23:02:06 2016 +0200 +++ b/lib/irccd/server.cpp Wed Aug 24 22:04:11 2016 +0200 @@ -838,7 +838,7 @@ * * Otherwise, the libircclient event_connect will change the state. */ - if (m_state == Disconnected) { + if (m_state == Connecting) { if (m_timer.elapsed() > static_cast(server.m_recodelay * 1000)) { log::warning() << "server " << server.name() << ": timeout while connecting" << std::endl; server.next(std::make_unique());