diff --git a/CMakeLists.txt b/CMakeLists.txt index d9531f46f69836c9f1981d3a572a39bfd4e1dedc..bc64947300f71bbb2cd343b88bb29c05cd16729b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -546,11 +546,10 @@ if(ENABLE_ONELAB2) list(APPEND EXTERNAL_LIBRARIES ${UDT_LIBRARY}) list(APPEND EXTERNAL_INCLUDES ${UDT_INCLUDE_DIR}) else(UDT_INCLUDE_DIR AND UDT_LIBRARY AND Threads_FOUND) - message(FATAL_ERROR "Unable to find UDT library") + message(FATAL_ERROR "Unable to find UDT library or threads") endif(UDT_INCLUDE_DIR AND UDT_LIBRARY AND Threads_FOUND) endif(ENABLE_UDT) set_config_option(HAVE_ONELAB2 "ONELAB2") - set(GMSH_SRC ${GMSH_SRC};Fltk/onelab2Group.cpp;Fltk/onelab2Group.h) add_subdirectory(contrib/onelab2) include_directories(contrib/onelab2) endif(ENABLE_ONELAB2) diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index 2f5613f4002e2b72a1187850f95bd828a1cf6b1c..8050d55b6f35f9d617708c881b410ef470d2f6c4 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -874,8 +874,34 @@ void GetOptions(int argc, char *argv[]) Msg::Fatal("Missing format"); } else if(!strcmp(argv[i] + 1, "listen")) { +#ifndef HAVE_ONELAB2 CTX::instance()->solver.listen = 1; +#else + CTX::instance()->batch = 1; i++; + if(argv[i]) { + CTX::instance()->onelab.listen_port = atoi(argv[i]); + } + else + CTX::instance()->onelab.listen_port = 1148; + // TODO get port if one is provided +#endif + } + else if(!strcmp(argv[i] + 1, "server")) { + CTX::instance()->batch = 1; + i++; + if(argv[i]){ + std::string hostname = std::string(argv[i]); + size_t colon = hostname.find(':'); + if(colon != std::string::npos) { + strcpy(&CTX::instance()->onelab.server_ip[0], hostname.substr(0,colon).c_str()); + CTX::instance()->onelab.server_port = atoi(hostname.substr(colon+1).c_str()); + } + else { + CTX::instance()->onelab.server_ip[0] = '\0'; + CTX::instance()->onelab.server_port = 0; + } + } } else if(!strcmp(argv[i] + 1, "minterpreter")) { i++; diff --git a/Common/Context.h b/Common/Context.h index 9f10362427325c6b4b96069521bc272f673fb607..4da71f888a4d6921bdd0322d940f6d88162b008b 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -252,6 +252,11 @@ class CTX { int autoSaveDatabase, autoArchiveOutputFiles, autoMesh, autoMergeFile; int autoShowViews, autoShowLastStep, autoCheck, showInvisibleParameters; }solver; + // onelab options + struct{ + short listen_port, server_port; + char server_ip[16]; + }onelab; // print options struct{ int fileFormat, epsQuality, epsCompress, epsPS3Shading; diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp index 3d244860b02acfd6c0c3df87c371cfce8a2f8f92..af12a10ac6870aa5ea0f7e5a798197084fb2a4c2 100644 --- a/Common/Gmsh.cpp +++ b/Common/Gmsh.cpp @@ -46,8 +46,19 @@ #include "FlGui.h" #include "graphicWindow.h" #include "drawContext.h" +#if defined(HAVE_ONELAB2) +#include "onelab2Group.h" +#else #include "onelabGroup.h" #endif +#endif + +#if defined(HAVE_ONELAB2) +#include "OnelabDatabase.h" +#include "NetworkUtils.h" + +OnelabDatabase *OnelabDatabase::_instance = NULL; +#endif int GmshInitialize(int argc, char **argv) { @@ -207,6 +218,7 @@ int GmshBatch() MergeFile(CTX::instance()->files[i]); } + #if defined(HAVE_POST) && defined(HAVE_MESH) if(!CTX::instance()->bgmFileName.empty()) { MergePostProcessingFile(CTX::instance()->bgmFileName); @@ -333,7 +345,6 @@ int GmshFLTK(int argc, char **argv) else Msg::Error("Invalid background mesh (no view)"); } - // listen to external solvers if(CTX::instance()->solver.listen){ gmshLocalNetworkClient *c = new gmshLocalNetworkClient("Listen", ""); diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index d94728cd0c5155ed039a6db9a4b51b7a95e47dac..88091b54e0a7efcae12ccf2e9e70ad83e700ab27 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -27,8 +27,11 @@ #if defined(HAVE_ONELAB) #include "onelab.h" -#include "gmshLocalNetworkClient.h" #endif +#if defined(HAVE_ONELAB2) +#include "OnelabDatabase.h" +#endif +#include "gmshLocalNetworkClient.h" #if defined(HAVE_PETSC) #include <petsc.h> @@ -712,7 +715,17 @@ bool Msg::UseOnelab() void Msg::SetOnelabNumber(std::string name, double val, bool visible) { -#if defined(HAVE_ONELAB) +#ifdef HAVE_ONELAB2 + std::vector<onelab::number> numbers; + OnelabDatabase::instance()->get(numbers, name); + if(numbers.empty()) { + numbers.resize(1); + numbers[0].setName(name); + } + numbers[0].setValue(val); + numbers[0].setVisible(visible); + OnelabDatabase::instance()->set(numbers[0], std::string("Gmsh")); +#elif defined(HAVE_ONELAB) if(_onelabClient){ std::vector<onelab::number> numbers; _onelabClient->get(numbers, name); @@ -740,6 +753,9 @@ void Msg::SetOnelabString(std::string name, std::string val, bool visible) strings[0].setValue(val); strings[0].setVisible(visible); _onelabClient->set(strings[0]); +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->set(strings[0], std::string("Gmsh")); +#endif } #endif } @@ -782,6 +798,9 @@ void Msg::InitializeOnelab(const std::string &name, const std::string &sockname) FILE *fp = Fopen(name.c_str(), "rb"); if(fp){ _onelabClient->fromFile(fp); +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->fromFile(fp); +#endif fclose(fp); } else @@ -909,7 +928,11 @@ void Msg::ExchangeOnelabParameter(const std::string &key, } std::vector<onelab::number> ps; +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->get(ps, name); +#else _onelabClient->get(ps, name); +#endif bool noRange = true, noChoices = true, noLoop = true; bool noGraph = true, noClosed = true; if(ps.size()){ @@ -989,8 +1012,12 @@ void Msg::ExchangeOnelabParameter(const std::string &key, if(noClosed && fopt.count("Closed")) ps[0].setAttribute("Closed", fopt["Closed"][0] ? "1" : "0"); _setStandardOptions(&ps[0], fopt, copt); +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->set(ps[0], std::string("Gmsh")); +#else _onelabClient->set(ps[0]); #endif +#endif } void Msg::ExchangeOnelabParameter(const std::string &key, @@ -1014,7 +1041,11 @@ void Msg::ExchangeOnelabParameter(const std::string &key, } std::vector<onelab::string> ps; +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->get(ps, name); +#else _onelabClient->get(ps, name); +#endif bool noChoices = true, noClosed = true, noMultipleSelection = true; if(ps.size()){ if(fopt.count("ReadOnly") && fopt["ReadOnly"][0]) @@ -1043,8 +1074,12 @@ void Msg::ExchangeOnelabParameter(const std::string &key, if(noMultipleSelection && copt.count("MultipleSelection")) ps[0].setAttribute("MultipleSelection", copt["MultipleSelection"][0]); _setStandardOptions(&ps[0], fopt, copt); +#ifdef HAVE_ONELAB2 + OnelabDatabase::instance()->set(ps[0], std::string("Gmsh")); +#else _onelabClient->set(ps[0]); #endif +#endif } void Msg::UndefineOnelabParameter(const std::string &name) diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index 728efd8be31a020b98e4a74c96c52da76d9c1ff2..b30519ccf536def053f9c4a3d07ec1df586b1ffa 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -42,7 +42,11 @@ #if defined(HAVE_FLTK) #include <FL/fl_ask.H> #include "FlGui.h" +#if defined(HAVE_ONELAB2) +#include "onelab2Group.h" +#else #include "onelabGroup.h" +#endif #include "graphicWindow.h" #include "drawContext.h" #endif diff --git a/Common/Options.cpp b/Common/Options.cpp index ff05d8fc639b37436a4cda62741f839872c4e8ad..858af0a28530e4af561d794163058d90482152d9 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -50,7 +50,11 @@ #include "manipWindow.h" #include "contextWindow.h" #include "clippingWindow.h" +#ifdef HAVE_ONELAB2 +#include "onelab2Group.h" +#else #include "onelabGroup.h" +#endif #include "viewButton.h" #include "drawContextFltkCairo.h" #include "drawContextFltkStringTexture.h" diff --git a/Common/onelab.h b/Common/onelab.h index 6bd4942376c6e38513d38c0969c8986e76c3e8ea..b8f47ad690b86996e70fe95b52507585db907cc9 100644 --- a/Common/onelab.h +++ b/Common/onelab.h @@ -371,7 +371,7 @@ namespace onelab{ return src; } - void showAttribute() + void showAttribute() const { std::cout << "Name: " << getName() << std::endl << "Label: " << getLabel() << std::endl @@ -560,7 +560,7 @@ namespace onelab{ return src; } - void showAttribute() + void showAttribute() const { parameter::showAttribute(); std::cout << "Value: " << this->_value << std::endl @@ -671,7 +671,7 @@ namespace onelab{ return src; } - void showAttribute() + void showAttribute() const { parameter::showAttribute(); std::cout << "Value: " << this->_value << std::endl; @@ -813,7 +813,7 @@ namespace onelab{ } return src; } - void showAttribute() {} + void showAttribute() const {} #endif }; @@ -961,7 +961,7 @@ namespace onelab{ } return src; } - void showAttribute() {} + void showAttribute() const {} #endif }; diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp index 803ea54a207618c27948b98b5734b94051a6dc92..aa17c56cd801ccb00596759cf09d007c08577302 100644 --- a/Common/onelabUtils.cpp +++ b/Common/onelabUtils.cpp @@ -22,10 +22,63 @@ #include "PViewOptions.h" #endif +#if defined(HAVE_ONELAB2) +#include "OnelabDatabase.h" +#include "OnelabServer.h" +#endif + namespace onelabUtils { // get command line arguments for the client if "UseCommandLine" is set for // this client +#ifdef HAVE_ONELAB2 + std::vector<std::string> getCommandLine(const std::string client) + { + std::vector<std::string> args; + std::vector<onelab::number> n; + OnelabDatabase::instance()->get(n, client + "/UseCommandLine"); + if(n.size() && n[0].getValue()){ + std::vector<onelab::string> ps; + OnelabDatabase::instance()->get(ps, client + "/Action"); + std::string action = (ps.empty() ? "" : ps[0].getValue()); + OnelabDatabase::instance()->get(ps, client + "/1ModelName"); + std::string modelName = (ps.empty() ? "" : ps[0].getValue()); + OnelabDatabase::instance()->get(ps, client + "/9CheckCommand"); + std::string checkCommand = (ps.empty() ? "" : ps[0].getValue()); + OnelabDatabase::instance()->get(ps, client + "/9ComputeCommand"); + std::string computeCommand = (ps.empty() ? "" : ps[0].getValue()); + if(modelName.size()) args.push_back(" \"" + modelName + "\""); + if(action == "check") + args.push_back(" " + checkCommand) ; + else if(action == "compute") + args.push_back(" " + computeCommand); + } + return args; + } + std::string getMshFileName() + { + std::string name; + std::vector<onelab::string> ps; + OnelabDatabase::instance()->get(ps, "Gmsh/MshFileName"); + if(ps.size()){ + name = ps[0].getValue(); + } + else{ + name = CTX::instance()->outputFileName; + if(name.empty()){ + if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO) + name = GetDefaultFileName(FORMAT_MSH); + else + name = GetDefaultFileName(CTX::instance()->mesh.fileFormat); + } + onelab::string o("Gmsh/MshFileName", name, "Mesh name"); + o.setKind("file"); + o.setAttribute("Closed", "1"); + OnelabDatabase::instance()->set(o, std::string("Gmsh")); + } + return name; +} +#else std::vector<std::string> getCommandLine(onelab::client *c) { std::vector<std::string> args; @@ -50,9 +103,9 @@ namespace onelabUtils { } return args; } - std::string getMshFileName(onelab::client *c) { + std::string name; std::vector<onelab::string> ps; c->get(ps, "Gmsh/MshFileName"); @@ -83,6 +136,7 @@ namespace onelabUtils { */ return name; } +#endif void guessModelName(onelab::client *c) { @@ -294,7 +348,86 @@ namespace onelabUtils { static bool _firstComputation = true; void setFirstComputationFlag(bool val){ _firstComputation = val; } bool getFirstComputationFlag(){ return _firstComputation; } +#ifdef HAVE_ONELAB2 + bool runGmshClient(const std::string &action, int meshAuto) + { + bool redraw = false; + + // do nothing in case of a python metamodel + std::vector<onelab::number> pn; + OnelabDatabase::instance()->get(pn, "IsPyMetamodel"); + if(pn.size() && pn[0].getValue()) return redraw; + + OnelabLocalNetworkClient *c = OnelabServer::instance()->getClient("Gmsh"); + std::cout << ((c != NULL)?"not":"ok") << std::endl; + if(c != NULL) return redraw; // Gmsh is remote TODO + + std::string mshFileName = onelabUtils::getMshFileName(); + + Msg::SetGmshOnelabAction(action); + static std::string modelName = GModel::current()->getName(); + + if(action == "initialize"){ + // nothing to do + } + else if(action == "reset"){ + setFirstComputationFlag(false); + // nothing more to do: "check" will be called right afterwards + } + else if(action == "check"){ + if(OnelabServer::instance()->getChanged("Gmsh") || + modelName != GModel::current()->getName()){ + // reload geometry if Gmsh parameters have been modified or + // if the model name has changed + modelName = GModel::current()->getName(); + redraw = true; + OpenProject(GModel::current()->getFileName(), false); + OnelabServer::instance()->setChanged(true, "Gmsh"); + } + } + else if(action == "compute"){ + std::cout << + "Gmsh getChanged is " << OnelabServer::instance()->getChanged("Gmsh") << std::endl << + "modelName is " << modelName << std::endl << + "current GModel is" << GModel::current()->getName() << std::endl << + "stat file " << mshFileName << " is " << StatFile(mshFileName) << std::endl << + "meshAuto is " << meshAuto + << std::endl; + if(OnelabServer::instance()->getChanged("Gmsh") || + modelName != GModel::current()->getName()){ + // reload the geometry, mesh it and save the mesh if Gmsh parameters + // have been modified or if the model name has changed + modelName = GModel::current()->getName(); + redraw = true; + OpenProject(GModel::current()->getFileName(), false); + if(getFirstComputationFlag() && !StatFile(mshFileName) && meshAuto != 2){ + Msg::Info("Skipping mesh generation: assuming '%s' is up-to-date " + "(use Solver.AutoMesh=2 to force mesh generation)", + mshFileName.c_str()); + } + else if(!GModel::current()->empty() && meshAuto){ + GModel::current()->mesh(3); + CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat); + } + } + else if(StatFile(mshFileName)){ + // mesh+save if the mesh file does not exist + if(meshAuto){ + redraw = true; + GModel::current()->mesh(3); + CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat); + } + } + setFirstComputationFlag(false); + OnelabServer::instance()->setChanged(false, "Gmsh"); + } + + Msg::SetGmshOnelabAction(""); + + return redraw; + } +#else bool runGmshClient(const std::string &action, int meshAuto) { bool redraw = false; @@ -365,7 +498,7 @@ namespace onelabUtils { return redraw; } - +#endif // update x using y, giving priority to any settings in x that can be set in // the GUI. The value of x is only changed if y is read-only. double updateNumber(onelab::number &x, onelab::number &y, const bool readOnlyRange) diff --git a/Common/onelabUtils.h b/Common/onelabUtils.h index 9f77c34646bf90aa84297a1db06b8e5e14b367aa..246467a9b359fb940b409bad039f339f5da70066 100644 --- a/Common/onelabUtils.h +++ b/Common/onelabUtils.h @@ -12,9 +12,15 @@ // onelab servers namespace onelabUtils { +#ifdef HAVE_ONELAB2 + std::vector<std::string> getCommandLine(const std::string client); + std::string getMshFileName(); + void guessModelName(onelab::client *c); // TODO ? +#else std::vector<std::string> getCommandLine(onelab::client *c); std::string getMshFileName(onelab::client *c); void guessModelName(onelab::client *c); +#endif void initializeLoop(const std::string &level); bool incrementLoop(const std::string &level); std::vector<double> getRange(onelab::number &p); diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt index e98342e478f1e99d4b90db0a74a448f8bdee3550..3469ee79bcac6bd44a91f92f3ece12e2406ef111 100644 --- a/Fltk/CMakeLists.txt +++ b/Fltk/CMakeLists.txt @@ -26,7 +26,20 @@ set(SRC projectionEditor.cpp classificationEditor.cpp partitionDialog.cpp +) +if(ENABLE_ONELAB2) + set(SRC + ${SRC} + onelab2Group.cpp + ) +else(ENALBE_ONELAB2) + set(SRC + ${SRC} onelabGroup.cpp + ) +endif(ENABLE_ONELAB2) +set(SRC + ${SRC} inputValue.cpp inputRegion.cpp viewButton.cpp solverButton.cpp Navigator.cpp diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index e24ad18126b1be719220ab4f8b99136272e55616..464d09f70818202a07a135f8cbbb8cae22b8d20d 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -29,7 +29,11 @@ typedef unsigned long intptr_t; #include "clippingWindow.h" #include "manipWindow.h" #include "contextWindow.h" +#ifdef HAVE_ONELAB2 +#include "onelab2Group.h" +#else #include "onelabGroup.h" +#endif #include "helpWindow.h" #include "colorbarWindow.h" #include "fileDialogs.h" diff --git a/Fltk/gmshLocalNetworkClient.h b/Fltk/gmshLocalNetworkClient.h index 8243598e1f0a5d678c9366c5d8696cdf01028ce1..d8b56c77cb1cb971fa15f4eff2cbf6d5ce253347 100644 --- a/Fltk/gmshLocalNetworkClient.h +++ b/Fltk/gmshLocalNetworkClient.h @@ -58,9 +58,15 @@ class gmshLocalNetworkClient : public onelab::localNetworkClient{ } return n; } +#ifdef HAVE_ONELAB2 // Useless code in onelab2 + bool receiveMessage(gmshLocalNetworkClient *master){return true;} + bool run(){return true;} + bool kill(){return true;} +#else bool receiveMessage(gmshLocalNetworkClient *master); bool run(); bool kill(); +#endif }; #endif diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index bff019d8530a82f5262430f151d70a23c794e217..3243f0214fe726d6fd7f2afd34c57fbedf572720 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -33,10 +33,6 @@ typedef unsigned long intptr_t; #include "fieldWindow.h" #include "pluginWindow.h" #include "helpWindow.h" -#include "onelabGroup.h" -#ifdef HAVE_ONELAB2 -#include "onelab2Group.h" -#endif #include "gmshLocalNetworkClient.h" #include "fileDialogs.h" #include "extraDialogs.h" @@ -3027,17 +3023,8 @@ graphicWindow::graphicWindow(bool main, int numTiles, bool detachedMenu) } if(main && !detachedMenu){ -#if defined(HAVE_ONELAB2) - // Hey Maxime, this is for you! - _onelab = NULL; - onelab2Group *_onelab2 = new onelab2Group(0, mh, twidth, height - mh - sh); - _tile->add(_onelab2); - _onelab2->resize(_tile->x(), _tile->y(), twidth, _tile->h()); - _tile->redraw(); -#else _onelab = new onelabGroup(0, mh, twidth, height - mh - sh); _onelab->enableTreeWidgetResize(false); -#endif } else{ _onelab = 0; diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index b3cd3e94bcabda6c9c5b04b1ef583bbe5ef5359d..9ab0116ae42abffab3d9ce28edaba37de7ae58c9 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -19,7 +19,11 @@ #endif #include <FL/Fl_Menu_Bar.H> #include "openglWindow.h" +#ifdef HAVE_ONELAB2 +#include "onelab2Group.h" +#else #include "onelabGroup.h" +#endif class graphicWindow{ private: diff --git a/Fltk/onelab2Group.cpp b/Fltk/onelab2Group.cpp index 981924e3343c8a9825e30a57bbbcf398da440552..2c8a6456ef19859f9837770719b1320a543846f8 100644 --- a/Fltk/onelab2Group.cpp +++ b/Fltk/onelab2Group.cpp @@ -9,34 +9,166 @@ #include "inputRange.h" #include "outputRange.h" #include "inputRegion.h" +#include "drawContext.h" +#include "viewButton.h" +#include "solverButton.h" +#include "Gmsh.h" +#include "onelabUtils.h" #include "OnelabDatabase.h" #include "Options.h" #include "Context.h" -OnelabDatabase *OnelabDatabase::_instance = NULL; +static void initializeLoops() +{ + onelabUtils::initializeLoop("1"); + onelabUtils::initializeLoop("2"); + onelabUtils::initializeLoop("3"); + + if(FlGui::available() && onelab::server::instance()->getChanged()) + FlGui::instance()->rebuildTree(false); +} + +static bool incrementLoops() +{ + bool ret = (onelabUtils::incrementLoop("3") || + onelabUtils::incrementLoop("2") || + onelabUtils::incrementLoop("1")); + + //Define ONELAB parameter indicating whether or not in a loop + onelab::number n("0Metamodel/Loop",ret?1:0); + n.setVisible(false); + onelab::server::instance()->set(n); + + if(FlGui::available() && onelab::server::instance()->getChanged()) + FlGui::instance()->rebuildTree(false); + + return ret; +} + +static void updateGraphs() +{ + bool redraw = false; + for(int i = 0; i < 18; i++){ + std::ostringstream tmp; + tmp << i; + bool ret = onelabUtils::updateGraph(tmp.str()); + redraw = redraw || ret; + } + if(redraw){ + // don't delete the widgets, as this is called in widget callbacks + FlGui::instance()->updateViews(true, false); + drawContext::global()->draw(); + } +} void connect_cb(Fl_Widget *w, void *arg) { - onelab2Group *obj = (onelab2Group *)arg; - obj->clearTree(); - GmshNetworkClient *cli = OnelabDatabase::instance()->useAsNetworkClient(obj->getServerIP(), obj->getServerPort()); - cli->setCallback(obj); - // FIXME just for debug - FILE *fp = fopen("/tmp/onelab.db", "rb"); - if(fp){ - std::cout << "Get database from onelab.db" << std::endl; - OnelabDatabase::instance()->fromFile(fp); - fclose(fp); + if(!arg) return; + onelabGroup *obj = (onelabGroup *)arg; + if(strcmp(w->label(), "Connect") == 0) { + if(!obj->useServer()) return; + obj->clearTree(); + GmshNetworkClient *cli = OnelabDatabase::instance()->useAsNetworkClient(obj->getServerIP(), obj->getServerPort()); + cli->setCallback(obj); + w->label("Disconnect"); + } + else { + obj->clearTree(); + OnelabDatabase::instance()->useAsClient()->setCallback(obj); + w->label("Connect"); } } -void onelab2_cb(Fl_Widget *w, void *data) +void useserver_cb(Fl_Widget *w, void *arg) +{ + if(!arg) return; + Fl_Check_Button *checkbox = (Fl_Check_Button *)w; + onelabGroup *obj = (onelabGroup *)arg; + obj->useServer(checkbox->value() == 1); +} + +void onelab_cb(Fl_Widget *w, void *data) { if(!data) return; std::string action((const char*)data); - OnelabDatabase::instance()->onelab_cb(action); + + if(action == "refresh"){ + updateGraphs(); + 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()); +} + + +void solver_cb(Fl_Widget *w, void *data) +{ + if(!FlGui::instance()->onelab) return; + + int num = (intptr_t)data; + if(num >= 0){ + std::string name = opt_solver_name(num, GMSH_GET, ""); + std::cout << name << ' '; + std::string exe = opt_solver_executable(num, GMSH_GET, ""); + std::string host = opt_solver_remote_login(num, GMSH_GET, ""); + // TODO check if the client exist, if not launch it + OnelabDatabase::instance()->run("initialize", name); + } + if(FlGui::instance()->onelab->isBusy()) + FlGui::instance()->onelab->show(); + else{ + if(CTX::instance()->launchSolverAtStartup >= 0){ + onelab_cb(0, (void*)"reset"); + onelabUtils::setFirstComputationFlag(true); + } + else if(num >= 0) { + onelab_cb(0, (void*)"check"); + } + else { + onelab_cb(0, (void*)"refresh"); + } + FlGui::instance()->onelab->updateGearMenu(); + } + + CTX::instance()->launchSolverAtStartup = -1; +} +void solver_batch_cb(Fl_Widget *w, void *data) +{ + // TODO } static bool getFlColor(const std::string &str, Fl_Color &c) @@ -56,7 +188,7 @@ static bool getFlColor(const std::string &str, Fl_Color &c) return false; } -onelab2Group::onelab2Group(int x, int y, int w, int h, const char *l) +onelabGroup::onelabGroup(int x, int y, int w, int h, const char *l) : Fl_Group(x, y, w, h, l), _stop(false), _enableTreeWidgetResize(false) { int col = FL_BACKGROUND2_COLOR; @@ -79,18 +211,21 @@ onelab2Group::onelab2Group(int x, int y, int w, int h, const char *l) int BB2 = BB / 2 + 4; _butt[0] = new Fl_Button(x + w - 3 * WB - 3 * BB2, y + h - WB - BH, BB2, BH, "Check"); - _butt[0]->callback(onelab2_cb, (void*)"check"); + _butt[0]->callback(onelab_cb, (void*)"check"); _butt[1] = new Fl_Button(x + w - 2 * WB - 2 * BB2, y + h - WB - BH, BB2, BH, "Run"); - _butt[1]->callback(onelab2_cb, (void*)"compute"); + _butt[1]->callback(onelab_cb, (void*)"compute"); - Fl_Check_Button *useServer = new Fl_Check_Button(x+WB, y, w-2*WB, BH, "Use a distant server"); // TODO - Fl_Box *ip_lbl = new Fl_Box(x+WB , y+BH, w-2*WB, BH, "Server IP address:"); - server_ip = new Fl_Input(x+WB, y+2*BH, w-2*WB, BH, "ip"); + Fl_Check_Button *useServer = new Fl_Check_Button(x+WB, y, w-2*WB, BH, "Use a remote server"); + useServer->callback(useserver_cb, this); + /*Fl_Box *ip_lbl = */new Fl_Box(x+WB , y+BH, w-2*WB, BH, "Server IP address:"); + server_ip = new Fl_Input(x+WB, y+2*BH, w-2*WB, BH, ""); server_ip->value("127.0.0.1"); - Fl_Box *port_lbl = new Fl_Box(x+WB , y+3*BH, w-2*WB, BH, "Server port:"); - server_port = new Fl_Input(x+WB, y+4*BH, w-2*WB, BH, "port"); - server_port->value("3456"); + server_ip->readonly(true); + /*Fl_Box *port_lbl = */new Fl_Box(x+WB , y+3*BH, w-2*WB, BH, "Server port:"); + server_port = new Fl_Input(x+WB, y+4*BH, w-2*WB, BH, ""); + server_port->value("1148"); + server_port->readonly(true); Fl_Button *connect_btn = new Fl_Button(x+WB, y+5*BH, w-2*WB, BH, "Connect"); connect_btn->callback(connect_cb, this); @@ -98,12 +233,12 @@ onelab2Group::onelab2Group(int x, int y, int w, int h, const char *l) _widgetLabelRatio = 0.48; OnelabDatabase::instance()->useAsClient()->setCallback(this); } -onelab2Group::~onelab2Group() +onelabGroup::~onelabGroup() { Fl::delete_widget(_tree); } -void onelab2Group::clearTree(bool deleteWidgets) +void onelabGroup::clearTree(bool deleteWidgets) { _tree->clear(); _tree->sortorder(FL_TREE_SORT_ASCENDING); @@ -126,10 +261,77 @@ void onelab2Group::clearTree(bool deleteWidgets) } } -template <class T> -void onelab2Group::addParameter(T &p) +void onelabGroup::openTreeItem(const std::string &name) +{ + Fl_Tree_Item *n = _tree->find_item(name.c_str()); + if(n && n->has_children()){ + n->open(); + _tree->redraw(); + } +} + +void onelabGroup::updateGearMenu() +{ + return; // TODO + Fl_Menu_Item* menu = (Fl_Menu_Item*)_gear->menu(); + int values[8] = {CTX::instance()->solver.autoSaveDatabase, + CTX::instance()->solver.autoArchiveOutputFiles, + CTX::instance()->solver.autoCheck, + CTX::instance()->solver.autoMesh, + CTX::instance()->solver.autoMergeFile, + CTX::instance()->solver.autoShowViews, + CTX::instance()->solver.autoShowLastStep, + CTX::instance()->solver.showInvisibleParameters}; + for(int i = 0; i < 8; i++){ + int idx = _gearOptionsStart - 1 + i; + if(values[i]) + menu[idx].set(); + else + menu[idx].clear(); + } +} + +void onelabGroup::rebuildSolverList() +{ + updateGearMenu(); + + std::vector<std::string> names, exes, hosts; + for(int i = 0; i < NUM_SOLVERS; i++){ + if(opt_solver_name(i, GMSH_GET, "").size()){ + names.push_back(opt_solver_name(i, GMSH_GET, "")); + exes.push_back(opt_solver_executable(i, GMSH_GET, "")); + hosts.push_back(opt_solver_remote_login(i, GMSH_GET, "")); + } + } + for(unsigned int i = 0; i < NUM_SOLVERS; i++){ + if(i < names.size()){ + onelab::server::citer it = onelab::server::instance()->findClient(names[i]); + if(it != onelab::server::instance()->lastClient()) + it->second->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]); + } + else{ + opt_solver_name(i, GMSH_SET, ""); + opt_solver_executable(i, GMSH_SET, ""); + opt_solver_remote_login(i, GMSH_SET, ""); + } + } + + //TODO setButtonVisibility(); + rebuildTree(true); +} +bool onelabGroup::useServer() {return !server_ip->readonly();} +void onelabGroup::useServer(bool use=false) { - std::cout << "add " << p.getName() << " to the tree (visible = " << p.getVisible() << ')' << std::endl; + server_ip->readonly(!use); + server_port->readonly(!use); +} + +void onelabGroup::addParameter(onelab::parameter &p) +{ + std::cout << "add " << p.getName() << " to the tree (visible = " << p.getVisible() << ", changed = " << p.getChanged() << ")" << std::endl; if(!p.getVisible() || CTX::instance()->solver.showInvisibleParameters) return; bool highlight = false; Fl_Color c; @@ -152,7 +354,7 @@ void onelab2Group::addParameter(T &p) _tree->end(); _tree->redraw(); } -Fl_Widget *onelab2Group::_addParameterWidget(onelab::parameter &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::parameter &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) { int type = p.getAttributeType(); if(type == onelab::number::attributeType()) @@ -165,6 +367,47 @@ Fl_Widget *onelab2Group::_addParameterWidget(onelab::parameter &p, int ww, int h return _addParameterWidget(*(onelab::function *)&p, ww, hh, n, highlight, c); return NULL; } + +template<class T> +static void autoCheck(const T &pold, const T &pnew, bool force=false) +{ + if(onelabUtils::getFirstComputationFlag()){ + if(pold.getValue() != pnew.getValue()) + onelabUtils::setFirstComputationFlag(false); + } + + if((CTX::instance()->solver.autoCheck && pnew.getAttribute("AutoCheck") != "0") || + pnew.getAttribute("AutoCheck") == "1"){ + if(force || pold.getValue() != pnew.getValue()) + onelab_cb(0, (void*)"check"); + } +} + +template <class T> +static void setGmshOption(T &n) +{ + std::string opt = n.getAttribute("GmshOption"); + if(opt.empty()) return; + /*if(opt == "ResetDatabase"){ // special option to reset the onelab db + resetDb(false); + FlGui::instance()->rebuildTree(false); + return; + } + if(opt == "Reset"){ // reset db + models except current one + resetDb(false); + for(int i = PView::list.size() - 1; i >= 0; i--) + delete PView::list[i]; + for(int i = GModel::list.size() - 1; i >= 0; i--) + if(GModel::list[i] != GModel::current()) delete GModel::list[i]; + FlGui::instance()->rebuildTree(false); + return; + }*/ + std::string::size_type dot = opt.find('.'); + if(dot == std::string::npos) return; + GmshSetOption(opt.substr(0, dot), opt.substr(dot + 1), n.getValue()); + drawContext::global()->draw(); +} + // callback for number static void onelab_number_input_range_cb(Fl_Widget *w, void *data) { @@ -186,10 +429,10 @@ static void onelab_number_input_range_cb(Fl_Widget *w, void *data) o->doCallbackOnValues(true); numbers[0].setAttribute("Loop", o->loop()); numbers[0].setAttribute("Graph", o->graph()); - //setGmshOption(numbers[0]); - OnelabDatabase::instance()->set(numbers[0]); - //updateGraphs(); - //autoCheck(old, numbers[0]); + setGmshOption(numbers[0]); + OnelabDatabase::instance()->set(numbers[0], std::string("localGUI")); + updateGraphs(); + autoCheck(old, numbers[0]); } } static void onelab_number_choice_cb(Fl_Widget *w, void *data) @@ -203,9 +446,9 @@ static void onelab_number_choice_cb(Fl_Widget *w, void *data) std::vector<double> choices = numbers[0].getChoices(); onelab::number old = numbers[0]; if(o->value() < (int)choices.size()) numbers[0].setValue(choices[o->value()]); - //setGmshOption(numbers[0]); - OnelabDatabase::instance()->set(numbers[0]); - //autoCheck(old, numbers[0]); + setGmshOption(numbers[0]); + OnelabDatabase::instance()->set(numbers[0], std::string("localGUI")); + autoCheck(old, numbers[0]); } } static void onelab_number_check_button_cb(Fl_Widget *w, void *data) @@ -218,13 +461,13 @@ static void onelab_number_check_button_cb(Fl_Widget *w, void *data) Fl_Check_Button *o = (Fl_Check_Button*)w; onelab::number old = numbers[0]; numbers[0].setValue(o->value()); - //setGmshOption(numbers[0]); - OnelabDatabase::instance()->set(numbers[0]); - //autoCheck(old, numbers[0]); + setGmshOption(numbers[0]); + OnelabDatabase::instance()->set(numbers[0], std::string("localGUI")); + autoCheck(old, numbers[0]); } } // add a parameter number to the tree -Fl_Widget *onelab2Group::_addParameterWidget(onelab::number &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) +Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) { char *path = strdup(getPath(n).c_str()); _treeStrings.push_back(path); @@ -322,12 +565,12 @@ static void onelab_string_input_choice_cb(Fl_Widget *w, void *data) if(choices.size()) strings[0].setAttribute("MultipleSelection", choices); //setGmshOption(strings[0]); - OnelabDatabase::instance()->set(strings[0]); - //autoCheck(old, strings[0]); + OnelabDatabase::instance()->set(strings[0], "localGUI"); + autoCheck(old, strings[0]); } } // add parameter string to tree -Fl_Widget *onelab2Group::_addParameterWidget(onelab::string &p, int ww, int hh, +Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) { char *path = strdup(getPath(n).c_str()); @@ -402,7 +645,7 @@ Fl_Widget *onelab2Group::_addParameterWidget(onelab::string &p, int ww, int hh, if(highlight) but->input()->color(c); return but; } -Fl_Widget *onelab2Group::_addParameterWidget(onelab::region &p, int ww, int hh, +Fl_Widget *onelabGroup::_addParameterWidget(onelab::region &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) { char *path = strdup(getPath(n).c_str()); @@ -425,7 +668,7 @@ Fl_Widget *onelab2Group::_addParameterWidget(onelab::region &p, int ww, int hh, return but; } -Fl_Widget *onelab2Group::_addParameterWidget(onelab::function &p, int ww, int hh, +Fl_Widget *onelabGroup::_addParameterWidget(onelab::function &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c) { // non-editable value @@ -438,15 +681,16 @@ Fl_Widget *onelab2Group::_addParameterWidget(onelab::function &p, int ww, int hh } } -void onelab2Group::updateParameter(onelab::parameter &p) +void onelabGroup::updateParameter(onelab::parameter &p) { + std::cout << "update " << p.getName() << " to the tree (visible = " << p.getVisible() << ", changed = " << p.getChanged() << ")" << std::endl; int type = p.getAttributeType(); if(type == onelab::number::attributeType()) return updateParameter(*(onelab::number *)&p); if(type == onelab::string::attributeType()) return updateParameter(*(onelab::string *)&p); } -void onelab2Group::updateParameter(onelab::number &p) +void onelabGroup::updateParameter(onelab::number &p) { Fl_Tree_Item *n = _tree->find_item(p.getName().c_str()); if(!n) { @@ -506,7 +750,7 @@ void onelab2Group::updateParameter(onelab::number &p) but->loop(p.getAttribute("Loop")); but->graph(p.getAttribute("Graph")); } -void onelab2Group::updateParameter(onelab::string &p) +void onelabGroup::updateParameter(onelab::string &p) { Fl_Tree_Item *n = _tree->find_item(p.getName().c_str()); if(!n) { @@ -538,19 +782,26 @@ void onelab2Group::updateParameter(onelab::string &p) but->value(p.getValue().c_str()); } -void onelab2Group::removeParameter(onelab::parameter &p) +void onelabGroup::removeParameter(onelab::parameter &p) { Fl_Tree_Item *n = _tree->find_item(p.getName().c_str()); _tree->remove(n); } -void onelab2Group::_computeWidths() +void onelabGroup::_computeWidths() { _baseWidth = (int)(_tree->w() - _tree->marginleft()); _indent = (int)(_tree->connectorwidth() / 2. + _tree->openicon()->w() / 2.); } -std::string onelab2Group::getPath(Fl_Tree_Item *item) +bool onelabGroup::isBusy() +{ + std::string s(_butt[1]->label()); + if(s == "Run") return false; + return true; +} + +std::string onelabGroup::getPath(Fl_Tree_Item *item) { if(!item){ Msg::Error("No item for path"); @@ -564,3 +815,72 @@ std::string onelab2Group::getPath(Fl_Tree_Item *item) return std::string(path); } +void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void *data) +{ + Fl_Tree_Item *n = _tree->add(path.c_str()); + _tree->begin(); + int ww = _baseWidth - (n->depth() + 1) * _indent; + int hh = n->labelsize() + 4; + Fl_Group *grp = new Fl_Group(1, 1, ww, hh); + Fl_Button *but = new Fl_Button(1, 1, ww, hh); + but->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + but->callback(callback, data); + but->box(FL_FLAT_BOX); + but->color(_tree->color()); + but->selection_color(_tree->color()); + grp->end(); + if(!_enableTreeWidgetResize) grp->resizable(0); + _treeWidgets.push_back(grp); + std::string label = path; + std::string::size_type last = path.find_last_of('/'); + if(last != std::string::npos) label = path.substr(last + 1); + but->copy_label(label.c_str()); + n->widget(grp); + _tree->end(); +} + +void onelabGroup::_addSolverMenu(int num) +{ + std::ostringstream path; + path << "0Modules/Solver/Solver" << num; + Fl_Tree_Item *n = _tree->add(path.str().c_str()); + int ww = _baseWidth - (n->depth() + 1) * _indent; + int hh = n->labelsize() + 4; + _tree->begin(); + Fl_Group *grp = new Fl_Group(1, 1, ww, hh); + new solverButton(1, 1, ww, hh, num, _tree->color()); + grp->end(); + if(!_enableTreeWidgetResize) grp->resizable(0); + _treeWidgets.push_back(grp); + n->widget(grp); + _tree->end(); +} + +void onelabGroup::_addViewMenu(int num) +{ + std::ostringstream path; + path << "0Modules/Post-processing/View" << num; + Fl_Tree_Item *n = _tree->add(path.str().c_str()); + int ww = _baseWidth - (n->depth() + 1) * _indent; + int hh = n->labelsize() + 4; + _tree->begin(); + Fl_Group *grp = new Fl_Group(1, 1, ww, hh); + new viewButton(1, 1, ww, hh, num, _tree->color()); + grp->end(); + if(!_enableTreeWidgetResize) grp->resizable(0); + _treeWidgets.push_back(grp); + n->widget(grp); + _tree->end(); +} + +viewButton *onelabGroup::getViewButton(int num) +{ + char tmp[256]; + sprintf(tmp, "0Modules/Post-processing/View%d", num); + Fl_Tree_Item *n = _tree->find_item(tmp); + if(n){ + Fl_Group *grp = (Fl_Group*)n->widget(); + return (viewButton*)grp->child(0); + } + return 0; +} diff --git a/Fltk/onelab2Group.h b/Fltk/onelab2Group.h index cc36060762f71750273f9d36b474e4e33c6d1480..b212741e66e28dd0ec8df1c525456c9b949a25e8 100644 --- a/Fltk/onelab2Group.h +++ b/Fltk/onelab2Group.h @@ -12,7 +12,9 @@ #include "NetworkUtils.h" #include "onelab.h" -class onelab2Group : public Fl_Group{ +class viewButton; + +class onelabGroup : public Fl_Group{ private: Fl_Input *server_ip, *server_port; Fl_Tree *_tree; @@ -34,21 +36,53 @@ private: Fl_Widget *_addParameterWidget(onelab::function &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c); Fl_Widget *_addParameterWidget(onelab::region &p, int ww, int hh, Fl_Tree_Item *n, bool highlight, Fl_Color c); void _computeWidths(); + void _addMenu(const std::string &path, Fl_Callback *callback, void *data); + void _addSolverMenu(int num); + void _addViewMenu(int num); + std::set<std::string> _getClosedGmshMenus(); + void _addGmshMenus(); public: - onelab2Group(int x, int y, int w, int h, const char *l=0); - ~onelab2Group(); + onelabGroup(int x, int y, int w, int h, const char *l=0); + ~onelabGroup(); + void updateGearMenu(); + void rebuildSolverList(); + void rebuildTree(bool deleteWidgets){} // useless in ONELAB2 ? + void enableTreeWidgetResize(bool value){ _enableTreeWidgetResize = value; } void clearTree(bool deleteWidgets=true); + void openTreeItem(const std::string &name); void createRemoteTree(bool keepLocal=true); UInt32 getServerIP() {return ip4_inet_pton(server_ip->value());} UInt16 getServerPort() {return (UInt16)strtoul(server_port->value(), NULL, 0);} - template <class T> void addParameter(T &p); + bool useServer(); + void useServer(bool); + bool isBusy(); + int getMinWindowWidth(){ return _minWindowWidth; } + int getMinWindowHeight(){ return _minWindowHeight; } + //template <class T> void addParameter(T &p); + void addParameter(onelab::parameter &p); void updateParameter(onelab::parameter &p); void updateParameter(onelab::number &p); void updateParameter(onelab::string &p); void removeParameter(onelab::parameter &p); std::string getPath(Fl_Tree_Item *item); + void insertInManuallyClosed(const std::string &path) + { + _manuallyClosed.insert(path); + } + void removeFromManuallyClosed(const std::string &path) + { + _manuallyClosed.erase(path); + } + bool isManuallyClosed(const std::string &path) + { + return _manuallyClosed.find(path) != _manuallyClosed.end(); + } + viewButton *getViewButton(int num); }; void connect_cb(Fl_Widget *w, void *arg); +void onelab_cb(Fl_Widget *w, void *data); +void solver_cb(Fl_Widget *w, void *data); +void solver_batch_cb(Fl_Widget *w, void *data); #endif diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp index d48af39bb720f3ce3a84735ef63bd78ebfc3c091..65c571f7bfeb5518718f73e528cad2a7c81b8c5b 100644 --- a/Fltk/onelabGroup.cpp +++ b/Fltk/onelabGroup.cpp @@ -931,7 +931,7 @@ void onelab_cb(Fl_Widget *w, void *data) // for this solver onelab::server::instance()->setChanged(false, c->getName()); - FlGui::instance()->onelab->checkForErrors(c->getName()); + FlGui::instance()->onelab->checkForErrors(c->getName()); } if(FlGui::instance()->onelab->stop()) break; } diff --git a/Fltk/viewButton.cpp b/Fltk/viewButton.cpp index ad1c7aa0bb3053eae44d0452b39176046d2c4b7a..d7612245a707753285cc191e94d9d4ea8d2b305f 100644 --- a/Fltk/viewButton.cpp +++ b/Fltk/viewButton.cpp @@ -18,7 +18,11 @@ #include "OpenFile.h" #include "Field.h" #include "OS.h" +#ifdef HAVE_ONELAB2 +#include "onelab2Group.h" +#else #include "onelabGroup.h" +#endif #include "viewButton.h" static void view_toggle_cb(Fl_Widget *w, void *data) diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp index 82c579034ba528b000372201f29be736df5fd04f..1c1471249f60a617dddc605e377f921fb1ab1ba4 100644 --- a/Geo/GeoStringInterface.cpp +++ b/Geo/GeoStringInterface.cpp @@ -23,6 +23,9 @@ #if defined(HAVE_ONELAB) #include "onelab.h" #endif +#if defined(HAVE_ONELAB2) +#include "OnelabDatabase.h" +#endif void add_infile(std::string text, std::string fileName, bool forceDestroy) { @@ -139,6 +142,9 @@ void add_infile(std::string text, std::string fileName, bool forceDestroy) #if defined(HAVE_ONELAB) onelab::server::instance()->setChanged(true, "Gmsh"); #endif +#if defined(HAVE_ONELAB2) + OnelabDatabase::instance()->setChanged(true, "Gmsh"); +#endif } void coherence(std::string fileName) diff --git a/contrib/onelab2/CMakeLists.txt b/contrib/onelab2/CMakeLists.txt index ef37305050f069b82fe6372e5a3db32a420ffadb..64e683f0f0e1466120903a3de05e130b39bfd05f 100644 --- a/contrib/onelab2/CMakeLists.txt +++ b/contrib/onelab2/CMakeLists.txt @@ -1,10 +1,13 @@ set(SRC NetworkUtils.cpp OnelabAttributes.cpp + OnelabDatabase.cpp OnelabProtocol.cpp OnelabLocalNetworkClient.cpp OnelabServer.cpp - OnelabNetworkClient.cpp) + OnelabNetworkClient.cpp + GmshNetworkClient.cpp + GmshLocalClient.cpp) file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) append_gmsh_src(contrib/onelab2 "${SRC};${HDR}") diff --git a/contrib/onelab2/GmshLocalClient.h b/contrib/onelab2/GmshLocalClient.h index 69846e2510db92508305d8b7674680b1f48532a2..9c87fcf9af12c6fdfbd8529dcb7ace22bcd4899a 100644 --- a/contrib/onelab2/GmshLocalClient.h +++ b/contrib/onelab2/GmshLocalClient.h @@ -3,19 +3,33 @@ #include "OnelabLocalClient.h" +#ifdef HAVE_FLTK +class onelabGroup; +#endif + class GmshLocalClient : public OnelabLocalClient { private: - onelab2Group *_cb_obj; +#ifdef HAVE_FLTK + onelabGroup *_cb_obj; +#endif public: +#ifdef HAVE_FLTK GmshLocalClient(std::string name, onelab::parameterSpace *parameterSpace) : OnelabLocalClient(name, parameterSpace){ + _cb_obj = NULL; } ~GmshLocalClient(){} - void setCallback(onelab2Group *cb) {_cb_obj = cb;} - void onNewParameter(onelab::parameter *p){_cb_obj->addParameter(*p);} - void onUpdateParameter(onelab::parameter *p){_cb_obj->updateParameter(*p);} - void onRemoveParameter(onelab::parameter *p){_cb_obj->removeParameter(*p);} + void setCallback(onelabGroup *cb); + void onNewParameter(onelab::parameter *p); + void onUpdateParameter(onelab::parameter *p); + void onRemoveParameter(onelab::parameter *p); +#else + GmshLocalClient(std::string name, onelab::parameterSpace *parameterSpace) + : OnelabLocalClient(name, parameterSpace){} +#endif + + void run(std::string action); }; #endif diff --git a/contrib/onelab2/GmshNetworkClient.h b/contrib/onelab2/GmshNetworkClient.h index 90b80687bdd95a3b0bc0bae22d13ad3b28ad3690..3ba86cd6babdd3b9fd10bd3a621fafb5495d731a 100644 --- a/contrib/onelab2/GmshNetworkClient.h +++ b/contrib/onelab2/GmshNetworkClient.h @@ -8,20 +8,28 @@ #include "OnelabNetworkClient.h" #include "OnelabProtocol.h" -class onelab2Group; +#ifdef HAVE_FLTK +class onelabGroup; +#endif class GmshNetworkClient : public OnelabNetworkClient { private: - onelab2Group *_cb_obj; +#ifdef HAVE_FLTK + onelabGroup *_cb_obj; +#endif public: +#ifdef HAVE_FLTK + GmshNetworkClient(std::string name) : OnelabNetworkClient(name) {_cb_obj=NULL;} + GmshNetworkClient(std::string name, unsigned int ip, unsigned short port) : OnelabNetworkClient(name, ip, port) {_cb_obj =NULL;} + void setCallback(onelabGroup *cb); + void onNewParameter(onelab::parameter *p); + void onUpdateParameter(onelab::parameter *p); + void onRemoveParameter(onelab::parameter *p); +#else GmshNetworkClient(std::string name) : OnelabNetworkClient(name) {} GmshNetworkClient(std::string name, unsigned int ip, unsigned short port) : OnelabNetworkClient(name, ip, port) {} - ~GmshNetworkClient() {} - void setCallback(onelab2Group *cb) {_cb_obj = cb;} - void onNewParameter(onelab::parameter *p){_cb_obj->addParameter(*p);} - void onUpdateParameter(onelab::parameter *p){_cb_obj->updateParameter(*p);} - void onRemoveParameter(onelab::parameter *p){_cb_obj->removeParameter(*p);} +#endif }; #endif diff --git a/contrib/onelab2/NetworkUtils.cpp b/contrib/onelab2/NetworkUtils.cpp index 71cbe9eb63ee9b19320cc590e20bcc821f6750a4..0aec45a55fe57270190d311d790264919442ebdf 100644 --- a/contrib/onelab2/NetworkUtils.cpp +++ b/contrib/onelab2/NetworkUtils.cpp @@ -106,7 +106,6 @@ int ip4_socket_send(Socket fd, UInt8 *src, int length, IPv4 dst) // 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; - //usleep(100000); return (int)sent; } diff --git a/contrib/onelab2/OnelabAttributes.cpp b/contrib/onelab2/OnelabAttributes.cpp index 4910149be88caef69f27a6edb0e277bfa45a038a..c6d67b5cf5b769b0636ed55168ff19f075314ea1 100644 --- a/contrib/onelab2/OnelabAttributes.cpp +++ b/contrib/onelab2/OnelabAttributes.cpp @@ -18,7 +18,7 @@ UInt8 *OnelabAttrStart::parseAttribute(UInt8 *src, UInt32 length) return src+length; } -void OnelabAttrStart::showAttribute() +void OnelabAttrStart::showAttribute() const { std::cout << "\033[1m" << "Attribute start:"<< getAttributeType() << "\033[0m"<< std::endl << "name: " << _name << std::endl; @@ -43,7 +43,7 @@ UInt8 *OnelabAttrParameterQuery::parseAttribute(UInt8 *src, UInt32 length) return src+length; } -void OnelabAttrParameterQuery::showAttribute() +void OnelabAttrParameterQuery::showAttribute() const { std::cout << "\033[1m" << "Attribute parameter query:"<< getAttributeType() << "\033[0m"<< std::endl << "type: " << this->_ptype << std::endl @@ -72,14 +72,14 @@ UInt8 *OnelabAttrMessage::parseAttribute(UInt8 *src, UInt32 length) return src; } -void OnelabAttrMessage::showAttribute() +void OnelabAttrMessage::showAttribute() const { std::cout << "Attribute message:" << std::endl << "Level: " << _level << std::endl << "Message: " << _message << std::endl; } -UInt8 *OnelabAttrAction::encodeAttibute(UInt8 *dst) +UInt8 *OnelabAttrAction::encodeAttribute(UInt8 *dst) { dst = encode(dst, getAttributeType()); dst = encode(dst, getAttributeLength()); @@ -90,7 +90,7 @@ UInt8 *OnelabAttrAction::encodeAttibute(UInt8 *dst) return dst; } -UInt8 *OnelabAttrAction::parseAttibute(UInt8 *src, UInt32 length) +UInt8 *OnelabAttrAction::parseAttribute(UInt8 *src, UInt32 length) { _client.assign((char *)src); src += _client.size()+1; @@ -99,6 +99,13 @@ UInt8 *OnelabAttrAction::parseAttibute(UInt8 *src, UInt32 length) return src; } +void OnelabAttrAction::showAttribute() const +{ + std::cout << "\033[1m" << "Attribute action:"<< getAttributeType() << "\033[0m"<< std::endl + << "client (target): " << _client << std::endl + << "action: " << _action << std::endl; +} + UInt8 *OnelabAttrFileQuery::encodeAttribute(UInt8 *dst) { dst = encode(dst, getAttributeType()); @@ -126,6 +133,13 @@ void OnelabAttrFileQuery::setFilename(const std::string name) _length = name.size(); _name = strndup(name.c_str(), _length); } +void OnelabAttrFileQuery::showAttribute() const +{ + std::cout << "\033[1m" << "Attribute file query:"<< getAttributeType() << "\033[0m"<< std::endl + << "client (file): " << _client << std::endl + << "file: " << _name << std::endl; +} + UInt8 *OnelabAttrFile::encodeAttribute(UInt8 *dst) { @@ -145,3 +159,8 @@ UInt8 *OnelabAttrFile::parseAttribute(UInt8 *src, UInt32 length) _name = strndup((char *)src, length-4); return src+length-4; } +void OnelabAttrFile::showAttribute() const +{ + std::cout << "\033[1m" << "Attribute file:"<< getAttributeType() << "\033[0m"<< std::endl + << "file: " << _name << std::endl; +} diff --git a/contrib/onelab2/OnelabAttributes.h b/contrib/onelab2/OnelabAttributes.h index b7dac34e1cb11f79daef882e4ab88f52a5913b29..7a8b7fe6b5a9cc1dde61ad3508d15c8f17379611 100644 --- a/contrib/onelab2/OnelabAttributes.h +++ b/contrib/onelab2/OnelabAttributes.h @@ -25,7 +25,7 @@ public: virtual UInt8 *encodeAttribute(UInt8 *dst) = 0; virtual UInt8 *parseAttribute(UInt8 *src, UInt32 length) = 0; - virtual void showAttribute() = 0; + virtual void showAttribute() const = 0; virtual inline UInt16 getAttributeType() const = 0; virtual inline UInt16 getAttributeLength() const = 0; @@ -61,7 +61,7 @@ public: ~OnelabAttrStart(){} UInt8 *encodeAttribute(UInt8 *dst); UInt8 *parseAttribute(UInt8 *src, UInt32 length); - void showAttribute(); + void showAttribute() const; static UInt16 attributeType() {return 0x04;} inline UInt16 getAttributeType() const {return this->attributeType();} @@ -81,7 +81,7 @@ public: ~OnelabAttrParameterQuery() {} UInt8 *encodeAttribute(UInt8 *buff); UInt8 *parseAttribute(UInt8 *buff, UInt32 length); - void showAttribute(); + void showAttribute() const; static UInt16 attributeType() {return 0x05;} inline UInt16 getAttributeType() const {return this->attributeType();} @@ -94,17 +94,17 @@ public: class OnelabAttrMessage : public OnelabAttr { private: - UInt8 _level; - UInt8 *_message; + UInt8 *_message = NULL; UInt16 _messageLength; + UInt8 _level; public: - OnelabAttrMessage() {this->_message = NULL; this->_level = 0;} - OnelabAttrMessage(std::string message, const int level=OnelabAttrMessage::Debug) {setMessage(message, level);} + OnelabAttrMessage() : _message(NULL), _messageLength(0), _level(0) {} + OnelabAttrMessage(std::string message, const int level=OnelabAttrMessage::Debug) : _message(NULL){setMessage(message, level);} ~OnelabAttrMessage(){if(_message != NULL) free(_message);}; UInt8 *encodeAttribute(UInt8 *dst); UInt8 *parseAttribute(UInt8 *src, UInt32 length); - void showAttribute(); + void showAttribute() const; static UInt16 attributeType() {return 0x0A;} inline UInt16 getAttributeType() const {return this->attributeType();} @@ -134,18 +134,19 @@ class OnelabAttrAction : public OnelabAttr private: std::string _action; std::string _client; + public: OnelabAttrAction() : _action(""), _client("") {} OnelabAttrAction(std::string action, std::string client) : _action(action), _client(client) {} ~OnelabAttrAction() {} - static UInt16 attributeType() {return 0x10;} - inline UInt16 getAttibuteType() const {return attributeType();} - inline UInt16 getAttibuteLength() const {return _client.size()+1+_action.size();} + UInt8 *encodeAttribute(UInt8 *dst); + UInt8 *parseAttribute(UInt8 *src, UInt32 lenght); + void showAttribute() const; - UInt8 *encodeAttibute(UInt8 *dst); - UInt8 *parseAttibute(UInt8 *src, UInt32 lenght); - void showAttribute() {} + static UInt16 attributeType() {return 0x10;} + inline UInt16 getAttributeType() const {return attributeType();} + inline UInt16 getAttributeLength() const {return _client.size()+1+_action.size();} void setAction(std::string action) {_action = action;} void setClient(std::string client) {_client = client;} @@ -166,7 +167,7 @@ public: ~OnelabAttrFileQuery() {if(_name != NULL) free(_name);} UInt8 *encodeAttribute(UInt8 *dst); UInt8 *parseAttribute(UInt8 *src, UInt32 length); - void showAttribute(){} + void showAttribute() const; static UInt16 attributeType() {return 0x0B;} inline UInt16 getAttributeType() const {return attributeType();} @@ -190,7 +191,7 @@ public: ~OnelabAttrFile() {if(_name != NULL) free(_name);} UInt8 *encodeAttribute(UInt8 *dst); UInt8 *parseAttribute(UInt8 *src, UInt32 length); - void showAttribute(){} + void showAttribute() const; static UInt16 attributeType() {return 0x0C;} inline UInt16 getAttributeType() const {return attributeType();} diff --git a/contrib/onelab2/OnelabDatabase.h b/contrib/onelab2/OnelabDatabase.h index 906717f8cd6438e6292c6b09666e82789a5cc322..467e54e3a4061f3852c0bd36f61c3b59d79da6d1 100644 --- a/contrib/onelab2/OnelabDatabase.h +++ b/contrib/onelab2/OnelabDatabase.h @@ -1,12 +1,15 @@ +#ifndef _ONELABDATABASE_H_ +#define _ONELABDATABASE_H_ +#endif #include <signal.h> #include <stdio.h> #include "GmshMessage.h" +#include "onelabUtils.h" #include "OnelabServer.h" +#include "VirtualClient.h" #include "GmshNetworkClient.h" #include "GmshLocalClient.h" -#include "onelabUtils.h" - #ifndef WIN32 void *OnelabDatabase_listen(void *arg); @@ -16,8 +19,6 @@ DWORD WINAPI OnelabDatabase_listen(LPVOID arg); DWORD WINAPI OnelabDatabase_server(void *arg); #endif -OnelabServer *OnelabServer::_server = NULL; - // OnelabDatabase is a singleton that get/set/... parameters from server/clients class OnelabDatabase { private: @@ -27,8 +28,10 @@ private: #else HANDLER _listenThread, _serverThread; #endif + bool _haveToStop; + std::string _action; GmshNetworkClient *_client; - GmshLocalClient *_localClient; + GmshLocalClient *_localGUI, *_localGmsh; void _clear() { #ifndef WIN32 // TODO send message to thread to exit the thread @@ -37,14 +40,19 @@ private: #else // TODO #endif - if(_client) delete _client; - if(_localClient) delete _localClient; - _client = NULL; _localClient = NULL; + if(_client) { + _client->disconnect(); + delete _client; + } + if(_localGUI) delete _localGUI; + if(_localGmsh) delete _localGmsh; + _client = NULL; _localGUI = _localGmsh = NULL; } public: OnelabDatabase() { - _localClient = NULL; _client = NULL; + _localGUI = NULL; _client = NULL; _localGmsh = NULL; + _action = ""; _haveToStop = false; } static OnelabDatabase *instance() { if(!_instance) _instance = new OnelabDatabase; @@ -56,33 +64,55 @@ public: OnelabServer::instance(0x7F000001, 0); //OnelabServer::instance(0, 0); - _localClient = new GmshLocalClient("localGUI", OnelabServer::instance()->getParameterSpace()); - OnelabServer::instance()->addClient(_localClient); // TODO remove from server in _clear() + _localGUI = new GmshLocalClient("localGUI", OnelabServer::instance()->getParameterSpace()); + _localGmsh = new GmshLocalClient("Gmsh", OnelabServer::instance()->getParameterSpace()); + OnelabServer::instance()->addClient(_localGUI); // TODO remove from server in _clear() + OnelabServer::instance()->addClient(_localGmsh); // TODO remove from server in _clear() #ifndef WIN32 - pthread_create(&_serverThread, NULL, OnelabDatabase_server, NULL); + pthread_create(&_serverThread, NULL, OnelabDatabase_server, &(((OnelabLocalClient *)_localGmsh)->getName())); #else _serverThread = CreateThread(NULL, 0, NULL, OnelabDatabase_server, 0, NULL); #endif - return _localClient; + return _localGUI; } - GmshNetworkClient *useAsNetworkClient(UInt32 address, UInt16 port){ + GmshNetworkClient *useAsNetworkClient(UInt32 address, UInt16 port, std::string cli="GUI"){ // use this as a network client (take server address/port) - _clear(); + if(!_client) { + _clear(); - _client = new GmshNetworkClient("GUI", address, port); - if(_client->connect()) { + _client = new GmshNetworkClient(cli, address, port); + if(_client->connect()) { +#ifndef WIN32 + pthread_create(&_listenThread, NULL, OnelabDatabase_listen, &(((OnelabLocalClient *)_client)->getName())); +#else + _listenThread = CreateThread(NULL, 0, NULL, OnelabDatabase_listen, 0, NULL); +#endif + return _client; + } + else { + Msg::Error("Unable to connect to the server!"); + return NULL; + } + } + else { #ifndef WIN32 - pthread_create(&_listenThread, NULL, OnelabDatabase_listen, NULL); + pthread_create(&_listenThread, NULL, OnelabDatabase_listen, &(((OnelabLocalClient *)_client)->getName())); #else _listenThread = CreateThread(NULL, 0, NULL, OnelabDatabase_listen, 0, NULL); #endif return _client; } - else - Msg::Error("Unable to connect to the server!"); return NULL; } + void networkClientHaveToStop(bool haveToStop) {_haveToStop = haveToStop;} + bool networkClientHaveToStop() {return _haveToStop;} + void haveToDo(const std::string action) {_action = action;} + std::string &actionToDo() {return _action;} + int wait() { + if(_client) return pthread_join(_listenThread, NULL); + return pthread_join(_serverThread, NULL); + } int listen(UInt8 *buff, unsigned int maxlen){ if(_client) return _client->recvfrom(buff, maxlen); return 0; @@ -95,25 +125,28 @@ public: _clear(); OnelabServer::instance(address, port); - _localClient = new GmshLocalClient("localGUI", OnelabServer::instance()->getParameterSpace()); + _localGUI = new GmshLocalClient("localGUI", OnelabServer::instance()->getParameterSpace()); #ifndef WIN32 pthread_create(&_serverThread, NULL, OnelabDatabase_server, NULL); #else _serverThread = CreateThread(NULL, 0, NULL, OnelabDatabase_server, 0, NULL); #endif - return _localClient; - } - template <class T> bool set(const T &p, bool update=true) { - if(_client) return _client->set(p, update); - //if(_localClient) return _localClient->set(p); - return OnelabServer::instance()->set(p, ""); + return _localGUI; } template <class T> bool set(const T &p, const std::string &client) { + std::cout<<"set "<<p.getName()<<" from "<<client<<std::endl; + if(_client) return _client->set(p, true); return OnelabServer::instance()->set(p, client); } + template <class T> bool set(const T &p, bool update=true) { + std::cout<<"set "<<p.getName()<<std::endl; + if(_client) return _client->set(p, update); + //if(_localGUI) return _localGUI->set(p); + return OnelabServer::instance()->set(p); + } template <class T> bool get(std::vector<T> &ps, const std::string &name="", const std::string &client="") { if(_client) return _client->get(ps, name); - //if(_localClient) _localClient->get(ps, name); + //if(_localGUI) _localGUI->get(ps, name); return OnelabServer::instance()->get(ps, name, client); } bool fromFile(FILE *fp, const std::string &client="") @@ -122,116 +155,62 @@ public: return OnelabServer::instance()->fromFile(fp, client); } - void onelab_cb(std::string action) { - if(_client) return; // TODO send action to the server - if(action == "stop"){ - //FlGui::instance()->onelab->stop(true); - if(_client) _client->stop(); + bool run(const std::string action, const std::string client="") { + UInt8 buff[1024]; + OnelabProtocol msg(OnelabProtocol::OnelabAction); + if(client.size()) { + std::cout << "try to " << action << ' ' << client << std::endl; + onelab::string o(client + "/Action", action); + o.setVisible(false); + o.setNeverChanged(true); + set(o); + if(_client && ((OnelabLocalClient *)_client)->getName() == client) { + if(client == "Gmsh") onelabUtils::runGmshClient(action, true); + } + else if(_client) { + std::cout << "client is remote" << std::endl; + msg.attrs.push_back(new OnelabAttrAction(action, client)); + int size = msg.encodeMsg(buff, 1024); + sendbytes(buff, size); + return true; + } + else { + std::cout << "client is local" << std::endl; + OnelabServer::instance()->performAction(action, client); + return true; + } } - //TODO if(action == "compute") initializeLoops(); + else { + // run Gmsh client + run(action, "Gmsh"); - do { - for (std::vector<OnelabLocalNetworkClient>::iterator it = OnelabServer::instance()->getClients().begin() ; it != OnelabServer::instance()->getClients().end(); ++it) - { - onelab::string o((*it).getName() + "/Action", action); - o.setVisible(false); - o.setNeverChanged(true); - this->set(o); - (*it).run(); + // iterate over all other clients + if(_client) { + std::cout << "server is remote" << std::endl; + msg.attrs.push_back(new OnelabAttrAction(action, client)); + int size = msg.encodeMsg(buff, 1024); + sendbytes(buff, size); + return true; } - - } while(action == "compute" && - //TODO incrementLoops() && - !false/*TODO onelab->stop*/); - + else { + std::cout << "server is local" << std::endl; + OnelabServer::instance()->performAction(action); + return true; + } + } + return false; + } + bool getChanged(const std::string &client="") const { + if(!_client) + return OnelabServer::instance()->getChanged(client); + else + return true; // TODO + } + void setChanged(bool changed, const std::string &client="") { + if(!_client) + OnelabServer::instance()->setChanged(changed, client); + else + return; // TODO } }; -#ifndef WIN32 -void *OnelabDatabase_listen(void *arg) -#else -DWORD WINAPI OnelabDatabase_listen(LPVOID arg) -#endif -{ - OnelabProtocol msg(-1); - UInt8 buff[1024]; - int recvlen = 0; - while(1) { - recvlen = OnelabDatabase::instance()->listen(buff, 1024); - if(recvlen == 1 && buff[0] == 'S') - break; - msg.parseMsg(buff, recvlen); - msg.showMsg(); - switch(msg.msgType()) { - case OnelabProtocol::OnelabStop: - return NULL; - case OnelabProtocol::OnelabMessage: - Msg::Info("Message from onelab"); // TODO - break; - case OnelabProtocol::OnelabResponse: - case OnelabProtocol::OnelabUpdate: - for(std::vector<OnelabAttr *>::iterator it = msg.attrs.begin() ; it != msg.attrs.end(); ++it) { - if((*it)->getAttributeType() == OnelabAttr::Number) { - onelab::number *attr = (onelab::number *)*it; - OnelabDatabase::instance()->set(*attr, false); - } - else if((*it)->getAttributeType() == OnelabAttr::String) { - onelab::string *attr = (onelab::string *)*it; - OnelabDatabase::instance()->set(*attr, false); - } - else if((*it)->getAttributeType() == OnelabAttr::Region) { - onelab::region *attr = (onelab::region *)*it; - OnelabDatabase::instance()->set(*attr, false); - } - else if((*it)->getAttributeType() == OnelabAttr::Function) { - onelab::function *attr = (onelab::function *)*it; - OnelabDatabase::instance()->set(*attr, false); - } - else if((*it)->getAttributeType() == OnelabAttrFileQuery::attributeType()) { - OnelabAttrFileQuery *attr = (OnelabAttrFileQuery *)*it; - const char *filename = attr->getFilename(); - // FIXME path/filename ? - std::clog << "try to open " << filename << " for reading" << std::endl; - FILE *fp = fopen(filename, "rb"); - if(fp != NULL){ - OnelabProtocol rep(OnelabProtocol::OnelabUpdate); - rep.attrs.push_back(new OnelabAttrFile(std::string(filename), fp)); - recvlen = rep.encodeMsg(buff, 1024); - OnelabDatabase::instance()->sendbytes(buff, recvlen); - while((recvlen = fread(buff, 1, 1024, fp)) > 0) - OnelabDatabase::instance()->sendbytes(buff, recvlen); - } - } - else if((*it)->getAttributeType() == OnelabAttrFile::attributeType()) { - OnelabAttrFile *attr = (OnelabAttrFile *)*it; - const char *filename = attr->getFilename(); - std::clog << "try to open " << filename << " for writing" << std::endl; - FILE *fp = fopen(filename, "wb"); - if(fp != NULL){ - unsigned int filesize = ((OnelabAttrFile *)attr)->getFileSize(); - unsigned int downloadsize = 0; - while(downloadsize < filesize) { - recvlen = OnelabDatabase::instance()->listen(buff, 1024); - downloadsize += recvlen; - fwrite(buff, 1, recvlen, fp); - } - } - } - else if((*it)->getAttributeType() == OnelabAttrAction::attributeType()) { - OnelabAttrAction *attr = (OnelabAttrAction *)*it; - OnelabLocalNetworkClient *target = OnelabServer::instance()->getClient(attr->getClient()); - target->sendto(buff, recvlen); - } - } - break; - } - } -} -#ifndef WIN32 -void *OnelabDatabase_server(void *arg) -#else -DWORD WINAPI OnelabDatabase_server(LPVOID arg) -#endif -{ - OnelabServer::instance()->Run(); -} diff --git a/contrib/onelab2/OnelabLocalClient.h b/contrib/onelab2/OnelabLocalClient.h index 5d0303ec5e1cc9d3545493ec86f55afee05dd6c1..fd82ccab9c45bca90766d2aa92142b9f496566c7 100644 --- a/contrib/onelab2/OnelabLocalClient.h +++ b/contrib/onelab2/OnelabLocalClient.h @@ -15,18 +15,18 @@ public: OnelabLocalClient(std::string name, onelab::parameterSpace *parameterSpace) : VirtualClient(name, parameterSpace){ } - template <class T> bool set(const T &p){ - return _parameterSpace->set(p, this->_name); - } - template <class T> bool get(std::vector<T> &ps, const std::string &name=""){ - return _parameterSpace->get(ps, name, this->_name); - } virtual ~OnelabLocalClient(){} - void onNewParameter(onelab::parameter *p){} - void onUpdateParameter(onelab::parameter *p){} - void onRemoveParameter(onelab::parameter *p){} + template <class T> bool set(const T &p){ + return _parameterSpace->set(p, this->_name); + } + template <class T> bool get(std::vector<T> &ps, const std::string &name){ + return _parameterSpace->get(ps, name, _name); + } + virtual void onNewParameter(onelab::parameter *p){} + virtual void onUpdateParameter(onelab::parameter *p){} + virtual void onRemoveParameter(onelab::parameter *p){} - void run() {} + virtual void run(std::string action) {} void stop() {} }; diff --git a/contrib/onelab2/OnelabLocalNetworkClient.cpp b/contrib/onelab2/OnelabLocalNetworkClient.cpp index 94060708b6503c04e57877a7a24681f64df2d650..69cdd39d76e2295f3b93ff4d44b5bdc9b34b0c34 100644 --- a/contrib/onelab2/OnelabLocalNetworkClient.cpp +++ b/contrib/onelab2/OnelabLocalNetworkClient.cpp @@ -48,9 +48,11 @@ int OnelabLocalNetworkClient::recvmsg(OnelabProtocol &msg) if(recvlen != 4) return recvlen; int msglen = msg.parseHeader(header, recvlen); // then recv the message + if(msglen == 0) return 4; buff = (UInt8 *) malloc(sizeof(UInt8)*msglen); recvlen = recvfrom(buff, msglen); // recvlen should be equals to msglen msg.parseMessage(buff, recvlen); + free(buff); return recvlen + 4; } void OnelabLocalNetworkClient::updateParameter(onelab::parameter *p) @@ -61,3 +63,11 @@ void OnelabLocalNetworkClient::updateParameter(onelab::parameter *p) unsigned int recvlen = msg.encodeMsg(buff, 1024); sendto(buff, recvlen); } +void OnelabLocalNetworkClient::run(std::string action) +{ + OnelabProtocol msg(OnelabProtocol::OnelabAction); + msg.attrs.push_back(new OnelabAttrAction(action, _name)); + UInt8 buff[1024]; + unsigned int size = msg.encodeMsg(buff, 1024); + sendto(buff, size); +} diff --git a/contrib/onelab2/OnelabLocalNetworkClient.h b/contrib/onelab2/OnelabLocalNetworkClient.h index ca21c6696019df168f1f9064d49e04b22380a8ee..17f94a471c7cebe5bc2bd6ff5fc93e253e804f23 100644 --- a/contrib/onelab2/OnelabLocalNetworkClient.h +++ b/contrib/onelab2/OnelabLocalNetworkClient.h @@ -35,7 +35,7 @@ public: unsigned int getIp() {return _ip.address;} unsigned short getPort() {return _ip.port;} - void run() {} - void stop() {} + void run(std::string action); + void stop() {} // TODO }; #endif diff --git a/contrib/onelab2/OnelabNetworkClient.cpp b/contrib/onelab2/OnelabNetworkClient.cpp index 6db37ee4c459b02ea3e3a5066d3b989999154ce4..5d1fcc5b0f0ee3bc51686332d3a61aa7002119ec 100644 --- a/contrib/onelab2/OnelabNetworkClient.cpp +++ b/contrib/onelab2/OnelabNetworkClient.cpp @@ -80,12 +80,22 @@ int OnelabNetworkClient::recvfrom(UInt8 *buff, UInt16 maxlen) return udt_socket_recv(_fdu, buff, maxlen); #endif } -void OnelabNetworkClient::recvfrom(OnelabProtocol &msg) +int OnelabNetworkClient::recvfrom(OnelabProtocol &msg) { - UInt16 bufflen = 1024, recvlen = 0; - UInt8 buff[1024]; - recvlen = this->recvfrom(buff, bufflen); - msg.parseMsg(buff, recvlen); + UInt8 header[8]; + UInt8 *buff = NULL; + int recvlen = 0; + // recv the header + recvlen = recvfrom(header, 4); + if(recvlen != 4) return recvlen; + int msglen = msg.parseHeader(header, recvlen); + // then recv the message + if(msglen == 0) return 4; + buff = (UInt8 *) malloc(sizeof(UInt8)*msglen); + recvlen = recvfrom(buff, msglen); // recvlen should be equals to msglen + msg.parseMessage(buff, recvlen); + free(buff); + return recvlen + 4; } bool OnelabNetworkClient::connect() { @@ -110,7 +120,7 @@ bool OnelabNetworkClient::connect() #ifdef HAVE_UDT udt_socket_timeout(_fdu, 3); #endif - //ip4_socket_timeout(_fds, 3); + ip4_socket_timeout(_fds, 3); recvlen = recvfrom(buff, bufflen); #ifdef HAVE_UDT diff --git a/contrib/onelab2/OnelabNetworkClient.h b/contrib/onelab2/OnelabNetworkClient.h index b4f602217e0af043718eda38f347e4ad7097cdcc..b627b40f50f8c0f16a2ff73684f1f31c50c0fb3a 100644 --- a/contrib/onelab2/OnelabNetworkClient.h +++ b/contrib/onelab2/OnelabNetworkClient.h @@ -2,11 +2,15 @@ #define _ONELABCLIENT_H_ #include <vector> +#include <unistd.h> -#include "NetworkUtils.h" #include "VirtualClient.h" -#include "OnelabLocalNetworkClient.h" #include "OnelabProtocol.h" +#ifdef HAVE_UDT +#include "UdtUtils.h" +#else +#include "NetworkUtils.h" +#endif class OnelabNetworkClient : VirtualClient { @@ -23,7 +27,16 @@ private: OnelabProtocol msg(OnelabProtocol::OnelabRequest); msg.attrs.push_back(new OnelabAttrParameterQuery(name.c_str(), T::attributeType())); this->request(msg); - return true; + // wait for the answer + fd_set readfds; + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(_fds, &readfds); + int nfds = select(_fds+1, &readfds, NULL, NULL, &timeout); + usleep(100000); // FIXME sleep while read the buffer + return nfds > 0; } void requestParameters(); // request all parameter for this client public: @@ -59,7 +72,10 @@ public: } template <class T> bool get(std::vector<T> &ps, const std::string &name=""){ if(_parameterSpace->get(ps, name, this->_name) && ps.size() == 0) - return requestParameter(ps, name); + if(requestParameter(ps, name)) + return _parameterSpace->get(ps, name, this->_name) && ps.size() == 0; + else + return false; return true; } FILE *openFile(const std::string name, const char *mode="rb") @@ -121,15 +137,14 @@ public: // network specific method bool connect(); bool isConnected(){return _connected;} - void recvfrom(OnelabProtocol &msg); + int recvfrom(OnelabProtocol &msg); int recvfrom(UInt8 *buff, UInt16 maxlen); void sendto(UInt8 *buff, UInt16 len); void disconnect(); void setRemoteIP(unsigned long ip){if(!_connected) _ip.address=ip;} void setRemotePort(unsigned short port){if(!_connected) _ip.port=port;} - void run() {} - void stop() {} + void run(std::string action) {} }; #endif diff --git a/contrib/onelab2/OnelabProtocol.cpp b/contrib/onelab2/OnelabProtocol.cpp index 416d1d1af9bae347bdc6e565d4825269db24979f..dd03b8e6b9580fce051e0bfc312cbb3db678de18 100644 --- a/contrib/onelab2/OnelabProtocol.cpp +++ b/contrib/onelab2/OnelabProtocol.cpp @@ -57,7 +57,7 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len) { UInt8 *ptr = buff; UInt8 *payload = ptr; - unsigned short parsed = 4; + unsigned short parsed = 4; // header size unsigned short size = _size; while(size >= 4) { UInt16 attrType = 0; @@ -96,6 +96,10 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len) this->attrs.push_back(new OnelabAttrParameterQuery()); ((OnelabAttrParameterQuery *)this->attrs.back())->parseAttribute(ptr, attrSize); break; + case 0x10: + this->attrs.push_back(new OnelabAttrAction()); + ((OnelabAttrAction *)this->attrs.back())->parseAttribute(ptr, attrSize); + break; case 0x0b: this->attrs.push_back(new OnelabAttrFileQuery()); ((OnelabAttrFileQuery *)this->attrs.back())->parseAttribute(ptr, attrSize); @@ -113,7 +117,7 @@ UInt32 OnelabProtocol::parseMessage(UInt8 *buff, UInt32 len) } ptr += attrSize; size -= attrSize; - parsed += attrSize+4; + parsed += (attrSize+4); } if(parsed != len) {std::cout << "parse - size left:" << len-parsed << '-' << size << "(len is "<< len <<" and parsed is "<< parsed <<" )" << std::endl;} @@ -172,6 +176,10 @@ UInt32 OnelabProtocol::parseMsg(UInt8 *buff, UInt32 len) this->attrs.push_back(new OnelabAttrParameterQuery()); ((OnelabAttrParameterQuery *)this->attrs.back())->parseAttribute(ptr, attrSize); break; + case 0x10: + this->attrs.push_back(new OnelabAttrAction()); + ((OnelabAttrAction *)this->attrs.back())->parseAttribute(ptr, attrSize); + break; case 0x0b: this->attrs.push_back(new OnelabAttrFileQuery()); ((OnelabAttrFileQuery *)this->attrs.back())->parseAttribute(ptr, attrSize); diff --git a/contrib/onelab2/OnelabProtocol.h b/contrib/onelab2/OnelabProtocol.h index 2179bfbe5ca1524c938a9b21380533a5c9d01f8f..1380da79b6df1ac8e4011de3c4842ab4aefcc78d 100644 --- a/contrib/onelab2/OnelabProtocol.h +++ b/contrib/onelab2/OnelabProtocol.h @@ -32,11 +32,12 @@ public: static const UInt8 BindResponseMsg = 0x02; static const UInt8 BindMessageMsg = 0x03; - static const UInt8 OnelabStart = 0x10; - static const UInt8 OnelabStop = 0x11; + static const UInt8 OnelabStart = 0x10; // Client send his name to the server (first message) + static const UInt8 OnelabStop = 0x11; // Client say to the server he is going to stop / the server ask a client to stop static const UInt8 OnelabMessage = 0x12; static const UInt8 OnelabRequest = 0x13; static const UInt8 OnelabResponse = 0x14; static const UInt8 OnelabUpdate = 0x15; + static const UInt8 OnelabAction = 0x16; }; #endif diff --git a/contrib/onelab2/OnelabServer.cpp b/contrib/onelab2/OnelabServer.cpp index 1c757b26da8696f387249dbec7a5ef845f56ddf0..2959173e024c6cfcea1d95836082af7d52de6b85 100644 --- a/contrib/onelab2/OnelabServer.cpp +++ b/contrib/onelab2/OnelabServer.cpp @@ -7,11 +7,19 @@ #include <wspiapi.h> #endif +#include "NetworkUtils.h" #include "OnelabServer.h" #include "OnelabProtocol.h" #include "OnelabAttributes.h" #include "onelab.h" -#include "NetworkUtils.h" +#include "onelabUtils.h" + +// FIXME no Gmsh specific header (used in launchClient) +#include "StringUtils.h" +#include "GmshMessage.h" +#include "OS.h" +#include "GModel.h" +#include "Options.h" static bool haveToStop = false; @@ -62,6 +70,56 @@ OnelabLocalNetworkClient *OnelabServer::getClient(UDTSOCKET fd) // UDTSOCKET Soc } #endif +int OnelabServer::launchClient(const std::string &client) // 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") { + command.assign(Msg::GetExecutableName()); + } + else { + int num = 0; + while(num < 10/*NUM_SOLVERS*/){ + if(opt_solver_name(num, GMSH_GET, "") == client) break; + num++; + } + if(num >= 10/*NUM_SOLVERS*/) { + std::cout << "Unable to find " << client << std::endl; + return -1; + } + + //std::string name = opt_solver_name(num, GMSH_GET, ""); + std::string exe = opt_solver_executable(num, GMSH_GET, ""); + command.assign(exe); + } + //std::string command = FixWindowsPath(_client->getExecutable()); // TODO + + if(command.size()){ + std::vector<std::string> args = onelabUtils::getCommandLine(client); + for(unsigned int i = 0; i < args.size(); i++) + command.append(" " + args[i]); + } + command.append(" -onelab" + " \"" + client + "\" %s"); + + char cmd[1024]; + // UNIX socket + //TODO sprintf(cmd, command, _sockname.c_str()); + + // TCP socket + if(client == "Gmsh") sprintf(cmd, command.c_str(), "-server %s:%d"); + else sprintf(cmd, command.c_str(), " %s:%d"); + command.assign(cmd); + 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); + + return 0; +} + //void OnelabServer::addClient(std::string name, Socket fd, UInt32 ip, UInt16 port) //{ // if(ip == 0 || port == 0) throw "Unable to add client (invalid ip or port)"; @@ -100,6 +158,15 @@ OnelabLocalNetworkClient *OnelabServer::getClient(std::string name) } return NULL; } +OnelabLocalClient *OnelabServer::getLocalClient(std::string name) +{ + for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin(); it != _localClients.end(); ++it) { + if((*it)->getName() == name) + return (*it); + } + return NULL; + +} void OnelabServer::removeClient(OnelabLocalNetworkClient *client) { @@ -111,6 +178,57 @@ void OnelabServer::removeClient(OnelabLocalNetworkClient *client) } } +void OnelabServer::performAction(const std::string action, const std::string client) +{ + if(client.size()) { + OnelabLocalNetworkClient *cli = getClient(client); + OnelabLocalClient *localcli = getLocalClient(client); + if(cli != NULL || localcli == NULL) { + onelab::string o(client + "/Action", action); + o.setVisible(false); + o.setNeverChanged(true); + set(o); + } + if(cli != NULL){ // Gmsh is used as a server and the client is remote + std::cout << action << " on " << client << "(client is remote)" << std::endl; + cli->run(action); + } + else if(localcli != NULL){ // client is local (in the same memory space than this server) + std::cout << action << " on " << client << "(client is local)" << std::endl; + localcli->run(action); + } + else { // client is Gmsh but do not exist (Gmsh is used as a server), launch Gmsh + std::cout << action << " on " << client << "(launch a new remote Gmsh)" << std::endl; + if(launchClient(client) >= 0) + ;// FIXME then action or action is store in onelab DB ? + else + ;// TODO save action and wait for the cli ? + } + } + else { + // run all non Gmsh clients TODO, exclude GUI ? + for(std::vector<OnelabLocalNetworkClient>::iterator it = _clients.begin(); it != _clients.end(); ++it) { + if((*it).getName() == "Gmsh") continue; + std::cout << action << " on " << (*it).getName() << "(remote)" << std::endl; + onelab::string o((*it).getName() + "/Action", action); + o.setVisible(false); + o.setNeverChanged(true); + set(o); + (*it).run(action); + } + + for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin(); it != _localClients.end(); ++it) { + if((*it)->getName() == "Gmsh") continue; + onelab::string o((*it)->getName() + "/Action", action); + o.setVisible(false); + o.setNeverChanged(true); + set(o); + std::cout << action << " on " << (*it)->getName() << "(local)" << std::endl; + (*it)->run(action); + } + } +} + #ifdef HAVE_UDT #ifndef WIN32 void *listenOnClients(void *param) @@ -122,22 +240,40 @@ void *listenOnClients(void *param) std::set<UDTSOCKET> fdus; std::set<Socket> fdss; int recvlen = 0; - UInt8 prev[1024]; UInt8 buff[1024]; OnelabProtocol msg(-1), rep(-1); int eid = OnelabServer::instance()->getEID(); while(UDT::ERROR != UDT::epoll_wait(eid, &fdus, NULL, -1, &fdss, NULL)) { - //for(std::set<UDTSOCKET>::iterator it = fdus.begin(); it != fdus.end(); ++it) { + /*for(std::set<UDTSOCKET>::iterator it = fdus.begin(); it != fdus.end(); ++it) { + OnelabLocalNetworkClient *cli = OnelabServer::instance()->getClient(*it); + if(cli == NULL) { // Client is not in the list (it muste be a Start message) + IPv4 ip; + recvlen = udt_socket_recv(*it, buff, 1024); + }TODO*/ for(std::set<Socket>::iterator it = fdss.begin(); it != fdss.end(); ++it) { OnelabLocalNetworkClient *cli = OnelabServer::instance()->getClient(*it); - if(cli == NULL) { + if(cli == NULL) { // Client is not in the list (it muste be a Start message) IPv4 ip; - //recvlen = udt_socket_recv(*it, buff, 1024); - recvlen = ip4_socket_recv(*it, buff, 1024, ip); // FIXME - std::clog << "recv " << recvlen << std::endl; - msg.parseMsg(buff, recvlen); + // recv the header + recvlen = ip4_socket_recv(*it, buff, 4, ip); + if(recvlen != 4) { + // invalid message header + UDT::epoll_remove_ssock(eid, *it); + UDT::close(*it); + continue; + } + int msglen = msg.parseHeader(buff, recvlen); + if(msglen > 1024) { + // FIXME? buffer is too small + UDT::epoll_remove_ssock(eid, *it); + UDT::close(*it); + continue; + } + // then recv the message + recvlen = ip4_socket_recv(*it, buff, msglen, ip); + msg.parseMessage(buff, recvlen); msg.showMsg(); if(msg.msgType() == OnelabProtocol::OnelabStart && msg.attrs.size() > 0 && msg.attrs[0]->getAttributeType() == OnelabAttr::Start) { std::string name = std::string(((OnelabAttrStart *)msg.attrs[0])->name()); @@ -153,6 +289,7 @@ void *listenOnClients(void *param) UDT::close(*it); continue; } + // Add a new remote client OnelabServer::instance()->addClient(name, *it, ip.address, ip.port); std::clog << "\033[0;31m" << "Add a new client: " << name << "\033[0m" << std::endl; OnelabProtocol rep(OnelabProtocol::OnelabStart); @@ -171,7 +308,6 @@ void *listenOnClients(void *param) } } else { - std::cout << "ok" << std::endl; try { recvlen = cli->recvmsg(msg); } @@ -189,6 +325,7 @@ void *listenOnClients(void *param) OnelabServer::instance()->removeClient(cli); UDT::close(*it); }*/ + std::cerr << "Error while recv message." << std::endl; continue; } if(recvlen == 0) { // for TCP @@ -199,7 +336,6 @@ void *listenOnClients(void *param) continue; } std::clog << "recv " << recvlen << " bytes on client " << cli->getName() << std::endl; - //unreaded = msg.parseMsg(buff, recvlen); switch (msg.msgType()) { case OnelabProtocol::OnelabStop: std::cout << "\033[0;31m" << "Client \"" << cli->getName() << "\" is going to stop" << "\033[0m" << std::endl; // DEBUG @@ -212,6 +348,7 @@ void *listenOnClients(void *param) UDT::close(*it); break; case OnelabProtocol::OnelabMessage: + std::cout << "recv a message ... (TODO)" << std::endl; // TODO break; case OnelabProtocol::OnelabRequest: @@ -319,6 +456,25 @@ void *listenOnClients(void *param) } } 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; } } } @@ -372,12 +528,6 @@ void OnelabServer::Run() pthread_create(&listen_thread, NULL, listenOnClients, NULL); #else listen_thread = CreateThread(NULL, 0, listenOnClients, NULL, 0, NULL); -#endif - if(_clients.size() == 1) -#ifndef WIN32 - pthread_join(listen_thread, NULL); -#else - WaitForSingleObject(listen_thread, INFINITE); #endif } udt_socket_close(_fdu); diff --git a/contrib/onelab2/OnelabServer.h b/contrib/onelab2/OnelabServer.h index 81b773b9445b3b5749a0bfb7a26a15e72038cb50..1db3bbae54c3f61a887827163319f50c24e4fd4b 100644 --- a/contrib/onelab2/OnelabServer.h +++ b/contrib/onelab2/OnelabServer.h @@ -39,6 +39,7 @@ public: } static void setInstance(OnelabServer *s) { _server = s; } onelab::parameterSpace *getParameterSpace() {return &_parameterSpace;} + UInt16 getPort() { return _ip.port;} #ifdef HAVE_UDT ~OnelabServer(){UDT::cleanup();} #else @@ -54,11 +55,13 @@ public: void addClient(std::string name, UInt32 ip, UInt16 port); #endif void addClient(OnelabLocalClient *cli) {_localClients.push_back(cli);} + int launchClient(const std::string &); void removeClient(OnelabLocalNetworkClient *client); std::vector<OnelabLocalNetworkClient> &getClients() {return _clients;} std::vector<OnelabLocalClient *> &getLocalClients() {return _localClients;} OnelabLocalNetworkClient *getClient(UInt32 ip, UInt16 port); OnelabLocalNetworkClient *getClient(std::string name); + OnelabLocalClient *getLocalClient(std::string name); void sendAllParameter(OnelabLocalNetworkClient *cli); // Parameters methods void clear(const std::string &name="", const std::string &client="") { @@ -74,10 +77,14 @@ public: _parameterSpace.set(p, client); T *pp; _parameterSpace.getPtr(&pp, p.getName()); - for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin() ; it != _localClients.end(); ++it) - if((*it)->getName() != client) + if(pp->getVisible()) pp->addClient("GUI", true); + for(std::vector<OnelabLocalClient *>::iterator it = _localClients.begin() ; it != _localClients.end(); ++it) { + std::cout << (*it)->getName() << " and is " << ((isNew)?"new ":"updated ") << " from " << client << std::endl; + if((*it)->getName() != client) { if(isNew)(*it)->onNewParameter(pp); else (*it)->onUpdateParameter(pp); + } + } std::map<std::string, bool> clients = p.getClients(); for(std::map<std::string, bool>::const_iterator it = clients.begin(); it != clients.end(); it++) { std::cout << "send " << p.getName() << " to " << it->first << " from " << client << std::endl; @@ -86,6 +93,7 @@ public: if(tmp == NULL) continue; tmp->updateParameter(pp); } + return true; } template <class T> bool get(std::vector<T> &ps, const std::string &name="", const std::string &client="") { return _parameterSpace.get(ps, name, client); @@ -122,5 +130,14 @@ public: if(onelab::parameter::fromFile(msg, fp)) return fromChar(msg, client); return false; } + bool getChanged(const std::string &client="") const { + return _parameterSpace.getChanged(client); + } + void setChanged(bool changed, const std::string &client="") { + _parameterSpace.setChanged(changed, client); + std::cout << "set " << client << ((changed)?" changed ":" unchanged ") << std::endl + << "get " << getChanged(client) << std::endl; + } + void performAction(const std::string action, const std::string client=""); }; #endif diff --git a/contrib/onelab2/VirtualClient.h b/contrib/onelab2/VirtualClient.h index 01c28bd48bd5a926b89e2db2bd7c5625b2401c83..a664d44d8a1c2b4e2aef018dd0bdc885df9ac409 100644 --- a/contrib/onelab2/VirtualClient.h +++ b/contrib/onelab2/VirtualClient.h @@ -38,8 +38,7 @@ public: virtual void onUpdateParameter(onelab::parameter *) = 0; virtual void onRemoveParameter(onelab::parameter *) = 0; - virtual void run() = 0; - virtual void stop() = 0; + virtual void run(std::string action) = 0; }; #endif