diff --git a/utils/solvers/c++/GmshSocket.h b/utils/solvers/c++/GmshSocket.h index 8afb52ed8047e9be897a429a7511e9b84eaab3cf..db40391fa393454256a31e52de67eb365bfe5987 100644 --- a/utils/solvers/c++/GmshSocket.h +++ b/utils/solvers/c++/GmshSocket.h @@ -28,6 +28,8 @@ #ifndef _GMSH_SOCKET_H_ #define _GMSH_SOCKET_H_ +//#include "GmshConfig.h" + #include <string> #include <stdio.h> #include <stdlib.h> @@ -84,6 +86,8 @@ class GmshSocket{ GMSH_PARAMETER_UPDATE = 32, GMSH_OPEN_PROJECT = 33, GMSH_CLIENT_CHANGED = 34, + GMSH_PARAMETER_WITHOUT_CHOICES = 35, + GMSH_PARAMETER_QUERY_WITHOUT_CHOICES = 36, GMSH_OPTION_1 = 100, GMSH_OPTION_2 = 101, GMSH_OPTION_3 = 102, @@ -94,6 +98,8 @@ class GmshSocket{ int _sock; // the socket name std::string _sockname; + // statistics + unsigned long int _sent, _received; // send some data over the socket int _SendData(const void *buffer, int bytes) { @@ -106,6 +112,7 @@ class GmshSocket{ sofar += len; remaining -= len; } while(remaining > 0); + _sent += bytes; return bytes; } // receive some data over the socket @@ -121,6 +128,7 @@ class GmshSocket{ sofar += len; remaining -= len; } while(remaining > 0); + _received += bytes; return bytes; } // utility function to swap bytes in an array @@ -145,7 +153,7 @@ class GmshSocket{ #endif } public: - GmshSocket() : _sock(0) + GmshSocket() : _sock(0), _sent(0), _received(0) { #if defined(WIN32) && !defined(__CYGWIN__) WSADATA wsaData; @@ -246,6 +254,8 @@ class GmshSocket{ shutdown(s, SHUT_RDWR); #endif } + unsigned long int SentBytes(){ return _sent; } + unsigned long int ReceivedBytes(){ return _received; } }; class GmshClient : public GmshSocket { diff --git a/utils/solvers/c++/onelab.h b/utils/solvers/c++/onelab.h index f71601773699991585f1c2a681464c085989fa43..338ec47606225a4522908d05c128c47978250140 100644 --- a/utils/solvers/c++/onelab.h +++ b/utils/solvers/c++/onelab.h @@ -137,7 +137,13 @@ namespace onelab{ } std::string getShortName() const { - if(_label.size()) return _label; + std::string units = getAttribute("Units"); + if(_label.size()){ + if(units.empty()) + return _label; + else + return _label + " [" + units + "]"; + } std::string s = _name; // remove path std::string::size_type last = _name.find_last_of('/'); @@ -154,7 +160,10 @@ namespace onelab{ // start' while(s.size() && s[0] >= '0' && s[0] <= '9') s = s.substr(1); - return s; + if(units.empty()) + return s; + else + return s + " [" + units + "]"; } int getChanged(const std::string &client="") const { @@ -189,7 +198,7 @@ namespace onelab{ const std::map<std::string, int> &getClients() const { return _clients; } static char charSep() { return '\0'; } static double maxNumber() { return 1e200; } - static std::string version() { return "1.2"; } + static std::string version() { return "1.3"; } static int defaultChangedValue() { return 31; } static std::string getNextToken(const std::string &msg, std::string::size_type &first, @@ -353,8 +362,7 @@ namespace onelab{ }; // The number class. Numbers are stored internally as double precision real - // numbers. All more complicated types (complex numbers, vectors, expressions, - // functions, etc.) are supposed to be exchanged as strings. + // numbers. class number : public parameter{ private: std::vector<double> _values, _choices; @@ -382,6 +390,7 @@ namespace onelab{ void setChoiceLabels(const std::vector<std::string> &labels) { if(labels.size() != _choices.size()) return; + if(_valueLabels.size()) _valueLabels.clear(); for(unsigned int i = 0; i < _choices.size(); i++) _valueLabels[_choices[i]] = labels[i]; } @@ -720,14 +729,24 @@ namespace onelab{ if(!done) done = _clear(name, client, _strings); } } - bool set(const number &p, - const std::string &client=""){ return _set(p, client, _numbers); } - bool set(const string &p, - const std::string &client=""){ return _set(p, client, _strings); } + bool set(const number &p, const std::string &client="") + { + return _set(p, client, _numbers); + } + bool set(const string &p, const std::string &client="") + { + return _set(p, client, _strings); + } bool get(std::vector<number> &ps, const std::string &name="", - const std::string &client=""){ return _get(ps, name, client, _numbers); } - bool get(std::vector<onelab::string> &ps, const std::string &name="", - const std::string &client=""){ return _get(ps, name, client, _strings); } + const std::string &client="") + { + return _get(ps, name, client, _numbers); + } + bool get(std::vector<string> &ps, const std::string &name="", + const std::string &client="") + { + return _get(ps, name, client, _strings); + } void getPtr(number **ptr, const std::string name, const std::string client="") { *ptr = _getPtr(name, client, _numbers); @@ -812,10 +831,10 @@ namespace onelab{ onelab::parameter::getInfoFromChar(msg[i], version, type, name); if(onelab::parameter::version() != version) return false; if(type == "number"){ - onelab::number p; p.fromChar(msg[i]); set(p, client); + number p; p.fromChar(msg[i]); set(p, client); } else if(type == "string"){ - onelab::string p; p.fromChar(msg[i]); set(p, client); + string p; p.fromChar(msg[i]); set(p, client); } else return false; @@ -881,7 +900,11 @@ namespace onelab{ virtual bool set(const number &p) = 0; virtual bool set(const string &p) = 0; virtual bool get(std::vector<number> &ps, const std::string &name="") = 0; - virtual bool get(std::vector<onelab::string> &ps, const std::string &name="") = 0; + virtual bool get(std::vector<string> &ps, const std::string &name="") = 0; + virtual bool setAndAppendChoices(const number &p) = 0; + virtual bool setAndAppendChoices(const string &p) = 0; + virtual bool getWithoutChoices(std::vector<number> &ps, const std::string &name="") = 0; + virtual bool getWithoutChoices(std::vector<string> &ps, const std::string &name="") = 0; std::vector<std::string> toChar() { std::vector<std::string> out; @@ -898,10 +921,10 @@ namespace onelab{ onelab::parameter::getInfoFromChar(msg[i], version, type, name); if(onelab::parameter::version() != version) return false; if(type == "number"){ - onelab::number p; p.fromChar(msg[i]); set(p); + number p; p.fromChar(msg[i]); set(p); } else if(type == "string"){ - onelab::string p; p.fromChar(msg[i]); set(p); + string p; p.fromChar(msg[i]); set(p); } else return false; @@ -919,6 +942,7 @@ namespace onelab{ return false; } }; + // The onelab server: a singleton that stores the parameter space and // interacts with onelab clients. class server{ @@ -1038,8 +1062,46 @@ namespace onelab{ virtual bool set(const string &p){ return _set(p); } virtual bool get(std::vector<number> &ps, const std::string &name=""){ return _get(ps, name); } - virtual bool get(std::vector<onelab::string> &ps, + virtual bool get(std::vector<string> &ps, const std::string &name=""){ return _get(ps, name); } + virtual bool setAndAppendChoices(const number &p) + { + std::vector<number> ps; + _get(ps, _name); + std::vector<double> choices; + if(ps.size()) choices = ps[0].getChoices(); + choices.insert(choices.end(), p.getChoices().begin(), p.getChoices().end()); + number p2(p); + p2.setChoices(choices); + return _set(p2); + } + virtual bool setAndAppendChoices(const string &p) + { + std::vector<string> ps; + _get(ps, _name); + std::vector<std::string> choices; + if(ps.size()) choices = ps[0].getChoices(); + choices.insert(choices.end(), p.getChoices().begin(), p.getChoices().end()); + string p2(p); + p2.setChoices(choices); + return _set(p2); + } + virtual bool getWithoutChoices(std::vector<number> &ps, + const std::string &name="") + { + bool ret = _get(ps, name); + for(unsigned int i = 0; i < ps.size(); i++) + ps[i].setChoices(std::vector<double>()); + return ret; + } + virtual bool getWithoutChoices(std::vector<string> &ps, + const std::string &name="") + { + bool ret = _get(ps, name); + for(unsigned int i = 0; i < ps.size(); i++) + ps[i].setChoices(std::vector<std::string>()); + return ret; + } }; // The local part of a network client. @@ -1096,21 +1158,26 @@ namespace onelab{ GmshClient *_gmshClient; // number of subclients int _numSubClients; - template <class T> bool _set(const T &p) + template <class T> bool _set(const T &p, bool withChoices=true) { if(!_gmshClient) return false; std::string msg = p.toChar(); - _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER, msg.size(), &msg[0]); + _gmshClient->SendMessage(withChoices ? GmshSocket::GMSH_PARAMETER : + GmshSocket::GMSH_PARAMETER_WITHOUT_CHOICES, + msg.size(), &msg[0]); return true; } - template <class T> bool _get(std::vector<T> &ps, const std::string &name="") + template <class T> bool _get(std::vector<T> &ps, const std::string &name="", + bool withChoices=true) { ps.clear(); if(!_gmshClient) return false; T p(name); std::string msg = p.toChar(); - if (name.size()) - _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]); + if(name.size()) + _gmshClient->SendMessage(withChoices ? GmshSocket::GMSH_PARAMETER_QUERY : + GmshSocket::GMSH_PARAMETER_QUERY_WITHOUT_CHOICES, + msg.size(), &msg[0]); else // get all parameters _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY_ALL, msg.size(), &msg[0]); @@ -1228,10 +1295,24 @@ namespace onelab{ } virtual bool set(const number &p){ return _set(p); } virtual bool set(const string &p){ return _set(p); } - virtual bool get(std::vector<number> &ps, - const std::string &name=""){ return _get(ps, name); } - virtual bool get(std::vector<onelab::string> &ps, - const std::string &name=""){ return _get(ps, name); } + virtual bool get(std::vector<number> &ps, const std::string &name="") + { + return _get(ps, name); + } + virtual bool get(std::vector<string> &ps, const std::string &name="") + { + return _get(ps, name); + } + virtual bool setAndAppendChoices(const number &p){ return _set(p, false); } + virtual bool setAndAppendChoices(const string &p){ return _set(p, false); } + virtual bool getWithoutChoices(std::vector<number> &ps, const std::string &name="") + { + return _get(ps, name, false); + } + virtual bool getWithoutChoices(std::vector<string> &ps, const std::string &name="") + { + return _get(ps, name, false); + } void sendInfo(const std::string &msg) { if(_gmshClient) _gmshClient->Info(msg.c_str()); @@ -1263,7 +1344,10 @@ namespace onelab{ void runNonBlockingSubClient(const std::string &name, const std::string &command) { if(!_gmshClient){ - system(command.c_str()); + int res = system(command.c_str()); + if(res){ + // report error + } return; } std::string msg = name + parameter::charSep() + command;