changeset 252:e0f58cfbd45a

Irccdctl: separate event/messages signals
author David Demelier <markand@malikania.fr>
date Wed, 24 Aug 2016 22:04:11 +0200
parents 7b54db12be51
children 11045c180db9
files lib/irccd/client.cpp lib/irccd/client.hpp lib/irccd/cmd-watch.cpp lib/irccd/irccdctl.cpp lib/irccd/irccdctl.hpp lib/irccd/server.cpp
diffstat 6 files changed, 55 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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 &) {
         }
     }
--- 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<const Info &> onConnect;
 
     /**
+     * onEvent
+     * --------------------------------------------------------------
+     *
+     * An event has been received.
+     */
+    Signal<const nlohmann::json &> onEvent;
+
+    /**
      * onMessage
      * ---------------------------------------------------------------
      *
--- 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())
--- 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<std::string> 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<std::string> 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);
--- 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<std::string, Alias> m_aliases;
 
     // Incoming data.
-    std::vector<nlohmann::json> m_input;
+    std::vector<nlohmann::json> m_events;
+    std::vector<nlohmann::json> 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.
--- 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<unsigned>(server.m_recodelay * 1000)) {
             log::warning() << "server " << server.name() << ": timeout while connecting" << std::endl;
             server.next(std::make_unique<DisconnectedState>());