diff --git a/Fltk/onelab2Group.cpp b/Fltk/onelab2Group.cpp index 15182af70e7581b4889e235c73d4eeb1675e4a64..7aac6aed7d01dac93d892fb2c01e19b5c1bc4aa9 100644 --- a/Fltk/onelab2Group.cpp +++ b/Fltk/onelab2Group.cpp @@ -70,8 +70,12 @@ void connect_cb(Fl_Widget *w, void *arg) if(!obj->useServer()) return; obj->clearTree(); GmshNetworkClient *cli = OnelabDatabase::instance()->useAsNetworkClient(obj->getServerIP(), obj->getServerPort()); - cli->setCallback(obj); - w->label("Disconnect"); + if(cli) { + cli->setCallback(obj); + w->label("Disconnect"); + } + else + fl_alert("Unable to connect to server"); } else { obj->clearTree(); @@ -99,39 +103,17 @@ void onelab_cb(Fl_Widget *w, void *data) return; } - if(action == "stop"){ - // TODO - return; - } - - if(action == "kill"){ - // TODO - return; - } - if(FlGui::instance()->onelab->isBusy()){ Msg::Info("I'm busy! Ask me that later..."); return; } Msg::Info("Try to %s", action.c_str()); - if(action == "reset"){ - //TODO resetDb(true); - action = "check"; - } - Msg::ResetErrorCounter(); //TODO FlGui::instance()->onelab->setButtonMode("", "stop"); - if(action == "compute") initializeLoops(); - - do{ - //OnelabDatabase::instance()->run("Gmsh", action); - OnelabDatabase::instance()->run(action); - } while(action == "compute" - //&& !FlGui::instance()->onelab->stop() - && incrementLoops()); + OnelabDatabase::instance()->run(action); } @@ -142,10 +124,12 @@ void solver_cb(Fl_Widget *w, void *data) int num = (intptr_t)data; if(num >= 0){ std::string name = opt_solver_name(num, GMSH_GET, ""); + if(name.empty()) return;// TODO std::string exe = opt_solver_executable(num, GMSH_GET, ""); std::string host = opt_solver_remote_login(num, GMSH_GET, ""); OnelabDatabase::instance()->run("initialize", name); } + if(FlGui::instance()->onelab->isBusy()) FlGui::instance()->onelab->show(); else{ @@ -164,6 +148,16 @@ void solver_cb(Fl_Widget *w, void *data) } void solver_batch_cb(Fl_Widget *w, void *data) { + int num = (intptr_t)data; + if(num >= 0) { + std::string name = opt_solver_name(num, GMSH_GET, ""); + std::string exe = opt_solver_executable(num, GMSH_GET, ""); + if(exe.empty()){ + Msg::Error("Solver executable name not provided"); + return; + } + } + Msg::Warning("solver_batch_cb TODO"); // TODO } diff --git a/contrib/onelab2/GmshLocalClient.cpp b/contrib/onelab2/GmshLocalClient.cpp index 011cab5304765a4456720eec888d960eff7423e9..5cdbcd359060527eae6115ef03354c3f88d8d7c1 100644 --- a/contrib/onelab2/GmshLocalClient.cpp +++ b/contrib/onelab2/GmshLocalClient.cpp @@ -3,6 +3,8 @@ #ifdef HAVE_FLTK #include "GmshMessage.h" #include "onelab2Group.h" +#include "OpenFile.h" +#include "Context.h" void GmshLocalClient::setCallback(onelabGroup *cb) {_cb_obj = cb;} void GmshLocalClient::onNewParameter(onelab::parameter *p) @@ -49,6 +51,13 @@ void GmshLocalClient::onMessage(const std::string & name, const std::string &mes Fl::unlock(); Fl::awake((void *)NULL); } +void GmshLocalClient::mergeFile(const std::string &filename) +{ + Fl::lock(); + MergePostProcessingFile(filename, CTX::instance()->solver.autoShowViews, CTX::instance()->solver.autoShowLastStep, true); + Fl::unlock(); + Fl::awake((void *)NULL); +} #endif void GmshLocalClient::run(std::string action) { diff --git a/contrib/onelab2/GmshLocalClient.h b/contrib/onelab2/GmshLocalClient.h index 8b7e9714e2f7443527a7d1d37aba5e5ce1a9a599..03d16291f8eaedbfbde8061c1e7dc1471a0bd66d 100644 --- a/contrib/onelab2/GmshLocalClient.h +++ b/contrib/onelab2/GmshLocalClient.h @@ -25,6 +25,7 @@ public: void onUpdateParameter(onelab::parameter *p); void onRemoveParameter(onelab::parameter *p); void onMessage(const std::string &name, const std::string &message, int level); + void mergeFile(const std::string &filename); #else GmshLocalClient(std::string name, onelab::parameterSpace *parameterSpace) : OnelabLocalClient(name, parameterSpace){} diff --git a/contrib/onelab2/NetworkUtils.cpp b/contrib/onelab2/NetworkUtils.cpp index 0aec45a55fe57270190d311d790264919442ebdf..12bfa2497bed629e2194202b9fbf508f9a58ef31 100644 --- a/contrib/onelab2/NetworkUtils.cpp +++ b/contrib/onelab2/NetworkUtils.cpp @@ -89,7 +89,7 @@ int ip4_socket_send(Socket fd, UInt8 *src, int length) ssize_t sent = send(fd, src, length, 0); // TODO handle error (length != sent) for ??? and (sent < 0) for local error - std::cout << "ip: send " << sent << "/" << length << "bytes" << std::endl; + //std::cout << "ip: send " << sent << "/" << length << "bytes" << std::endl; return (int)sent; } int ip4_socket_send(Socket fd, UInt8 *src, int length, IPv4 dst) @@ -105,7 +105,7 @@ int ip4_socket_send(Socket fd, UInt8 *src, int length, IPv4 dst) ssize_t sent = sendto(fd, src, length, 0, (struct sockaddr *)&to, tol); // TODO handle error (length != sent) for ??? and (sent < 0) for local error - std::cout << "ip: send " << sent << "/" << length << "bytes to " << ip4_inet_ntop(dst.address)<< ':' << dst.port << std::endl; + //std::cout << "ip: send " << sent << "/" << length << "bytes to " << ip4_inet_ntop(dst.address)<< ':' << dst.port << std::endl; return (int)sent; } @@ -114,7 +114,7 @@ int ip4_socket_recv(Socket fd, UInt8 *dst, int maxlength) ssize_t recved = recv(fd, dst, maxlength, 0); // TODO handle error if(recvlength < 0) - std::cout << "ip: recv " << recved << "bytes" << std::endl; + //std::cout << "ip: recv " << recved << "bytes" << std::endl; return recved; } int ip4_socket_recv(Socket fd, UInt8 *dst, int maxlength, IPv4 &src) @@ -128,7 +128,7 @@ int ip4_socket_recv(Socket fd, UInt8 *dst, int maxlength, IPv4 &src) src.address = ntoh32(from.sin_addr.s_addr); // TODO handle error if(recvlength < 0) - std::cout << "ip: recv " << recvlength << "bytes from " << ip4_inet_ntop(src.address)<< ':' << src.port << std::endl; + //std::cout << "ip: recv " << recvlength << "bytes from " << ip4_inet_ntop(src.address)<< ':' << src.port << std::endl; return recvlength; } diff --git a/contrib/onelab2/OnelabAttributes.cpp b/contrib/onelab2/OnelabAttributes.cpp index c6d67b5cf5b769b0636ed55168ff19f075314ea1..f89c9897d61d0c530f4162a12cc66834549159be 100644 --- a/contrib/onelab2/OnelabAttributes.cpp +++ b/contrib/onelab2/OnelabAttributes.cpp @@ -141,6 +141,38 @@ void OnelabAttrFileQuery::showAttribute() const } +UInt8 *OnelabAttrMergeFile::encodeAttribute(UInt8 *dst) +{ + dst = encode(dst, getAttributeType()); + dst = encode(dst, getAttributeLength()); + + dst = encode(dst, (UInt8 *)_name, _length); + + return dst; +} +UInt8 *OnelabAttrMergeFile::parseAttribute(UInt8 *src, UInt32 length) +{ + if(_name != NULL) free(_name); + _length = length; + _name = (char *)malloc(_length+1); + src = parse(src, (UInt8 *)_name, _length); + _name[_length] = '\0'; + return src; +} +void OnelabAttrMergeFile::setFilename(const std::string name) +{ + if(_name != NULL) free(_name); + + _length = name.size(); + _name = strndup(name.c_str(), _length+1); +} +void OnelabAttrMergeFile::showAttribute() const +{ + std::cout << "\033[1m" << "Attribute merge file:"<< getAttributeType() << "\033[0m"<< std::endl + << "file: " << _name << std::endl; +} + + UInt8 *OnelabAttrFile::encodeAttribute(UInt8 *dst) { dst = encode(dst, getAttributeType()); diff --git a/contrib/onelab2/OnelabAttributes.h b/contrib/onelab2/OnelabAttributes.h index cd8532e781f6ef00744be328a879edc845b5f830..433a501960c209ae8e9ffd839066455913ed922e 100644 --- a/contrib/onelab2/OnelabAttributes.h +++ b/contrib/onelab2/OnelabAttributes.h @@ -177,6 +177,28 @@ public: const char *getFilename() {return _name;} }; +class OnelabAttrMergeFile : public OnelabAttr +{ +private: + char *_name; + UInt16 _length; + +public: + OnelabAttrMergeFile() : _name(NULL), _length(0){} + OnelabAttrMergeFile(const std::string filename) : _name(NULL), _length(0) {setFilename(filename);} + ~OnelabAttrMergeFile() {if(_name != NULL) free(_name);} + UInt8 *encodeAttribute(UInt8 *dst); + UInt8 *parseAttribute(UInt8 *src, UInt32 length); + void showAttribute() const; + + static UInt16 attributeType() {return 0x0D;} + inline UInt16 getAttributeType() const {return attributeType();} + inline UInt16 getAttributeLength() const {return _length;} + + void setFilename(std::string name); + const char *getFilename() {return _name;} +}; + class OnelabAttrFile : public OnelabAttr { private: diff --git a/contrib/onelab2/OnelabDatabase.h b/contrib/onelab2/OnelabDatabase.h index 011ea82958d340ae8ce85cbda6a2ae6d20cdca4a..ea3e8bb1fc6a8791e98c62fb601e954122cc35d4 100644 --- a/contrib/onelab2/OnelabDatabase.h +++ b/contrib/onelab2/OnelabDatabase.h @@ -182,16 +182,21 @@ public: return true; } } - else { - // run Gmsh client - run(action, "Gmsh"); + else { // run all client + run(action, "Gmsh"); // run Gmsh client - // iterate over all other clients - if(CTX::instance()->solverToRun >= 0) { + if(CTX::instance()->solverToRun >= 0) { // launch the solver std::string solver = opt_solver_name(CTX::instance()->solverToRun, GMSH_GET, ""); + std::string exe = opt_solver_executable(CTX::instance()->solverToRun, GMSH_GET, ""); + if(_client && exe.size()) { + onelab::string o(solver + "/CommandLine", exe); + o.setVisible(false); + o.setNeverChanged(true); + set(o, solver); + } run(action, solver); } - else { + else { // send action to all connected client except Gmsh if(_client) { std::cout << "server is remote" << std::endl; msg.attrs.push_back(new OnelabAttrAction(action, client)); diff --git a/contrib/onelab2/OnelabLocalClient.h b/contrib/onelab2/OnelabLocalClient.h index cb71e790825845f2e0ab363acc7ff5a2eebbb45b..f70b3b3b088132c2c2d28f5c89b74a41ddb23e0a 100644 --- a/contrib/onelab2/OnelabLocalClient.h +++ b/contrib/onelab2/OnelabLocalClient.h @@ -22,6 +22,7 @@ public: virtual void onUpdateParameter(onelab::parameter *p){} virtual void onRemoveParameter(onelab::parameter *p){} virtual void onMessage(const std::string &name, const std::string &message, int level){} + virtual void mergeFile(const std::string &filename){} virtual void run(std::string action) {} void stop() {} diff --git a/contrib/onelab2/OnelabNetworkClient.h b/contrib/onelab2/OnelabNetworkClient.h index 5e3da23ef00bcca63836be9ae25de9d3dc82d3d7..148153220c994711f648ce3f31e83512e897d2bf 100644 --- a/contrib/onelab2/OnelabNetworkClient.h +++ b/contrib/onelab2/OnelabNetworkClient.h @@ -140,7 +140,8 @@ public: } virtual void onNewParameter(onelab::parameter *){} virtual void onUpdateParameter(onelab::parameter *){} - virtual void onRemoveParameter(onelab::parameter *){} // TODO call on clear + virtual void onRemoveParameter(onelab::parameter *){} + void onMessage(const std::string &name, const std::string &message, int level) {} // network specific method bool connect(); bool isConnected(){return _connected;} @@ -168,7 +169,15 @@ public: { sendMessage(OnelabAttrMessage::Error, msg); } - + void mergeFile(const std::string &filename) + { + OnelabProtocol msg(OnelabProtocol::OnelabUpdate); + UInt8 buff[1024]; + msg.attrs.push_back(new OnelabAttrMergeFile(filename)); + int recvlen = msg.encodeMsg(buff, 1024); + std::cout <<recvlen << std::endl; + sendto(buff, recvlen); + } }; #endif diff --git a/contrib/onelab2/OnelabProtocol.cpp b/contrib/onelab2/OnelabProtocol.cpp index d8b3d3198f546fc6bd2ff9288481d60525e51fae..93ee70277324d3c4d685e3bdd0a407d3ccf4750b 100644 --- a/contrib/onelab2/OnelabProtocol.cpp +++ b/contrib/onelab2/OnelabProtocol.cpp @@ -27,10 +27,8 @@ unsigned short OnelabProtocol::encodeMsg(UInt8 *buff, UInt32 len) for (std::vector<OnelabAttr*>::iterator it = this->attrs.begin() ; it != this->attrs.end(); ++it) { UInt16 attrLen = (*it)->getAttributeLength(); if(4+_size+attrLen > len) { - // FIXME encode(sizeptr, _size); return (unsigned short)(ptr-buff); - // size = 0; } ptr = (*it)->encodeAttribute(ptr); _size+=attrLen+4; @@ -134,6 +132,10 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len) case 0x0c: this->attrs.push_back(new OnelabAttrFile()); ((OnelabAttrFile *)this->attrs.back())->parseAttribute(ptr, attrSize); + break; + case 0x0d: + this->attrs.push_back(new OnelabAttrMergeFile()); + ((OnelabAttrMergeFile *)this->attrs.back())->parseAttribute(ptr, attrSize); break; default: // FIXME unknown attribute diff --git a/contrib/onelab2/OnelabServer.cpp b/contrib/onelab2/OnelabServer.cpp index 9aabef7e200b44e06787a5bbedce037281be2ca7..f91e743581ca3ce0704dd78de27f06d911452e51 100644 --- a/contrib/onelab2/OnelabServer.cpp +++ b/contrib/onelab2/OnelabServer.cpp @@ -63,13 +63,18 @@ OnelabLocalNetworkClient *OnelabServer::getClient(UDTSOCKET fd) // UDTSOCKET Soc } #endif -int OnelabServer::launchClient(const std::string &client) // FIXME OnelabDatabase instead of OnelabServer ? +int OnelabServer::launchClient(const std::string &client, bool blocking) // FIXME OnelabDatabase instead of OnelabServer ? { // launch a new client with a system call std::string command = ""; if(getClient(client) != NULL || getLocalClient(client) != NULL) return -1; // client already exist - if(client == "Gmsh") { + std::vector<onelab::string> s; + get(s, client + "/CommandLine"); + if(s.size()) { + command.assign(s[0].getValue()); + } + else if(client == "Gmsh") { command.assign(Msg::GetExecutableName()); } else { @@ -106,7 +111,7 @@ int OnelabServer::launchClient(const std::string &client) // FIXME OnelabDatabas sprintf(cmd, command.c_str(), (_ip.address==0)?"127.0.0.1":ip4_inet_ntop(_ip.address).c_str(), _ip.port); std::cout << "launch " << client << " with command: " << cmd << std::endl; - SystemCall(cmd); + SystemCall(cmd, blocking); return 0; } @@ -177,7 +182,7 @@ void OnelabServer::waitForClient(const std::string &name) fd_set errorfds; FD_ZERO(&errorfds); FD_SET(cli->getSSocket(), &errorfds); - select(cli->getSSocket()+1, NULL, NULL, &errorfds, NULL); // Wait for the server to answer + select(cli->getSSocket()+1, NULL, NULL, &errorfds, NULL); // TODO wait until the client close std::cout << "======= cli " << cli->getName() << "just ended ?" << std::cout; } @@ -360,8 +365,13 @@ void *listenOnClients(void *param) break; case OnelabProtocol::OnelabMessage: if(msg.attrs.size()==1 && msg.attrs[0]->getAttributeType() == OnelabAttrMessage::attributeType()) { - OnelabLocalClient *gui = OnelabServer::instance()->getLocalClient("localGUI"); - if(gui) gui->onMessage(cli->getName(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage(), ((OnelabAttrMessage *)msg.attrs[0])->getLevel()); + OnelabLocalClient *localgui = OnelabServer::instance()->getLocalClient("localGUI"); + OnelabLocalNetworkClient *gui = OnelabServer::instance()->getClient("GUI"); + if(gui) { + recvlen = msg.encodeMsg(buff, 1024); + gui->sendto(buff, recvlen); + } + if(localgui) localgui->onMessage(cli->getName(), ((OnelabAttrMessage *)msg.attrs[0])->getMessage(), ((OnelabAttrMessage *)msg.attrs[0])->getLevel()); } break; case OnelabProtocol::OnelabRequest: @@ -401,27 +411,27 @@ void *listenOnClients(void *param) std::cout << "\033[0;31m" << "Client \"" << cli->getName() << " update parameter \"" << attr->getName() << "\"\033[0m" << std::endl; // DEBUG onelab::parameter *parameter = NULL; switch(attr->getAttributeType()) { - case OnelabAttr::Number: - OnelabServer::instance()->set(*(onelab::number *)attr, cli->getName()); - OnelabServer::instance()->getPtr((onelab::number **)¶meter, attr->getName(), cli->getName()); - break; - case OnelabAttr::String: - OnelabServer::instance()->set(*(onelab::string *)attr, cli->getName()); - OnelabServer::instance()->getPtr((onelab::string **)¶meter, attr->getName(), cli->getName()); - break; - case OnelabAttr::Region: - OnelabServer::instance()->set(*(onelab::region *)attr, cli->getName()); - OnelabServer::instance()->getPtr((onelab::region **)¶meter, attr->getName(), cli->getName()); - break; - case OnelabAttr::Function: - OnelabServer::instance()->set(*(onelab::function *)attr, cli->getName()); - OnelabServer::instance()->getPtr((onelab::function **)¶meter, attr->getName(), cli->getName()); - break; + case OnelabAttr::Number: + OnelabServer::instance()->set(*(onelab::number *)attr, cli->getName()); + OnelabServer::instance()->getPtr((onelab::number **)¶meter, attr->getName(), cli->getName()); + break; + case OnelabAttr::String: + OnelabServer::instance()->set(*(onelab::string *)attr, cli->getName()); + OnelabServer::instance()->getPtr((onelab::string **)¶meter, attr->getName(), cli->getName()); + break; + case OnelabAttr::Region: + OnelabServer::instance()->set(*(onelab::region *)attr, cli->getName()); + OnelabServer::instance()->getPtr((onelab::region **)¶meter, attr->getName(), cli->getName()); + break; + case OnelabAttr::Function: + OnelabServer::instance()->set(*(onelab::function *)attr, cli->getName()); + OnelabServer::instance()->getPtr((onelab::function **)¶meter, attr->getName(), cli->getName()); + break; } } else switch((*it)->getAttributeType()) { - case 0x0B: + case 0x0B: { // TODO check if file is on a specific client const char *filename = ((OnelabAttrFileQuery *)*it)->getFilename(); @@ -441,40 +451,37 @@ void *listenOnClients(void *param) std::clog << "file ok" << std::endl; break; } - case 0x0C: - const char *filename = ((OnelabAttrFile *)*it)->getFilename(); - std::clog << "try to open " << filename << " to write" << std::endl; - FILE *fp = fopen(filename, "wb"); - if(fp != NULL){ - std::clog << "file open" << std::endl; - int filesize = ((OnelabAttrFile *)*it)->getFileSize(); - int downloadsize = 0; - while(downloadsize < filesize) { - recvlen = cli->recvfrom(buff, 1024); - fwrite(buff, 1, recvlen, fp); + case 0x0C: + { + const char *filename = ((OnelabAttrFile *)*it)->getFilename(); + std::clog << "try to open " << filename << " to write" << std::endl; + FILE *fp = fopen(filename, "wb"); + if(fp != NULL){ + std::clog << "file open" << std::endl; + int filesize = ((OnelabAttrFile *)*it)->getFileSize(); + int downloadsize = 0; + while(downloadsize < filesize) { + recvlen = cli->recvfrom(buff, 1024); + fwrite(buff, 1, recvlen, fp); + } } + std::clog << "file ok" << std::endl; + break; + } + case 0x0D: + { + // merge file only if the GUI and the server are local + OnelabLocalClient *gui = OnelabServer::instance()->getLocalClient("localGUI"); + if(gui) gui->mergeFile(((OnelabAttrMergeFile *)*it)->getFilename()); } - std::clog << "file ok" << std::endl; - break; } - } - break; + } + break; case OnelabProtocol::OnelabAction: { if(msg.attrs.size()==1 && msg.attrs[0]->getAttributeType() == OnelabAttrAction::attributeType()) { std::clog << "\033[0;31m" << "Client " << cli->getName() << " ask " << ((OnelabAttrAction *)msg.attrs[0])->getClient() << " to " << ((OnelabAttrAction *)msg.attrs[0])->getAction() << "\033[0m" << std::endl; OnelabServer::instance()->performAction(((OnelabAttrAction *)msg.attrs[0])->getAction(), ((OnelabAttrAction *)msg.attrs[0])->getClient()); - //OnelabLocalNetworkClient *cli = OnelabServer::instance()->getClient(((OnelabAttrAction *)msg.attrs[0])->getClient()); - //OnelabLocalClient *localcli = OnelabServer::instance()->getLocalClient(((OnelabAttrAction *)msg.attrs[0])->getClient()); - //std::cout << ((OnelabAttrAction *)msg.attrs[0])->getAction() << " on " << ((OnelabAttrAction *)msg.attrs[0])->getClient() << "(" << cli << " or local " << localcli << ")" << std::endl; - //if(cli == NULL && localcli == NULL) { - //} - //if(cli != NULL) - // cli->run(((OnelabAttrAction *)msg.attrs[0])->getAction()); - //else if(localcli != NULL) - // localcli->run(((OnelabAttrAction *)msg.attrs[0])->getAction()); - //else - // ;// TODO save action and wait for the cli ? } } break; diff --git a/contrib/onelab2/OnelabServer.h b/contrib/onelab2/OnelabServer.h index b3558414ffd4894e9eb9242228c0ab893de37158..a116fecf2f588d4ca8f9410aa4cd190ef3bf0db9 100644 --- a/contrib/onelab2/OnelabServer.h +++ b/contrib/onelab2/OnelabServer.h @@ -58,7 +58,7 @@ public: void addClient(std::string name, UInt32 ip, UInt16 port); #endif void addClient(OnelabLocalClient *cli) {_localClients.push_back(cli);} - int launchClient(const std::string &); + int launchClient(const std::string &, bool blocking=false); void removeClient(OnelabLocalNetworkClient *client); std::vector<OnelabLocalNetworkClient> &getClients() {return _clients;} std::vector<OnelabLocalClient *> &getLocalClients() {return _localClients;}