From d0874c66951f9eb14e9df1011419a277c810527b Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Mon, 9 Mar 2015 18:25:12 +0000
Subject: [PATCH] there's no need to impose unique client names on the server:
 it just complicates everything - so let's remove this limitation

---
 Common/CommandLine.cpp            |  7 ++++
 Common/gmshLocalNetworkClient.cpp | 54 ++++++++++---------------------
 Common/onelab.h                   | 21 ++++++------
 Common/onelabUtils.cpp            | 13 +++++++-
 Fltk/graphicWindow.cpp            |  2 +-
 Fltk/onelab2Group.cpp             |  8 ++---
 Fltk/onelabGroup.cpp              | 14 ++++----
 Fltk/optionWindow.cpp             |  2 +-
 Fltk/solverButton.cpp             |  3 +-
 9 files changed, 61 insertions(+), 63 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 0ad7ecec91..1c74f91f77 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -20,6 +20,11 @@
 #include "CreateFile.h"
 #include "OS.h"
 
+// keep track of -setnumber/-setstring command line option, so we can propagate
+// them to subclients later on
+//std::map<std::string, double> CommandLineNumbers;
+//std::map<std::string, std::string> CommandLineStrings;
+
 #if defined(HAVE_FLTK)
 #include <FL/Fl.H>
 #if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION >= 3)
@@ -534,6 +539,7 @@ void GetOptions(int argc, char *argv[])
         i++;
 	if (i + 1 < argc && argv[i][0] != '-' && argv[i + 1][0] != '-') {
           gmsh_yystringsymbols[argv[i]] = argv[i + 1];
+          //CommandLineStrings[argv[i]] = argv[i + 1];
           i += 2;
 	}
         else
@@ -544,6 +550,7 @@ void GetOptions(int argc, char *argv[])
 	if (i + 1 < argc && argv[i][0] != '-') {
           std::vector<double> val(1, atof(argv[i + 1]));
           gmsh_yysymbols[argv[i]].value = val;
+          //CommandLineNumbers[argv[i]] = atof(argv[i + 1]);
           i += 2;
 	}
         else
diff --git a/Common/gmshLocalNetworkClient.cpp b/Common/gmshLocalNetworkClient.cpp
index 02bdf6e2f7..6e918c4451 100644
--- a/Common/gmshLocalNetworkClient.cpp
+++ b/Common/gmshLocalNetworkClient.cpp
@@ -375,34 +375,21 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
       std::string::size_type first = 0;
       std::string clientName = onelab::parameter::getNextToken(message, first);
       std::string command = onelab::parameter::getNextToken(message, first);
-      if (!onelab::server::instance()->isRegistered(clientName)){
-	gmshLocalNetworkClient* subClient =
-	  new gmshLocalNetworkClient(clientName, command, "", true);
-	onelabGmshServer *server = new onelabGmshServer(subClient);
-	subClient->setPid(0);
-	int sock = server->LaunchClient();
-	if(sock < 0){ // could not establish the connection: aborting
-	  server->Shutdown();
-	  delete server;
-	  Msg::Error("Could not connect client '%s'", subClient->getName().c_str());
-	}
-	else{
-	  Msg::StatusBar(true, "Running '%s'...", subClient->getName().c_str());
-	  subClient->setGmshServer(server);
-	  subClient->setFather(this);
-	  master->addClient(subClient);
-	}
+      gmshLocalNetworkClient* subClient =
+        new gmshLocalNetworkClient(clientName, command, "", true);
+      onelabGmshServer *server = new onelabGmshServer(subClient);
+      subClient->setPid(0);
+      int sock = server->LaunchClient();
+      if(sock < 0){ // could not establish the connection: aborting
+        server->Shutdown();
+        delete server;
+        Msg::Error("Could not connect client '%s'", subClient->getName().c_str());
       }
       else{
-	std::string reply = "";
-	for(onelab::server::citer it = onelab::server::instance()->firstClient();
-	    it != onelab::server::instance()->lastClient(); it++){
-	  reply.append(it->second->getName() + " ");
-	}
-	Msg::Error("Skipping already existing client '%s' - Registered clients: %s",
-                   clientName.c_str(), reply.c_str());
-	getGmshServer()->SendMessage
-	  (GmshSocket::GMSH_STOP, reply.size(), &reply[0]); // reply is dummy
+        Msg::StatusBar(true, "Running '%s'...", subClient->getName().c_str());
+        subClient->setGmshServer(server);
+        subClient->setFather(this);
+        master->addClient(subClient);
       }
     }
     break;
@@ -413,14 +400,9 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
       std::string::size_type first = 0;
       std::string clientName = onelab::parameter::getNextToken(message, first);
       std::string fullName = onelab::parameter::getNextToken(message, first);
-      if (!onelab::server::instance()->isRegistered(clientName)){
-	preProcess(clientName, fullName); // contrib/onelab/OnelabParser.cpp
-	Msg::Info("Preprocess file <%s> done", fullName.c_str());
-	reply = onelab::server::instance()->getChanged(clientName) ? "true" : "false";
-      }
-      else{
-	Msg::Error("Skipping client with already existing name <%s>",clientName.c_str());
-      }
+      preProcess(clientName, fullName); // contrib/onelab/OnelabParser.cpp
+      Msg::Info("Done preprocessing file '%s'", fullName.c_str());
+      reply = onelab::server::instance()->getChanged(clientName) ? "true" : "false";
 #endif
       getGmshServer()->SendMessage
 	(GmshSocket::GMSH_OLPARSE, reply.size(), &reply[0]);
@@ -499,7 +481,6 @@ bool gmshLocalNetworkClient::run()
             delete s;
           }
           toDelete.push_back(c);
-          onelab::server::instance()->unregisterClient(c);
           continue;
         }
       }
@@ -557,7 +538,6 @@ bool gmshLocalNetworkClient::run()
       if(c->getPid() > 0)
         Msg::Error("Subclient %s was not stopped correctly", c->getName().c_str());
       toDelete.push_back(c);
-      onelab::server::instance()->unregisterClient(c);
     }
   }
   for(unsigned int i = 0; i < toDelete.size(); i++){
@@ -784,7 +764,7 @@ void resetDb(bool runGmshClient)
   // released
   for(onelab::server::citer it = onelab::server::instance()->firstClient();
       it != onelab::server::instance()->lastClient(); it++){
-    onelab::client *c = it->second;
+    onelab::client *c = *it;
     std::vector<onelab::number> ps;
     c->get(ps, c->getName() + "/UseCommandLine");
     if(ps.size()) persistentNumbers.push_back(ps[0]);
diff --git a/Common/onelab.h b/Common/onelab.h
index e249b5f3af..8a9dc5cfbe 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -1292,8 +1292,8 @@ namespace onelab{
     static server *_server;
     // the address of the server
     std::string _address;
-    // the connected clients, indexed by name
-    std::map<std::string, client*> _clients;
+    // the connected clients
+    std::set<client*> _clients;
     // the parameter space
     parameterSpace _parameterSpace;
   public:
@@ -1318,17 +1318,22 @@ namespace onelab{
     {
       return _parameterSpace.get(ps, name, client);
     }
-    typedef std::map<std::string, client*>::iterator citer;
+    typedef std::set<client*>::iterator citer;
     citer firstClient(){ return _clients.begin(); }
     citer lastClient(){ return _clients.end(); }
     int getNumClients() { return (int)_clients.size(); };
-    citer findClient(const std::string &name){ return _clients.find(name); }
+    citer findClient(const std::string &name)
+    {
+      for(citer it = _clients.begin(); it != _clients.end(); it++)
+        if((*it)->getName() == name) return it;
+      return _clients.end();
+    }
     void registerClient(client *c)
     {
-      _clients[c->getName()] = c;
+      _clients.insert(c);
       c->setId(_clients.size());
     }
-    void unregisterClient(client *c){ _clients.erase(c->getName()); }
+    void unregisterClient(client *c){ _clients.erase(c); }
     void setChanged(bool changed, const std::string &client="")
     {
       _parameterSpace.setChanged(changed, client);
@@ -1337,10 +1342,6 @@ namespace onelab{
     {
       return _parameterSpace.getChanged(client);
     }
-    bool isRegistered(const std::string &client)
-    {
-      return _clients.count(client);
-    }
     unsigned int getNumParameters(){ return _parameterSpace.getNumParameters(); }
     std::vector<std::string> toChar(const std::string &client="")
     {
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index 8ec8b9a0a2..7aaa43574a 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -124,6 +124,17 @@ namespace onelabUtils {
         args.push_back(" " + checkCommand) ;
       else if(action == "compute")
         args.push_back(" " + computeCommand);
+      // FIXME: this would be the place to propagate the the client any
+      // -setnumber/-setstring command line options given to gmsh. Is this a
+      // good idea?
+      std::vector<std::string> gmshOptions = onelab::parameter::split
+        (Msg::GetCommandLineArgs(), ' ');
+      for(unsigned int i = 0; i < gmshOptions.size(); i++){
+        if(gmshOptions[i] == "-setnumber" && i < gmshOptions.size() - 2){
+          printf("hello!! %s %s %s\n", gmshOptions[i].c_str(), gmshOptions[i+1].c_str(),
+                 gmshOptions[i + 2].c_str());
+        }
+      }
     }
     return args;
   }
@@ -457,7 +468,7 @@ namespace onelabUtils {
     onelab::server::citer it = onelab::server::instance()->findClient("Gmsh");
     if(it == onelab::server::instance()->lastClient()) return redraw;
 
-    onelab::client *c = it->second;
+    onelab::client *c = *it;
     std::string mshFileName = onelabUtils::getMshFileName(c);
 
     Msg::SetGmshOnelabAction(action);
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index d683260269..4bfb2fffd1 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -190,7 +190,7 @@ static void file_remote_cb(Fl_Widget *w, void *data)
     c->setSocketSwitch("-socket");
   }
   else
-    c = (onelab::localNetworkClient*)it->second;
+    c = (onelab::localNetworkClient*)(*it);
   GmshServer *server = c->getGmshServer();
 
   std::string str((const char*)data);
diff --git a/Fltk/onelab2Group.cpp b/Fltk/onelab2Group.cpp
index d61bf2b5af..6a30dfe139 100644
--- a/Fltk/onelab2Group.cpp
+++ b/Fltk/onelab2Group.cpp
@@ -417,7 +417,7 @@ void onelabGroup::rebuildSolverList()
     if(i < names.size()){
       onelab::server::citer it = onelab::server::instance()->findClient(names[i]);
       if(it != onelab::server::instance()->lastClient())
-        it->second->setIndex(i);
+        (*it)->setIndex(i);
       opt_solver_name(i, GMSH_SET, names[i]);
       opt_solver_executable(i, GMSH_SET, exes[i]);
       opt_solver_remote_login(i, GMSH_SET, hosts[i]);
@@ -439,7 +439,7 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab
   //onelab::server::citer it = onelab::server::instance()->findClient(name);
   //if(it != onelab::server::instance()->lastClient()){
   //  if(needToChooseExe(executable))
-  //    onelab_choose_executable_cb(0, (void *)it->second);
+  //    onelab_choose_executable_cb(0, (void *)(*it));
   //  return; // solver already exists
   //}
 
@@ -447,8 +447,8 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab
   //std::vector<onelab::client*> networkClients;
   //for(onelab::server::citer it = onelab::server::instance()->firstClient();
   //    it != onelab::server::instance()->lastClient(); it++)
-  //  if(it->second->isNetworkClient())
-  //    networkClients.push_back(it->second);
+  //  if((*it)->isNetworkClient())
+  //    networkClients.push_back(*it);
   //for(unsigned int i = 0; i < networkClients.size(); i++){
   //  delete networkClients[i];
   //}
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 75d391c12f..02561263f2 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -66,7 +66,7 @@ void onelab_cb(Fl_Widget *w, void *data)
     FlGui::instance()->onelab->setButtonMode("", "kill");
     for(onelab::server::citer it = onelab::server::instance()->firstClient();
         it != onelab::server::instance()->lastClient(); it++){
-      onelab::string o(it->second->getName() + "/Action", "stop");
+      onelab::string o((*it)->getName() + "/Action", "stop");
       o.setVisible(false);
       o.setNeverChanged(true);
       onelab::server::instance()->set(o);
@@ -78,7 +78,7 @@ void onelab_cb(Fl_Widget *w, void *data)
     FlGui::instance()->onelab->stop(true);
     for(onelab::server::citer it = onelab::server::instance()->firstClient();
         it != onelab::server::instance()->lastClient(); it++)
-      it->second->kill();
+      (*it)->kill();
     return;
   }
 
@@ -163,7 +163,7 @@ void onelab_cb(Fl_Widget *w, void *data)
     // iterate over all other clients (there should normally only be one)
     for(onelab::server::citer it = onelab::server::instance()->firstClient();
 	it != onelab::server::instance()->lastClient(); it++){
-      onelab::client *c = it->second;
+      onelab::client *c = *it;
       if(c->getName() == "Gmsh" || // local Gmsh client
 	 c->getName() == "Listen" || // unknown client connecting through "-listen"
 	 c->getName() == "GmshRemote" || // distant post-processing Gmsh client
@@ -1262,7 +1262,7 @@ void onelabGroup::rebuildSolverList()
     if(i < names.size()){
       onelab::server::citer it = onelab::server::instance()->findClient(names[i]);
       if(it != onelab::server::instance()->lastClient())
-        it->second->setIndex(i);
+        (*it)->setIndex(i);
       opt_solver_name(i, GMSH_SET, names[i]);
       opt_solver_executable(i, GMSH_SET, exes[i]);
       opt_solver_remote_login(i, GMSH_SET, hosts[i]);
@@ -1297,7 +1297,7 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab
   onelab::server::citer it = onelab::server::instance()->findClient(name);
   if(it != onelab::server::instance()->lastClient()){
     if(needToChooseExe(executable))
-      onelab_choose_executable_cb(0, (void *)it->second);
+      onelab_choose_executable_cb(0, (void *)(*it));
     return; // solver already exists
   }
 
@@ -1305,8 +1305,8 @@ void onelabGroup::addSolver(const std::string &name, const std::string &executab
   std::vector<onelab::client*> networkClients;
   for(onelab::server::citer it = onelab::server::instance()->firstClient();
       it != onelab::server::instance()->lastClient(); it++)
-    if(it->second->isNetworkClient())
-      networkClients.push_back(it->second);
+    if((*it)->isNetworkClient())
+      networkClients.push_back(*it);
   for(unsigned int i = 0; i < networkClients.size(); i++){
     delete networkClients[i];
   }
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index b4d3024fdf..83f5bc192d 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -579,7 +579,7 @@ static void solver_options_ok_cb(Fl_Widget *w, void *data)
       c->run();
     }
     else
-      it->second->run();
+      (*it)->run();
   }
 #endif
 
diff --git a/Fltk/solverButton.cpp b/Fltk/solverButton.cpp
index a73e950877..46756cbcbf 100644
--- a/Fltk/solverButton.cpp
+++ b/Fltk/solverButton.cpp
@@ -25,8 +25,7 @@ static void solver_remove_cb(Fl_Widget *w, void *data)
 
   onelab::server::citer it = onelab::server::instance()->findClient(name);
   if(it != onelab::server::instance()->lastClient()){
-    onelab::client *c = it->second;
-    delete c;
+    delete *it;
   }
   FlGui::instance()->onelab->rebuildSolverList();
 }
-- 
GitLab