示例#1
0
  // redefinition of virtual onelab_client::sendMergeFileRequest
  void sendMergeFileRequest(const std::string &name)
  {
    if(name.find(".geo") != std::string::npos){
      MergePostProcessingFile(name, CTX::instance()->solver.autoShowLastStep,
			      CTX::instance()->solver.autoHideNewViews, true);
      GModel::current()->setFileName(name);
    }
    else if((name.find(".opt") != std::string::npos)){
      MergeFile(name);
    }
    else if((name.find(".macro") != std::string::npos)){
      MergeFile(name);
    }
    else
      MergePostProcessingFile(name, CTX::instance()->solver.autoShowLastStep,
			      CTX::instance()->solver.autoHideNewViews, true);
  }
bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
{
  // receive a message on the associated GmshServer; 'master' is only used when
  // creating subclients with GMSH_CONNECT.

  double timer = GetTimeInSeconds();

  if(!getGmshServer()){
    Msg::Error("Abnormal server termination (no valid server)");
    return false;
  }

  int type, length, swap;
  if(!getGmshServer()->ReceiveHeader(&type, &length, &swap)){
    Msg::Error("Abnormal server termination (did not receive message header)");
    return false;
  }

  std::string message(length, ' '), blank = message;
  if(!getGmshServer()->ReceiveMessage(length, &message[0])){
    Msg::Error("Abnormal server termination (did not receive message body)");
    return false;
  }

  if(message == blank && !(type == GmshSocket::GMSH_PROGRESS ||
                           type == GmshSocket::GMSH_INFO ||
                           type == GmshSocket::GMSH_WARNING ||
                           type == GmshSocket::GMSH_ERROR)){
    // we should still allow blank msg strings to be sent
    Msg::Error("Abnormal server termination (blank message: client not stopped?)");
    return false;
  }

  switch (type) {
  case GmshSocket::GMSH_START:
    setPid(atoi(message.c_str()));
    break;
  case GmshSocket::GMSH_STOP:
    setPid(-1);
    if(getFather()){
      std::string reply = getName(); // reply is dummy
      getFather()->getGmshServer()->SendMessage
        (GmshSocket::GMSH_STOP, reply.size(), &reply[0]);
    }
    break;
  case GmshSocket::GMSH_PARAMETER:
  case GmshSocket::GMSH_PARAMETER_UPDATE:
    {
      std::string version, ptype, name;
      onelab::parameter::getInfoFromChar(message, version, ptype, name);
      if(onelab::parameter::version() != version){
        Msg::Error("ONELAB version mismatch (server: %s / client: %s)",
                   onelab::parameter::version().c_str(), version.c_str());
      }
      else if(ptype == "number"){
        onelab::number p; p.fromChar(message);
        if(type == GmshSocket::GMSH_PARAMETER_UPDATE){
          std::vector<onelab::number> par; get(par, name);
          if(par.size()) {
            onelab::number y = p; p = par[0]; onelabUtils::updateNumber(p, y);
          }
        }
        set(p);
        if(p.getName() == getName() + "/Progress"){
#if defined(HAVE_FLTK)
          if(FlGui::available())
            FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
                                           p.getMin(), p.getMax());
#endif
        }
      }
      else if(ptype == "string"){
        onelab::string p; p.fromChar(message);
        if(type == GmshSocket::GMSH_PARAMETER_UPDATE){
          std::vector<onelab::string> par; get(par, name);
          if(par.size()){
            onelab::string y = p; p = par[0]; onelabUtils::updateString(p,y);
          }
	}
        set(p);
      }
      else if(ptype == "region"){
        onelab::region p; p.fromChar(message); set(p);
      }
      else if(ptype == "function"){
        onelab::function p; p.fromChar(message); set(p);
      }
      else
        Msg::Error("Unknown ONELAB parameter type: %s", ptype.c_str());
    }
    break;
  case GmshSocket::GMSH_PARAMETER_QUERY:
    {
      std::string version, ptype, name, reply;
      onelab::parameter::getInfoFromChar(message, version, ptype, name);
      if(onelab::parameter::version() != version){
        Msg::Error("ONELAB version mismatch (server: %s / client: %s)",
                   onelab::parameter::version().c_str(), version.c_str());
      }
      else if(ptype == "number"){
        std::vector<onelab::number> par; get(par, name);
        if(par.size() == 1) reply = par[0].toChar();
      }
      else if(ptype == "string"){
        std::vector<onelab::string> par; get(par, name);
        if(par.size() == 1) reply = par[0].toChar();
      }
      else if(ptype == "region"){
        std::vector<onelab::region> par; get(par, name);
        if(par.size() == 1) reply = par[0].toChar();
      }
      else if(ptype == "function"){
        std::vector<onelab::function> par; get(par, name);
        if(par.size() == 1) reply = par[0].toChar();
      }
      else
        Msg::Error("Unknown ONELAB parameter type in query: %s", ptype.c_str());

      if(reply.size()){
        getGmshServer()->SendMessage
          (GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
      }
      else{
        reply = name;
        getGmshServer()->SendMessage
          (GmshSocket::GMSH_PARAMETER_NOT_FOUND, reply.size(), &reply[0]);
      }
    }
    break;
  case GmshSocket::GMSH_PARAMETER_QUERY_ALL:
    {
      std::string version, ptype, name, reply;
      std::vector<std::string> replies;
      onelab::parameter::getInfoFromChar(message, version, ptype, name);
      if(onelab::parameter::version() != version){
        Msg::Error("ONELAB version mismatch (server: %s / client: %s)",
                   onelab::parameter::version().c_str(), version.c_str());
      }
      else if(ptype == "number"){
        std::vector<onelab::number> numbers; get(numbers);
        for(std::vector<onelab::number>::iterator it = numbers.begin();
            it != numbers.end(); it++) replies.push_back((*it).toChar());
      }
      else if(ptype == "string"){
        std::vector<onelab::string> strings; get(strings);
        for(std::vector<onelab::string>::iterator it = strings.begin();
            it != strings.end(); it++) replies.push_back((*it).toChar());
      }
      else if(ptype == "region"){
        std::vector<onelab::region> regions; get(regions);
        for(std::vector<onelab::region>::iterator it = regions.begin();
            it != regions.end(); it++) replies.push_back((*it).toChar());
      }
      else if(ptype == "function"){
        std::vector<onelab::function> functions; get(functions);
        for(std::vector<onelab::function>::iterator it = functions.begin();
            it != functions.end(); it++) replies.push_back((*it).toChar());
      }
      else
        Msg::Error("Unknown ONELAB parameter type in query: %s", ptype.c_str());

      for(unsigned int i = 0; i < replies.size(); i++)
        getGmshServer()->SendMessage
          (GmshSocket::GMSH_PARAMETER_QUERY_ALL, replies[i].size(), &replies[i][0]);
      reply = "Sent all ONELAB " + ptype + "s";
      getGmshServer()->SendMessage
        (GmshSocket::GMSH_PARAMETER_QUERY_END, reply.size(), &reply[0]);
    }
    break;
  case GmshSocket::GMSH_PARAMETER_CLEAR:
    clear(message == "*" ? "" : message);
    break;
  case GmshSocket::GMSH_PROGRESS:
    Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str());
    break;
  case GmshSocket::GMSH_INFO:
    Msg::Direct("Info    : %s - %s", _name.c_str(), message.c_str());
    break;
  case GmshSocket::GMSH_WARNING:
    Msg::Warning("%s - %s", _name.c_str(), message.c_str());
    break;
  case GmshSocket::GMSH_ERROR:
    Msg::Error("%s - %s", _name.c_str(), message.c_str());
    break;
  case GmshSocket::GMSH_MERGE_FILE:
    if(CTX::instance()->solver.autoMergeFile){
      unsigned int n = PView::list.size();
      MergePostProcessingFile(message, CTX::instance()->solver.autoShowViews,
                              CTX::instance()->solver.autoShowLastStep, true);
#if defined(HAVE_FLTK)
      drawContext::global()->draw();
      if(FlGui::available() && n != PView::list.size()){
        FlGui::instance()->rebuildTree(true);
        FlGui::instance()->openModule("Post-processing");
      }
#endif
    }
    break;
  case GmshSocket::GMSH_OPEN_PROJECT:
    OpenProject(message);
#if defined(HAVE_FLTK)
    drawContext::global()->draw();
#endif
    break;
  case GmshSocket::GMSH_PARSE_STRING:
    ParseString(message, true);
#if defined(HAVE_FLTK)
    drawContext::global()->draw();
#endif
    break;
  case GmshSocket::GMSH_SPEED_TEST:
    Msg::Info("got %d Mb message in %g seconds",
              length / 1024 / 1024, GetTimeInSeconds() - timer);
    break;
  case GmshSocket::GMSH_VERTEX_ARRAY:
    {
      int n = PView::list.size();
      PView::fillVertexArray(this, length, &message[0], swap);
#if defined(HAVE_FLTK)
      if(FlGui::available())
        FlGui::instance()->updateViews(n != (int)PView::list.size(), true);
      drawContext::global()->draw();
#endif
    }
    break;
  case GmshSocket::GMSH_CONNECT:
    {
      std::string::size_type first = 0;
      std::string clientName = onelab::parameter::getNextToken(message, first);
      std::string command = onelab::parameter::getNextToken(message, first);
      gmshLocalNetworkClient* subClient =
        new gmshLocalNetworkClient(clientName, command, "", true);
      onelabGmshServer *server = new onelabGmshServer(subClient);
      subClient->setPid(0);
      onelab::string o(subClient->getName() + "/Action", "compute");
      o.setVisible(false);
      o.setNeverChanged(true);
      onelab::server::instance()->set(o);
      int sock = server->LaunchClient();
      if(sock < 0){ // could not establish the connection: aborting
        server->Shutdown();
        delete server;
        Msg::Error("Could not connect client '%s'", subClient->getName().c_str());
      }
      else{
        Msg::StatusBar(true, "Running '%s'...", subClient->getName().c_str());
        subClient->setGmshServer(server);
        subClient->setFather(this);
        master->addClient(subClient);
      }
    }
    break;
  case GmshSocket::GMSH_OLPARSE:
    {
      std::string reply = "unavailable";
#if defined(HAVE_ONELAB_METAMODEL)
      std::string::size_type first = 0;
      std::string clientName = onelab::parameter::getNextToken(message, first);
      std::string fullName = onelab::parameter::getNextToken(message, first);
      preProcess(clientName, fullName); // contrib/onelab/OnelabParser.cpp
      Msg::Info("Done preprocessing file '%s'", fullName.c_str());
      reply = onelab::server::instance()->getChanged(clientName) ? "true" : "false";
#endif
      getGmshServer()->SendMessage
	(GmshSocket::GMSH_OLPARSE, reply.size(), &reply[0]);
    }
    break;
  case GmshSocket::GMSH_CLIENT_CHANGED:
    {
      std::string::size_type first = 0;
      std::string command = onelab::parameter::getNextToken(message, first);
      std::string name = onelab::parameter::getNextToken(message, first);
      if(command == "get"){
	std::string reply = onelab::server::instance()->getChanged(name) ? "true" : "false";
	getGmshServer()->SendMessage
	  (GmshSocket::GMSH_CLIENT_CHANGED, reply.size(), &reply[0]);
      }
      else if(command == "set"){
	std::string changed = onelab::parameter::getNextToken(message, first);
	onelab::server::instance()->setChanged(changed=="true"?true:false,name);
      }
    }
    break;
  default:
    Msg::Warning("Received unknown message type (%d)", type);
    break;
  }

  return true;
}