From e22d30e25a264c309bd819edde3eacb1184da800 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@qt.io>
Date: Fri, 9 Sep 2016 10:01:45 +0200
Subject: server-mode: Allow for sending signals

Enable the server to send signals.
---
 Help/manual/cmake-server.7.rst |  8 ++++++++
 Source/cmServer.cxx            | 13 +++++++++++++
 Source/cmServer.h              |  1 +
 Source/cmServerDictionary.h    |  2 ++
 Source/cmServerProtocol.cxx    |  7 +++++++
 Source/cmServerProtocol.h      |  2 ++
 6 files changed, 33 insertions(+)

diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst
index 00ffcd1..61d6896 100644
--- a/Help/manual/cmake-server.7.rst
+++ b/Help/manual/cmake-server.7.rst
@@ -186,6 +186,14 @@ Example::
   ]== CMake Server ==]
 
 
+Type "signal"
+^^^^^^^^^^^^^
+
+The server can send signals when it detects changes in the system state. Signals
+are of type "signal", have an empty "cookie" and "inReplyTo" field and always
+have a "name" set to show which signal was sent.
+
+
 Specific Message Types
 ----------------------
 
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index f7e5e3b..d5dac4e 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -343,6 +343,19 @@ void cmServer::WriteParseError(const std::string& message) const
   this->WriteJsonObject(obj, nullptr);
 }
 
+void cmServer::WriteSignal(const std::string& name,
+                           const Json::Value& data) const
+{
+  assert(data.isObject());
+  Json::Value obj = data;
+  obj[kTYPE_KEY] = kSIGNAL_TYPE;
+  obj[kREPLY_TO_KEY] = "";
+  obj[kCOOKIE_KEY] = "";
+  obj[kNAME_KEY] = name;
+
+  WriteJsonObject(obj, nullptr);
+}
+
 void cmServer::WriteResponse(const cmServerResponse& response,
                              const DebugInfo* debug) const
 {
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 433b2ac..849e5c5 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -63,6 +63,7 @@ private:
   void WriteResponse(const cmServerResponse& response,
                      const DebugInfo* debug) const;
   void WriteParseError(const std::string& message) const;
+  void WriteSignal(const std::string& name, const Json::Value& obj) const;
 
   void WriteJsonObject(Json::Value const& jsonValue,
                        const DebugInfo* debug) const;
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
index 379c94d..156ade2 100644
--- a/Source/cmServerDictionary.h
+++ b/Source/cmServerDictionary.h
@@ -21,6 +21,7 @@ static const std::string kHANDSHAKE_TYPE = "handshake";
 static const std::string kMESSAGE_TYPE = "message";
 static const std::string kPROGRESS_TYPE = "progress";
 static const std::string kREPLY_TYPE = "reply";
+static const std::string kSIGNAL_TYPE = "signal";
 
 static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
 static const std::string kCOOKIE_KEY = "cookie";
@@ -31,6 +32,7 @@ static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
 static const std::string kMAJOR_KEY = "major";
 static const std::string kMESSAGE_KEY = "message";
 static const std::string kMINOR_KEY = "minor";
+static const std::string kNAME_KEY = "name";
 static const std::string kPROGRESS_CURRENT_KEY = "progressCurrent";
 static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum";
 static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 16a6374..e42b18a 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -122,6 +122,13 @@ bool cmServerProtocol::Activate(cmServer* server,
   return result;
 }
 
+void cmServerProtocol::SendSignal(const std::string& name,
+                                  const Json::Value& data) const
+{
+  if (this->m_Server)
+    this->m_Server->WriteSignal(name, data);
+}
+
 cmake* cmServerProtocol::CMakeInstance() const
 {
   return this->m_CMakeInstance.get();
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 92c8162..0383dfe 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -90,6 +90,8 @@ public:
   bool Activate(cmServer* server, const cmServerRequest& request,
                 std::string* errorMessage);
 
+  void SendSignal(const std::string& name, const Json::Value& data) const;
+
 protected:
   cmake* CMakeInstance() const;
   // Implement protocol specific activation tasks here. Called from Activate().
-- 
cgit v0.12