From 02f441ffb1aae06851108984fa4ff351e8a2b93f Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Wed, 29 May 2019 15:03:37 +0200
Subject: [PATCH] geom viewer: use REveGeomRequest class for request/reply
 transport

Instead specialized parsing of different request arguments
pack them together in one class.
Should be possible to extend in the future
---
 graf3d/eve7/inc/LinkDef.h                    |  1 +
 graf3d/eve7/inc/ROOT/REveGeomData.hxx        | 11 ++++-
 graf3d/eve7/src/REveGeomViewer.cxx           | 39 +++++++----------
 ui5/eve7/controller/GeomViewer.controller.js | 46 ++++++++++++++------
 4 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/graf3d/eve7/inc/LinkDef.h b/graf3d/eve7/inc/LinkDef.h
index 9e24434262b..13a67bb6ff2 100644
--- a/graf3d/eve7/inc/LinkDef.h
+++ b/graf3d/eve7/inc/LinkDef.h
@@ -220,6 +220,7 @@
 #pragma link C++ class ROOT::Experimental::REveShapeRenderInfo+;
 #pragma link C++ class ROOT::Experimental::REveGeomDescription+;
 #pragma link C++ class ROOT::Experimental::REveGeomDrawing+;
+#pragma link C++ class ROOT::Experimental::REveGeomRequest+;
 
 // Tables
 #pragma link C++ class ROOT::Experimental::REveTableViewInfo;
diff --git a/graf3d/eve7/inc/ROOT/REveGeomData.hxx b/graf3d/eve7/inc/ROOT/REveGeomData.hxx
index 51dff8f8f84..108a8c87f1b 100644
--- a/graf3d/eve7/inc/ROOT/REveGeomData.hxx
+++ b/graf3d/eve7/inc/ROOT/REveGeomData.hxx
@@ -115,12 +115,21 @@ public:
    std::vector<REveGeomVisible> visibles;   ///< all visibles items with
    std::string drawopt;                     ///< draw options for TGeoPainter
    int binlen{0};                           ///< extra binary data for that drawing
+};
+
 
-   REveGeomDrawing() = default;
+/** Request object send from client for different operations */
+class REveGeomRequest {
+public:
+   std::string oper;  ///< operation like HIGHL or HOVER
+   std::string path;  ///< path parameter, used with HOVER
+   std::vector<int> stack; ///< stack parameter, used with HIGHL
 };
 
+
 using REveGeomScanFunc_t = std::function<bool(REveGeomNode &, std::vector<int> &, bool)>;
 
+
 class REveGeomDescription {
 
    friend class RGeomBrowserIter;
diff --git a/graf3d/eve7/src/REveGeomViewer.cxx b/graf3d/eve7/src/REveGeomViewer.cxx
index 35afe8c164f..000929f3e2d 100644
--- a/graf3d/eve7/src/REveGeomViewer.cxx
+++ b/graf3d/eve7/src/REveGeomViewer.cxx
@@ -21,6 +21,8 @@
 #include "TBufferJSON.h"
 #include "TGeoManager.h"
 
+using namespace std::string_literals;
+
 //////////////////////////////////////////////////////////////////////////////////////////////
 /// constructor
 
@@ -196,33 +198,24 @@ void ROOT::Experimental::REveGeomViewer::WebWindowCallback(unsigned connid, cons
       if (binary.size() > 0)
          fWebWindow->SendBinary(connid, &binary[0], binary.size());
 
-   } else if (arg.compare(0, 6, "HOVER:") == 0) {
+   } else if (arg.compare(0, 6, "GVREQ:") == 0) {
 
-      std::string msg = arg.substr(6), json;
+      auto req = TBufferJSON::FromJSON<REveGeomRequest>(arg.substr(6));
 
-      if (msg.compare("OFF") != 0) {
-         auto stack = fDesc.MakeStackByPath(msg);
-         if (stack.size() > 0)
-            json = TBufferJSON::ToJSON(&stack, fDesc.GetJsonComp());
+      if (req && (req->oper == "HOVER")) {
+         if (req->path != "OFF")
+            req->stack = fDesc.MakeStackByPath(req->path);
+         req->path.clear();
+      } else if (req && (req->oper == "HIGHL")) {
+         if (req->stack.size() > 0)
+            req->path = fDesc.MakePathByStack(req->stack);
+         req->stack.clear();
+      } else {
+         req.reset(nullptr);
       }
 
-      if (json.empty()) json = "OFF";
-      json = std::string("HOVER:") + json;
-      fWebWindow->Send(connid, json);
-
-   } else if (arg.compare(0, 6, "HIGHL:") == 0) {
-
-      std::string msg = arg.substr(6), json;
-
-      if (msg.compare("OFF") != 0) {
-         auto stack = GetStackFromJson(msg);
-
-         json = fDesc.MakePathByStack(stack);
-      }
-
-      if (json.empty()) json = "OFF";
-      json = std::string("HIGHL:") + json;
-      fWebWindow->Send(connid, json);
+      if (req)
+         fWebWindow->Send(connid, "GVRPL:"s + TBufferJSON::ToJSON(req.get(), TBufferJSON::kSkipTypeInfo + TBufferJSON::kNoSpaces).Data());
 
    } else if ((arg.compare(0, 7, "SETVI0:") == 0) || (arg.compare(0, 7, "SETVI1:") == 0)) {
       // change visibility for specified nodeid
diff --git a/ui5/eve7/controller/GeomViewer.controller.js b/ui5/eve7/controller/GeomViewer.controller.js
index 4cbffbebd54..d3a845f9158 100644
--- a/ui5/eve7/controller/GeomViewer.controller.js
+++ b/ui5/eve7/controller/GeomViewer.controller.js
@@ -194,6 +194,31 @@ sap.ui.define(['sap/ui/core/Component',
          }
       },
 
+      /** @brief Send REveGeomRequest data to geometry viewer */
+      sendViewerRequest: function(_oper, args) {
+         var req = { oper: _oper, path: "", stack: [] };
+         JSROOT.extend(req, args);
+         this.websocket.Send("GVREQ:" + JSON.stringify(req));
+      },
+
+      /** Process reply on REveGeomRequest */
+      processViewerReply: function(repl) {
+         if (!repl || (typeof repl != "object") || !repl.oper)
+            return false;
+
+         if (repl.oper == "HOVER") {
+
+            this._hover_stack = repl.stack || null;
+            if (this.geo_painter)
+               this.geo_painter.HighlightMesh(null, 0x00ff00, null, undefined, this._hover_stack, true);
+
+         } else if (repl.oper == "HIGHL") {
+
+            this.highlighRowWithPath(repl.path);
+
+         }
+      },
+
       /** @brief function called then mouse-hover event over the row is invoked
        * @desc Used to highlight correspondent volume on geometry drawing */
       onRowHover: function(row, is_enter) {
@@ -206,7 +231,7 @@ sap.ui.define(['sap/ui/core/Component',
             // avoid multiple time submitting same request
             if (this._last_hover_req === req) return;
             this._last_hover_req = req;
-            return this.websocket.Send("HOVER:" + req);
+            return this.sendViewerRequest("HOVER", { path: req });
          }
 
          if (this.geo_painter && this.geo_clones) {
@@ -260,11 +285,11 @@ sap.ui.define(['sap/ui/core/Component',
       /** Callback from geo painter when mesh object is highlighted. Use for update of TreeTable */
       HighlightMesh: function(active_mesh, color, geo_object, geo_index, geo_stack) {
          if (!this.standalone) {
-            var req = geo_stack ? JSON.stringify(geo_stack) : "OFF";
+            var req = geo_stack ? geo_stack : [];
             // avoid multiple time submitting same request
-            if (this._last_highlight_req === req) return;
+            if (JSROOT.GEO.IsSameStack(this._last_highlight_req, req)) return;
             this._last_highlight_req = req;
-            return this.websocket.Send("HIGHL:" + req);
+            return this.sendViewerRequest("HIGHL", { stack: req });
          }
 
          var hpath = "---";
@@ -282,7 +307,7 @@ sap.ui.define(['sap/ui/core/Component',
 
          for (var i=0;i<rows.length;++i) {
             rows[i].$().css("background-color", "");
-            if (path !== "OFF") {
+            if (path && (path !== "OFF")) {
                var ctxt = rows[i].getBindingContext(),
                    prop = ctxt ? ctxt.getProperty(ctxt.getPath()) : null,
                    cmp = 0;
@@ -474,7 +499,7 @@ sap.ui.define(['sap/ui/core/Component',
          var mhdr = msg.substr(0,6);
          msg = msg.substr(6);
 
-         // console.log(mhdr, msg.length, msg.substr(0,70), "...");
+         console.log(mhdr, msg.length, msg.substr(0,70), "...");
 
          switch (mhdr) {
          case "DESCR:":  // browser hierarchy
@@ -503,13 +528,8 @@ sap.ui.define(['sap/ui/core/Component',
          case "APPND:":
             this.checkDrawMsg("append", JSROOT.parse(msg));
             break;
-         case "HOVER:":
-            this._hover_stack = (msg == "OFF") ? null : JSON.parse(msg);
-            if (this.geo_painter)
-               this.geo_painter.HighlightMesh(null, 0x00ff00, null, undefined, this._hover_stack, true);
-            break;
-         case "HIGHL:":
-            this.highlighRowWithPath(msg);
+         case "GVRPL:":
+            this.processViewerReply(JSROOT.parse(msg));
             break;
          default:
             console.error('Non recognized msg ' + mhdr + ' len=' + msg.length);
-- 
GitLab