diff --git a/Common/onelab.h b/Common/onelab.h index 2fe895a2cb0485cd69de041cbb8bca3cccdfd4d1..dc56f025cc9750e18f1fd2722e0411b97598c354 100644 --- a/Common/onelab.h +++ b/Common/onelab.h @@ -40,18 +40,19 @@ namespace onelab{ private: // the name of the parameter, including its '/'-separated path in // the parameter hierarchy. Parameters or subpaths can start with - // numbers to force their relative ordering (such numbers could be - // automatically hidden in a GUI). + // numbers to force their relative ordering (such numbers are + // automatically hidden in the interface). std::string _name; - // help strings (the short help can serve as a better way to - // display the parameter in a GUI). Should allow richer encoding - // (UTF? HTML?) + // help strings (the short serves as a better way to display the + // parameter in the interface). Should allow richer encoding (UTF? + // HTML?) std::string _shortHelp, _help; // clients (computing steps) that use this parameter std::set<std::string> _clients; - // flag to check if the parameter has been changed since the last run + // flag to check if the parameter has been changed since the last + // run() bool _changed; - // should the parameter be visible in the interface + // should the parameter be visible in the interface? bool _visible; protected: // optional additional attributes @@ -90,7 +91,7 @@ namespace onelab{ const std::string &getHelp() const { return _help; } bool getChanged() const { return _changed; } bool getVisible() const { return _visible; } - std::string getAttribute (const std::string &key) const + std::string getAttribute(const std::string &key) const { std::map<std::string, std::string>::const_iterator it = _attributes.find(key); if(it != _attributes.end()) return it->second; @@ -103,7 +104,7 @@ namespace onelab{ const std::set<std::string> &getClients() const { return _clients; } static char charSep() { return '|' /* '\0' */; } static double maxNumber() { return 1e200; } - std::string sanitize (const std::string &in) const + std::string sanitize(const std::string &in) const { std::string out(in); for(unsigned int i = 0; i < in.size(); i++) @@ -113,7 +114,8 @@ namespace onelab{ virtual std::string toChar() const { std::ostringstream sstream; - sstream << getType() << charSep() << sanitize(getName()) << charSep() + sstream << getType() << charSep() + << sanitize(getName()) << charSep() << sanitize(getShortHelp()) << charSep() << sanitize(getHelp()) << charSep() << (getVisible() ? 1 : 0) << charSep() @@ -121,9 +123,32 @@ namespace onelab{ for(std::map<std::string, std::string>::const_iterator it = _attributes.begin(); it != _attributes.end(); it++) sstream << it->first << charSep() << it->second << charSep(); + sstream << getClients().size() << charSep(); + for(std::set<std::string>::const_iterator it = getClients().begin(); + it != getClients().end(); it++) + sstream << *it << charSep(); return sstream.str(); } - virtual void fromChar(const std::string &msg){} + virtual std::string::size_type fromChar(const std::string &msg) + { + std::string::size_type pos = 0; + if(getNextToken(msg, pos) != getType()) return 0; + setName(getNextToken(msg, pos)); + setShortHelp(getNextToken(msg, pos)); + setHelp(getNextToken(msg, pos)); + setVisible(atoi(getNextToken(msg, pos).c_str())); + int numAttributes = atoi(getNextToken(msg, pos).c_str()); + for(int i = 0; i < numAttributes; i++){ + std::string key(getNextToken(msg, pos)); + setAttribute(key, getNextToken(msg, pos)); + } + int numClients = atoi(getNextToken(msg, pos).c_str()); + for(int i = 0; i < numClients; i++){ + std::string client(getNextToken(msg, pos)); + addClient(client); + } + return pos; + } static std::string getNextToken(const std::string &msg, std::string::size_type &first) { @@ -176,7 +201,10 @@ namespace onelab{ const std::vector<double> &getChoices() const { return _choices; } void update(const number &p) { - addClients(p.getClients()); + addClients(p.getClients()); // complete the list + setShortHelp(p.getShortHelp()); + setHelp(p.getHelp()); + setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); setChanged(true); @@ -185,9 +213,6 @@ namespace onelab{ setMax(p.getMax()); setStep(p.getStep()); setChoices(p.getChoices()); - setShortHelp(p.getShortHelp()); - setHelp(p.getHelp()); - setAttributes(p.getAttributes()); } std::string toChar() const { @@ -197,25 +222,12 @@ namespace onelab{ << _choices.size() << charSep(); for(unsigned int i = 0; i < _choices.size(); i++) sstream << _choices[i] << charSep(); - sstream << getClients().size() << charSep(); - for(std::set<std::string>::const_iterator it = getClients().begin(); - it != getClients().end(); it++) - sstream << *it << charSep(); return sstream.str(); } - void fromChar(const std::string &msg) + std::string::size_type fromChar(const std::string &msg) { - std::string::size_type pos = 0; - if(getNextToken(msg, pos) != getType()) return; - setName(getNextToken(msg, pos)); - setShortHelp(getNextToken(msg, pos)); - setHelp(getNextToken(msg, pos)); - setVisible(atoi(getNextToken(msg, pos).c_str())); - int numAttributes = atoi(getNextToken(msg, pos).c_str()); - for(int i = 0; i < numAttributes; i++){ - std::string key(getNextToken(msg, pos)); - setAttribute(key, getNextToken(msg, pos)); - } + std::string::size_type pos = parameter::fromChar(msg); + if(!pos) return 0; setValue(atof(getNextToken(msg, pos).c_str())); setMin(atof(getNextToken(msg, pos).c_str())); setMax(atof(getNextToken(msg, pos).c_str())); @@ -223,13 +235,14 @@ namespace onelab{ _choices.resize(atoi(getNextToken(msg, pos).c_str())); for(unsigned int i = 0; i < _choices.size(); i++) _choices[i] = atof(getNextToken(msg, pos).c_str()); + return pos; } }; // The string class. A string has a mutable "kind": we do not derive // specialized classes, because the kind should be changeable at - // runtime (e.g. from client-dependent mathematical expression to to - // table of values). Possible kinds: generic, filename, hostname, + // runtime (e.g. from a client-dependent mathematical expression to + // a table of values). Possible kinds: generic, filename, hostname, // client-dependent mathematical expression, comma-separated list of // values, matlab matrix, onelab mathematical expression (through // mathex?), ... @@ -251,6 +264,9 @@ namespace onelab{ void update(const string &p) { addClients(p.getClients()); + setShortHelp(p.getShortHelp()); + setHelp(p.getHelp()); + setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); setChanged(true); @@ -260,9 +276,6 @@ namespace onelab{ setChanged(true); } setChoices(p.getChoices()); - setShortHelp(p.getShortHelp()); - setHelp(p.getHelp()); - setAttributes(p.getAttributes()); } std::string toChar() const { @@ -272,30 +285,18 @@ namespace onelab{ << _choices.size() << charSep(); for(unsigned int i = 0; i < _choices.size(); i++) sstream << sanitize(_choices[i]) << charSep(); - sstream << getClients().size() << charSep(); - for(std::set<std::string>::const_iterator it = getClients().begin(); - it != getClients().end(); it++) - sstream << *it << charSep(); return sstream.str(); } - void fromChar(const std::string &msg) + std::string::size_type fromChar(const std::string &msg) { - std::string::size_type pos = 0; - if(getNextToken(msg, pos) != getType()) return; - setName(getNextToken(msg, pos)); - setShortHelp(getNextToken(msg, pos)); - setHelp(getNextToken(msg, pos)); - setVisible(atoi(getNextToken(msg, pos).c_str())); - int numAttributes = atoi(getNextToken(msg, pos).c_str()); - for(int i = 0; i < numAttributes; i++){ - std::string key(getNextToken(msg, pos)); - setAttribute(key, getNextToken(msg, pos)); - } + std::string::size_type pos = parameter::fromChar(msg); + if(!pos) return 0; setValue(getNextToken(msg, pos)); setKind(getNextToken(msg, pos)); _choices.resize(atoi(getNextToken(msg, pos).c_str())); for(unsigned int i = 0; i < _choices.size(); i++) _choices[i] = getNextToken(msg, pos); + return pos; } }; @@ -316,6 +317,9 @@ namespace onelab{ void update(const region &p) { addClients(p.getClients()); + setShortHelp(p.getShortHelp()); + setHelp(p.getHelp()); + setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); setChanged(true); @@ -328,10 +332,6 @@ namespace onelab{ << _choices.size() << charSep(); for(unsigned int i = 0; i < _choices.size(); i++) sstream << _choices[i] << charSep(); - sstream << getClients().size() << charSep(); - for(std::set<std::string>::const_iterator it = getClients().begin(); - it != getClients().end(); it++) - sstream << *it << charSep(); return sstream.str(); } }; @@ -376,6 +376,9 @@ namespace onelab{ void update(const function &p) { addClients(p.getClients()); + setShortHelp(p.getShortHelp()); + setHelp(p.getHelp()); + setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); setChanged(true); @@ -386,17 +389,13 @@ namespace onelab{ std::ostringstream sstream; sstream << parameter::toChar() << sanitize(_value) << charSep() << _pieceWiseValues.size() << charSep(); - for(std::map<std::string, std::string>::const_iterator it = - _pieceWiseValues.begin(); it != _pieceWiseValues.end(); it++) - sstream << sanitize(it->first) << charSep() - << sanitize(it->second) << charSep(); + for(std::map<std::string, std::string>::const_iterator it = + _pieceWiseValues.begin(); it != _pieceWiseValues.end(); it++) + sstream << sanitize(it->first) << charSep() + << sanitize(it->second) << charSep(); sstream << _choices.size() << charSep(); for(unsigned int i = 0; i < _choices.size(); i++) sstream << sanitize(_choices[i]) << charSep(); - sstream << getClients().size() << charSep(); - for(std::set<std::string>::const_iterator it = getClients().begin(); - it != getClients().end(); it++) - sstream << *it << charSep(); return sstream.str(); } }; @@ -525,7 +524,8 @@ namespace onelab{ }; // The onelab client: a class that communicates with the onelab - // server. Each client should be derived from this one. + // server. Each client should be derived from this one. A client can + // be understood as "one simulation step in a complex computation". class client{ protected: // the name of the client