Changeset 90:88b6f38d610a in finroc_plugins_runtime_construction


Ignore:
Timestamp:
07.04.2017 04:18:30 (4 years ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Rebase:
63313064303165373336633339393964306230643033616163343236323134643833653433363232
Message:

Adds support for type conversion and other connector options in finstructable groups and administration service. CreateFrameworkElementAction register is now based on register mechanism from rrlib_serialization.

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • dynamic_loading.cpp

    r88 r90  
    375375 
    376376  // try to find component type among loaded ones 
    377   const std::vector<tCreateFrameworkElementAction*>& modules = tCreateFrameworkElementAction::GetConstructibleElements(); 
    378   for (size_t i = 0u; i < modules.size(); i++) 
     377  auto& modules = tCreateFrameworkElementAction::GetConstructibleElements(); 
     378  for (size_t i = 0, n = modules.Size(); i < n; i++) 
    379379  { 
    380380    tCreateFrameworkElementAction* cma = modules[i]; 
  • tAdministrationService.cpp

    r89 r90  
    3333// External includes (system with <>, local with "") 
    3434//---------------------------------------------------------------------- 
     35#include "rrlib/rtti_conversion/tStaticCastOperation.h" 
    3536#include "core/tRuntimeEnvironment.h" 
    3637#include "core/tRuntimeSettings.h" 
     
    8081    &tAdministrationService::LoadModuleLibrary, &tAdministrationService::PauseExecution, &tAdministrationService::SaveAllFinstructableFiles, 
    8182    &tAdministrationService::SaveFinstructableGroup, &tAdministrationService::SetAnnotation, &tAdministrationService::SetPortValue, 
    82     &tAdministrationService::StartExecution, &tAdministrationService::NetworkConnect, &tAdministrationService::ConnectPorts); // NetworkConnect etc. are last in order to not break binary compatibility 
     83    &tAdministrationService::StartExecution, &tAdministrationService::NetworkConnect, &tAdministrationService::ConnectPorts,  // NetworkConnect etc. are last in order to not break binary compatibility 
     84    &tAdministrationService::CreateUriConnector, &tAdministrationService::DeleteUriConnector); 
    8385 
    8486static tAdministrationService administration_service; 
     87 
     88/*! Serialization info for memory buffers in some commands */ 
     89static const rrlib::serialization::tSerializationInfo cBASIC_UID_SERIALIZATION_INFO(0, rrlib::serialization::tRegisterEntryEncoding::UID, 0); 
    8590 
    8691//---------------------------------------------------------------------- 
     
    130135std::string tAdministrationService::ConnectPorts(int source_port_handle, int destination_port_handle, const core::tConnectOptions& connect_options) 
    131136{ 
    132   std::string result; 
     137  std::stringstream result; 
    133138  auto cVOLATILE = core::tFrameworkElement::tFlag::VOLATILE; 
    134139  core::tAbstractPort* source_port = Runtime().GetPort(source_port_handle); 
     
    137142  if ((!source_port) || (!destination_port)) 
    138143  { 
    139     result = "At least one port to be connected does not exist"; 
     144    const char* result = "At least one port to be connected does not exist"; 
    140145    FINROC_LOG_PRINT(WARNING, result); 
    141146    return result; 
     
    143148  if (source_port->GetFlag(cVOLATILE) && destination_port->GetFlag(cVOLATILE)) 
    144149  { 
    145     FINROC_LOG_PRINT(WARNING, "Cannot really persistently connect two network ports: ", source_port->GetQualifiedLink(), ", ", destination_port->GetQualifiedLink()); 
     150    FINROC_LOG_PRINT(WARNING, "Cannot really persistently connect two network ports: ", source_port, ", ", destination_port); 
    146151  } 
    147152 
     
    152157    { 
    153158      options.flags |= core::tConnectionFlag::RECONNECT; 
    154       destination_port->ConnectTo(source_port->GetQualifiedLink(), options); 
     159      destination_port->ConnectTo(source_port->GetPath(), options); 
    155160    } 
    156161    else if (destination_port->GetFlag(cVOLATILE) && (!source_port->GetFlag(cVOLATILE))) 
    157162    { 
    158163      options.flags |= core::tConnectionFlag::RECONNECT; 
    159       source_port->ConnectTo(destination_port->GetQualifiedLink(), options); 
     164      source_port->ConnectTo(destination_port->GetPath(), options); 
    160165    } 
    161166    else 
     
    166171  catch (const std::exception& e) 
    167172  { 
    168     result = "Could not connect ports '" + source_port->GetQualifiedName() + "' and '" + destination_port->GetQualifiedName() + "'. Reason: " + e.what(); 
    169     FINROC_LOG_PRINT(WARNING, result); 
    170     return result; 
     173    result << "Could not connect ports '" << source_port << "' and '" << destination_port << "'. Reason: " << e.what(); 
     174    FINROC_LOG_PRINT(WARNING, result.str()); 
     175    return result.str(); 
    171176  } 
    172177 
     
    174179  if (!source_port->IsConnectedTo(*destination_port)) 
    175180  { 
    176     result = "Could not connect ports '" + source_port->GetQualifiedName() + "' and '" + destination_port->GetQualifiedName() + "' (see output of connected Finroc program for details)."; 
    177     FINROC_LOG_PRINT(WARNING, result); 
    178   } 
    179   else 
    180   { 
    181     FINROC_LOG_PRINT(USER, "Connected ports ", source_port->GetQualifiedName(), " ", destination_port->GetQualifiedName()); 
    182   } 
    183   return result; 
     181    result << "Could not connect ports '" << source_port << "' and '" << destination_port << "' (see output of connected Finroc program for details)."; 
     182    FINROC_LOG_PRINT(WARNING, result.str()); 
     183  } 
     184  else 
     185  { 
     186    FINROC_LOG_PRINT(USER, "Connected ports ", source_port, " ", destination_port); 
     187  } 
     188  return result.str(); 
    184189} 
    185190 
     
    197202  { 
    198203    rrlib::thread::tLock lock(Runtime().GetStructureMutex()); 
    199     const std::vector<tCreateFrameworkElementAction*>& create_actions = tCreateFrameworkElementAction::GetConstructibleElements(); 
    200     if (create_action_index >= create_actions.size()) 
     204    auto& create_actions = tCreateFrameworkElementAction::GetConstructibleElements(); 
     205    if (create_action_index >= create_actions.Size()) 
    201206    { 
    202207      error_message = "Invalid construction action index"; 
     
    210215        error_message = "Parent not available. Cancelling remote module creation."; 
    211216      } 
    212       else if ((!core::tRuntimeSettings::DuplicateQualifiedNamesAllowed()) && parent->GetChild(module_name)) 
     217      else if (parent->GetChild(module_name)) 
    213218      { 
    214219        error_message = std::string("Element with name '") + module_name + "' already exists. Creating another module with this name is not allowed."; 
     
    216221      else 
    217222      { 
    218         FINROC_LOG_PRINT(USER, "Creating Module ", parent->GetQualifiedLink(), "/", module_name); 
     223        FINROC_LOG_PRINT(USER, "Creating Module ", parent, "/", module_name); 
    219224        std::unique_ptr<tConstructorParameters> parameters; 
    220225        if (create_action->GetParameterTypes() && create_action->GetParameterTypes()->Size() > 0) 
    221226        { 
    222227          parameters.reset(create_action->GetParameterTypes()->Instantiate()); 
    223           rrlib::serialization::tInputStream input_stream(serialized_creation_parameters, rrlib::serialization::tTypeEncoding::NAMES); 
     228          rrlib::serialization::tInputStream input_stream(serialized_creation_parameters, cBASIC_UID_SERIALIZATION_INFO); 
    224229          for (size_t i = 0; i < parameters->Size(); i++) 
    225230          { 
     
    259264} 
    260265 
     266std::string tAdministrationService::CreateUriConnector(int local_port_handle, const rrlib::uri::tURI& uri, const core::tUriConnectOptions& connect_options) 
     267{ 
     268  core::tAbstractPort* port = core::tRuntimeEnvironment::GetInstance().GetPort(local_port_handle); 
     269  std::stringstream result; 
     270  if (port && port->IsReady()) 
     271  { 
     272    try 
     273    { 
     274      core::tUriConnector::Create(*port, uri, connect_options); 
     275      return ""; 
     276    } 
     277    catch (const std::exception& e) 
     278    { 
     279      result << "Creating URI connector failed: " << e.what(); 
     280    } 
     281  } 
     282  else 
     283  { 
     284    result << "No port with local handle " << local_port_handle << " found"; 
     285  } 
     286  FINROC_LOG_PRINT(WARNING, result.str()); 
     287  return result.str(); 
     288} 
     289 
    261290void tAdministrationService::DeleteElement(int element_handle) 
    262291{ 
     
    264293  if (element && (!element->IsDeleted())) 
    265294  { 
    266     FINROC_LOG_PRINT(USER, "Deleting element ", element->GetQualifiedLink()); 
     295    FINROC_LOG_PRINT(USER, "Deleting element ", element); 
    267296    element->ManagedDelete(); 
    268297  } 
     
    271300    FINROC_LOG_PRINT(ERROR, "Could not delete Framework element, because it does not appear to be available."); 
    272301  } 
     302} 
     303 
     304bool tAdministrationService::DeleteUriConnector(int local_port_handle, const rrlib::uri::tURI& uri) 
     305{ 
     306  core::tAbstractPort* port = core::tRuntimeEnvironment::GetInstance().GetPort(local_port_handle); 
     307  std::stringstream result; 
     308  if (port && port->IsReady()) 
     309  { 
     310    for (auto & connector : port->UriConnectors()) 
     311    { 
     312      if (connector->Uri() == uri) 
     313      { 
     314        connector->Disconnect(); 
     315        return true; 
     316      } 
     317    } 
     318    result << "No connector with URI " << uri.ToString() << " found"; 
     319  } 
     320  else 
     321  { 
     322    result << "No port with local handle " << local_port_handle << " found"; 
     323  } 
     324  FINROC_LOG_PRINT(WARNING, result.str()); 
     325  return false; 
    273326} 
    274327 
     
    285338  if (source_port->GetFlag(cVOLATILE)) 
    286339  { 
    287     destination_port->DisconnectFrom(source_port->GetQualifiedLink()); 
     340    destination_port->DisconnectFrom(source_port->GetPath()); 
    288341  } 
    289342  if (destination_port->GetFlag(cVOLATILE)) 
    290343  { 
    291     source_port->DisconnectFrom(destination_port->GetQualifiedLink()); 
     344    source_port->DisconnectFrom(destination_port->GetPath()); 
    292345  } 
    293346  source_port->DisconnectFrom(*destination_port); 
    294347  if (source_port->IsConnectedTo(*destination_port)) 
    295348  { 
    296     FINROC_LOG_PRINT(WARNING, "Could not disconnect ports ", source_port->GetQualifiedName(), " ", destination_port->GetQualifiedName()); 
    297   } 
    298   else 
    299   { 
    300     FINROC_LOG_PRINT(USER, "Disconnected ports ", source_port->GetQualifiedName(), " ", destination_port->GetQualifiedName()); 
     349    FINROC_LOG_PRINT(WARNING, "Could not disconnect ports ", source_port, " ", destination_port); 
     350  } 
     351  else 
     352  { 
     353    FINROC_LOG_PRINT(USER, "Disconnected ports ", source_port, " ", destination_port); 
    301354  } 
    302355} 
     
    311364  } 
    312365  port->DisconnectAll(); 
    313   FINROC_LOG_PRINT(USER, "Disconnected port ", port->GetQualifiedName()); 
     366  FINROC_LOG_PRINT(USER, "Disconnected port ", port); 
    314367} 
    315368 
     
    324377    { 
    325378      rrlib::serialization::tMemoryBuffer result_buffer; 
    326       rrlib::serialization::tOutputStream output_stream(result_buffer, rrlib::serialization::tTypeEncoding::NAMES); 
     379      rrlib::serialization::tOutputStream output_stream(result_buffer, cBASIC_UID_SERIALIZATION_INFO); 
    327380      rrlib::rtti::tTypedConstPointer annotation_pointer(result, type); 
    328381      annotation_pointer.Serialize(output_stream); 
     
    340393rrlib::serialization::tMemoryBuffer tAdministrationService::GetCreateModuleActions() 
    341394{ 
    342   rrlib::serialization::tMemoryBuffer result_buffer; 
    343   rrlib::serialization::tOutputStream output_stream(result_buffer, rrlib::serialization::tTypeEncoding::NAMES); 
    344   const std::vector<tCreateFrameworkElementAction*>& module_types = tCreateFrameworkElementAction::GetConstructibleElements(); 
    345   for (size_t i = 0u; i < module_types.size(); i++) 
    346   { 
    347     const tCreateFrameworkElementAction& create_action = *module_types[i]; 
    348     output_stream.WriteString(create_action.GetName()); 
    349     output_stream.WriteString(create_action.GetModuleGroup().ToString()); 
    350     output_stream.WriteBoolean(create_action.GetParameterTypes()); 
    351     if (create_action.GetParameterTypes()) 
    352     { 
    353       output_stream << *create_action.GetParameterTypes(); 
    354     } 
    355   } 
    356   output_stream.Close(); 
    357   return result_buffer; 
     395  FINROC_LOG_PRINT(WARNING, "GetCreateModuleActions() is superseded"); 
     396  return rrlib::serialization::tMemoryBuffer(); 
    358397} 
    359398 
     
    382421  parameters::tConfigFile* config_file = parameters::tConfigFile::Find(*root); 
    383422  rrlib::serialization::tMemoryBuffer result_buffer; 
    384   rrlib::serialization::tOutputStream output_stream(result_buffer, rrlib::serialization::tTypeEncoding::NAMES); 
     423  rrlib::serialization::tOutputStream output_stream(result_buffer, cBASIC_UID_SERIALIZATION_INFO); 
    385424  if (!config_file) 
    386425  { 
     
    462501    const std::string& remote_runtime_uuid, int remote_port_handle, const std::string& remote_port_link, bool disconnect) 
    463502{ 
    464   // check local port 
    465   auto cVOLATILE = core::tFrameworkElement::tFlag::VOLATILE; 
    466   core::tAbstractPort* local_port = Runtime().GetPort(local_port_handle); 
    467   std::string return_message; 
    468   if (!local_port) 
    469   { 
    470     return_message = disconnect ? "Local port to be disconnected does not exist" : "Local port to be connected does not exist"; 
    471     FINROC_LOG_PRINT(WARNING, return_message); 
    472     return return_message; 
    473   } 
    474   if ((!disconnect) && local_port->GetFlag(cVOLATILE)) 
    475   { 
    476     return_message = "Cannot really persistently connect a volatile port: " + local_port->GetQualifiedLink(); 
    477     FINROC_LOG_PRINT(WARNING, return_message); 
    478     return return_message; 
    479   } 
    480  
    481   // create list with order in which network transports are tried 
    482   std::vector<network_transport::tNetworkTransportPlugin*> transports_to_try; 
    483   for (auto it = network_transport::tNetworkTransportPlugin::GetAll().begin(); it != network_transport::tNetworkTransportPlugin::GetAll().end(); ++it) 
    484   { 
    485     if (preferred_transport == (*it)->GetName()) 
    486     { 
    487       transports_to_try.insert(transports_to_try.begin(), *it); 
    488     } 
    489     else 
    490     { 
    491       transports_to_try.push_back(*it); 
    492     } 
    493   } 
    494  
    495   if (disconnect) 
    496   { 
    497     // try disconnecting with all available transport plugins 
    498     for (auto it = transports_to_try.begin(); it != transports_to_try.end(); ++it) 
    499     { 
    500       (*it)->Disconnect(*local_port, remote_runtime_uuid, remote_port_handle, remote_port_link); 
    501     } 
    502     return ""; 
    503   } 
    504  
    505   // try connecting 
    506   for (auto it = transports_to_try.begin(); it != transports_to_try.end(); ++it) 
    507   { 
    508     std::string result = (*it)->Connect(*local_port, remote_runtime_uuid, remote_port_handle, remote_port_link); 
    509     if (result.length() == 0) 
    510     { 
    511       FINROC_LOG_PRINT(USER, "Connected local port '", local_port->GetQualifiedLink(), "' to remote port '", remote_port_link, "' via ", (*it)->GetName()); 
    512       return ""; 
    513     } 
    514   } 
    515  
    516   return_message = "Could not connect local port " + local_port->GetQualifiedLink() + " to remote port " + remote_port_link + " using any available network transport plugin."; 
    517   FINROC_LOG_PRINT(WARNING, return_message); 
    518   return return_message; 
     503  const char* message = "tAdministrationService::NetworkConnect() is superseded. Please use a newer version of your tool that uses CreateUriConnector()."; 
     504  FINROC_LOG_PRINT(WARNING, message); 
     505  return message; 
    519506} 
    520507 
     
    552539        else 
    553540        { 
    554           FINROC_LOG_PRINT(ERROR, "Element invalidly flagged as finstructable: ", it->GetQualifiedLink()); 
     541          FINROC_LOG_PRINT(ERROR, "Element invalidly flagged as finstructable: ", *it); 
    555542        } 
    556543      } 
    557544      catch (const std::exception& e) 
    558545      { 
    559         FINROC_LOG_PRINT(ERROR, "Error saving finstructable group ", it->GetQualifiedLink()); 
     546        FINROC_LOG_PRINT(ERROR, "Error saving finstructable group ", *it); 
    560547        FINROC_LOG_PRINT(ERROR, e); 
    561548      } 
     
    578565      else 
    579566      { 
    580         FINROC_LOG_PRINT(ERROR, "Element invalidly flagged as finstructable: ", group->GetQualifiedLink()); 
     567        FINROC_LOG_PRINT(ERROR, "Element invalidly flagged as finstructable: ", *group); 
    581568      } 
    582569    } 
    583570    catch (const std::exception& e) 
    584571    { 
    585       FINROC_LOG_PRINT(ERROR, "Error saving finstructable group ", group->GetQualifiedLink()); 
     572      FINROC_LOG_PRINT(ERROR, "Error saving finstructable group ", *group); 
    586573      FINROC_LOG_PRINT(ERROR, e); 
    587574    } 
     
    602589  else 
    603590  { 
    604     rrlib::serialization::tInputStream input_stream(serialized_annotation, rrlib::serialization::tTypeEncoding::NAMES); 
     591    rrlib::serialization::tInputStream input_stream(serialized_annotation, cBASIC_UID_SERIALIZATION_INFO); 
    605592    rrlib::rtti::tType type; 
    606593    input_stream >> type; 
     
    641628std::string tAdministrationService::SetPortValue(int port_handle, const rrlib::serialization::tMemoryBuffer& serialized_new_value) 
    642629{ 
     630  enum tDataEncoding 
     631  { 
     632    BINARY, 
     633    STRING, 
     634    XML, 
     635    STATIC_CAST, 
     636    DOUBLE_STATIC_CAST, 
     637    DIMENSION 
     638  }; 
     639 
    643640  core::tAbstractPort* port = Runtime().GetPort(port_handle); 
    644641  std::string error_message; 
     
    655652      try 
    656653      { 
    657         rrlib::serialization::tInputStream input_stream(serialized_new_value, rrlib::serialization::tTypeEncoding::NAMES); 
    658         rrlib::serialization::tDataEncoding encoding; 
    659         input_stream >> encoding; 
     654        rrlib::serialization::tInputStream input_stream(serialized_new_value, cBASIC_UID_SERIALIZATION_INFO); 
     655        uint8_t encoding = input_stream.ReadByte(); 
     656        if (encoding >= DIMENSION) 
     657        { 
     658          throw std::runtime_error("Invalid encoding"); 
     659        } 
    660660        data_ports::tGenericPort wrapped_port = data_ports::tGenericPort::Wrap(*port); 
    661661        data_ports::tPortDataPointer<rrlib::rtti::tGenericObject> buffer = wrapped_port.GetUnusedBuffer(); 
    662         buffer->Deserialize(input_stream, encoding); 
     662        if (encoding <= XML) 
     663        { 
     664          buffer->Deserialize(input_stream, static_cast<rrlib::serialization::tDataEncoding>(encoding)); 
     665        } 
     666        else 
     667        { 
     668          rrlib::serialization::tDataEncoding encoding2; 
     669          input_stream >> encoding2; 
     670          rrlib::rtti::tType type = rrlib::rtti::tType::GetType(input_stream.ReadShort()); 
     671          rrlib::rtti::conversion::tCompiledConversionOperation operation; 
     672          if (encoding == STATIC_CAST) 
     673          { 
     674            operation = rrlib::rtti::conversion::tConversionOperationSequence(rrlib::rtti::conversion::tStaticCastOperation::GetInstance()).Compile(false, type, wrapped_port.GetDataType()); 
     675          } 
     676          else 
     677          { 
     678            rrlib::rtti::tType inter_type = rrlib::rtti::tType::GetType(input_stream.ReadShort()); 
     679            operation = rrlib::rtti::conversion::tConversionOperationSequence(rrlib::rtti::conversion::tStaticCastOperation::GetInstance(), rrlib::rtti::conversion::tStaticCastOperation::GetInstance(), inter_type).Compile(false, type, wrapped_port.GetDataType()); 
     680          } 
     681          std::unique_ptr<rrlib::rtti::tGenericObject> object(type.CreateGenericObject()); 
     682          object->Deserialize(input_stream, encoding2); 
     683          operation.Convert(*object, *buffer); 
     684        } 
    663685        error_message = wrapped_port.BrowserPublish(buffer); 
    664686        if (error_message.length() > 0) 
    665687        { 
    666           FINROC_LOG_PRINT(WARNING, "Setting value of port '", port->GetQualifiedName(), "' failed: ", error_message); 
     688          FINROC_LOG_PRINT(WARNING, "Setting value of port '", port, "' failed: ", error_message); 
    667689        } 
    668690      } 
    669691      catch (const std::exception& e) 
    670692      { 
    671         FINROC_LOG_PRINT(WARNING, "Setting value of port '", port->GetQualifiedName(), "' failed: ", e); 
     693        FINROC_LOG_PRINT(WARNING, "Setting value of port '", port, "' failed: ", e); 
    672694        error_message = e.what(); 
    673695      } 
  • tAdministrationService.h

    r89 r90  
    134134 
    135135  /*! 
     136   * Create URI connector connecting local port using one of the supported URI schemes (provided e.g. by network transports). 
     137   * 
     138   * \param local_port_handle Handle of local owner port 
     139   * \param uri URI of partner port 
     140   * \param connect_options Connect options 
     141   * \return Returns error message if connecting failed. On success an empty string is returned. 
     142   */ 
     143  std::string CreateUriConnector(int local_port_handle, const rrlib::uri::tURI& uri, const core::tUriConnectOptions& connect_options); 
     144 
     145  /*! 
    136146   * Deletes specified framework element 
    137147   * 
     
    139149   */ 
    140150  void DeleteElement(int element_handle); 
     151 
     152  /*! 
     153   * Delete URI connector 
     154   * 
     155   * \param local_port_handle Handle of local owner port 
     156   * \param uri URI of partner port 
     157   * \return Whether any connector was deleted 
     158   */ 
     159  bool DeleteUriConnector(int local_port_handle, const rrlib::uri::tURI& uri); 
    141160 
    142161  /*! 
  • tCreateFrameworkElementAction.cpp

    r55 r90  
    7373{ 
    7474 
    75 std::vector<tCreateFrameworkElementAction*>& GetConstructibleElements() 
     75tCreateFrameworkElementAction::tRegister& GetConstructibleElements() 
    7676{ 
    77   static std::vector<tCreateFrameworkElementAction*> module_types; 
     77  static tCreateFrameworkElementAction::tRegister module_types; 
    7878  return module_types; 
    7979} 
     
    8383tCreateFrameworkElementAction::tCreateFrameworkElementAction() 
    8484{ 
    85   internal::GetConstructibleElements().push_back(this); 
     85  internal::GetConstructibleElements().Add(this); 
    8686} 
    8787 
     
    9898} 
    9999 
    100 const std::vector<tCreateFrameworkElementAction*>& tCreateFrameworkElementAction::GetConstructibleElements() 
     100const tCreateFrameworkElementAction::tRegister& tCreateFrameworkElementAction::GetConstructibleElements() 
    101101{ 
    102102  return internal::GetConstructibleElements(); 
     103} 
     104 
     105bool tCreateFrameworkElementAction::IsDeprecated() const 
     106{ 
     107  return false; 
    103108} 
    104109 
  • tCreateFrameworkElementAction.h

    r39 r90  
    7979public: 
    8080 
     81  typedef rrlib::serialization::tRegister<tCreateFrameworkElementAction*, 64, 128, uint16_t> tRegister; 
     82 
    8183  tCreateFrameworkElementAction(); 
     84 
     85  virtual ~tCreateFrameworkElementAction() = default; 
    8286 
    8387  /*! 
     
    8993   * \return Created Module (or Group) 
    9094   */ 
    91   virtual core::tFrameworkElement* CreateModule(core::tFrameworkElement* parent, const std::string& name, tConstructorParameters* params = NULL) const = 0; 
     95  virtual core::tFrameworkElement* CreateModule(core::tFrameworkElement* parent, const std::string& name, tConstructorParameters* params = nullptr) const = 0; 
     96 
     97  /*! 
     98   * \return Returns .so file in which address provided as argument is found by dladdr 
     99   */ 
     100  tSharedLibrary GetBinary(void* addr); 
    92101 
    93102  /*! 
    94103   * \return List with framework element types that can be instantiated in this runtime using this standard mechanism 
    95104   */ 
    96   static const std::vector<tCreateFrameworkElementAction*>& GetConstructibleElements(); 
     105  static const tRegister& GetConstructibleElements(); 
    97106 
    98107  /*! 
     
    112121 
    113122  /*! 
    114    * \return Returns .so file in which address provided as argument is found by dladdr 
     123   * \return Whether create action is deprecated; 
    115124   */ 
    116   tSharedLibrary GetBinary(void* addr); 
     125  virtual bool IsDeprecated() const; 
    117126 
    118127//---------------------------------------------------------------------- 
  • tFinstructable.cpp

    r88 r90  
    3737#include "core/file_lookup.h" 
    3838#include "core/tRuntimeEnvironment.h" 
    39 #include "core/internal/tByStringConnector.h" 
    4039#include "plugins/parameters/internal/tParameterInfo.h" 
    4140 
     
    7877 
    7978/*! Thread currently saving finstructable group */ 
    80 static rrlib::thread::tThread* saving_thread = NULL; 
     79static rrlib::thread::tThread* saving_thread = nullptr; 
    8180 
    8281/*! Temporary variable for saving: .so files that should be loaded prior to instantiating this group */ 
     
    112111} 
    113112 
    114 void tFinstructable::AnnotatedObjectInitialized() 
    115 { 
    116   if (!GetFrameworkElement()->GetFlag(tFlag::FINSTRUCTABLE_GROUP)) 
    117   { 
    118     throw std::logic_error("Any class using tFinstructable must set tFlag::FINSTRUCTABLE_GROUP in constructor"); 
    119   } 
    120 } 
    121  
    122 core::tAbstractPort* tFinstructable::GetChildPort(const std::string& link) 
    123 { 
    124   if (link[0] == '/') 
    125   { 
    126     return core::tRuntimeEnvironment::GetInstance().GetPort(link); 
    127   } 
    128   tFrameworkElement* fe = GetFrameworkElement()->GetChildElement(link, false); 
    129   if (fe != NULL && fe->IsPort()) 
    130   { 
    131     return static_cast<core::tAbstractPort*>(fe); 
    132   } 
    133   return NULL; 
    134 } 
    135  
    136 std::string tFinstructable::GetEdgeLink(const std::string& target_link, const std::string& this_group_link) 
    137 { 
    138   if (target_link.compare(0, this_group_link.length(), this_group_link) == 0) 
    139   { 
    140     return target_link.substr(this_group_link.length()); 
    141   } 
    142   return target_link; 
    143 } 
    144  
    145 std::string tFinstructable::GetEdgeLink(core::tAbstractPort& ap, const std::string& this_group_link) 
    146 { 
    147   tFrameworkElement* alt_root = ap.GetParentWithFlags(tFlag::ALTERNATIVE_LINK_ROOT); 
     113core::tAbstractPort* tFinstructable::GetChildPort(const core::tPath& path) 
     114{ 
     115  tFrameworkElement* element = GetFrameworkElement()->GetChild(path); 
     116  if (element && element->IsPort()) 
     117  { 
     118    return static_cast<core::tAbstractPort*>(element); 
     119  } 
     120  return nullptr; 
     121} 
     122 
     123core::tPath tFinstructable::GetConnectorPath(const core::tPath& target_path, const core::tPath& this_group_path) 
     124{ 
     125  if (target_path.CountCommonElements(this_group_path) == this_group_path.Size()) 
     126  { 
     127    return core::tPath(false, target_path.Begin() + this_group_path.Size(), target_path.End()); 
     128  } 
     129  return target_path; 
     130} 
     131 
     132core::tPath tFinstructable::GetConnectorPath(core::tAbstractPort& port, const core::tPath& this_group_path) 
     133{ 
     134  core::tPath port_path = port.GetPath(); 
     135  tFrameworkElement* alt_root = port.GetParentWithFlags(tFlag::ALTERNATIVE_LOCAL_URI_ROOT); 
    148136  if (alt_root && alt_root->IsChildOf(*GetFrameworkElement())) 
    149137  { 
    150     return ap.GetQualifiedLink(); 
    151   } 
    152   return ap.GetQualifiedName().substr(this_group_link.length()); 
     138    return core::tPath(true, port_path.Begin() + alt_root->GetPath().Size(), port_path.End()); 
     139  } 
     140  return core::tPath(true, port_path.Begin() + this_group_path.Size(), port_path.End()); 
    153141} 
    154142 
    155143std::string tFinstructable::GetLogDescription() const 
    156144{ 
    157   return GetFrameworkElement() ? GetFrameworkElement()->GetQualifiedName() : "Unattached Finstructable"; 
     145  if (GetFrameworkElement()) 
     146  { 
     147    std::stringstream stream; 
     148    stream << *GetFrameworkElement(); 
     149    return stream.str(); 
     150  } 
     151  return "Unattached Finstructable"; 
    158152} 
    159153 
     
    182176    // read parameters 
    183177    rrlib::xml::tNode::const_iterator child_node = node.ChildrenBegin(); 
    184     const rrlib::xml::tNode* parameters = NULL; 
    185     const rrlib::xml::tNode* constructor_params = NULL; 
     178    const rrlib::xml::tNode* parameters = nullptr; 
     179    const rrlib::xml::tNode* constructor_params = nullptr; 
    186180    std::string p_name = child_node->Name(); 
    187181    if (p_name == "constructor") 
     
    198192 
    199193    // create mode 
    200     tFrameworkElement* created = NULL; 
    201     tConstructorParameters* spl = NULL; 
    202     if (constructor_params != NULL) 
     194    tFrameworkElement* created = nullptr; 
     195    tConstructorParameters* spl = nullptr; 
     196    if (constructor_params != nullptr) 
    203197    { 
    204198      spl = action.GetParameterTypes()->Instantiate(); 
     
    248242  if (!pi) 
    249243  { 
    250     FINROC_LOG_PRINT(WARNING, "Port is not a parameter: '", parameter_port.GetQualifiedName(), "'. Parameter entry is not loaded."); 
     244    FINROC_LOG_PRINT(WARNING, "Port is not a parameter: '", parameter_port, "'. Parameter entry is not loaded."); 
    251245  } 
    252246  else 
     
    266260    catch (const std::exception& e) 
    267261    { 
    268       FINROC_LOG_PRINT(WARNING, "Unable to load parameter value for '", parameter_port.GetQualifiedName(), "'. ", e); 
     262      FINROC_LOG_PRINT(WARNING, "Unable to load parameter value for '", parameter_port, "'. ", e); 
    269263    } 
    270264  } 
     
    280274      rrlib::xml::tDocument doc(core::GetFinrocXMLDocument(GetXmlFileString(), false)); 
    281275      rrlib::xml::tNode& root = doc.RootNode(); 
    282       std::string link_tmp = GetFrameworkElement()->GetQualifiedName() + "/"; 
     276      core::tPath path_to_this = GetFrameworkElement()->GetPath(); 
    283277      if (main_name.length() == 0 && root.HasAttribute("defaultname")) 
    284278      { 
     
    364358        else if (name == "edge") 
    365359        { 
    366           std::string src = node->GetStringAttribute("src"); 
    367           std::string dest = node->GetStringAttribute("dest"); 
    368           core::tAbstractPort* src_port = GetChildPort(src); 
    369           core::tAbstractPort* dest_port = GetChildPort(dest); 
    370           if (src_port == NULL && dest_port == NULL) 
    371           { 
    372             FINROC_LOG_PRINT(WARNING, "Cannot create edge because neither port is available: ", src, ", ", dest); 
    373           } 
    374           else if (src_port == NULL || src_port->GetFlag(tFlag::VOLATILE))    // source volatile 
    375           { 
    376             dest_port->ConnectTo(QualifyLink(src, link_tmp), core::tConnectionFlag::FINSTRUCTED | core::tConnectionFlag::RECONNECT); 
    377           } 
    378           else if (dest_port == NULL || dest_port->GetFlag(tFlag::VOLATILE))    // destination volatile 
    379           { 
    380             src_port->ConnectTo(QualifyLink(dest, link_tmp), core::tConnectionFlag::FINSTRUCTED | core::tConnectionFlag::RECONNECT); 
     360          core::tURI source_uri(node->GetStringAttribute("src")); 
     361          core::tURI destination_uri(node->GetStringAttribute("dest")); 
     362          try 
     363          { 
     364            rrlib::uri::tURIElements source_uri_parsed; 
     365            rrlib::uri::tURIElements destination_uri_parsed; 
     366            source_uri.Parse(source_uri_parsed); 
     367            destination_uri.Parse(destination_uri_parsed); 
     368            core::tUriConnectOptions connect_options(core::tConnectionFlag::FINSTRUCTED); 
     369            if (node->HasAttribute("flags")) 
     370            { 
     371              connect_options.flags |= rrlib::serialization::Deserialize<core::tConnectionFlags>(node->GetStringAttribute("flags")); 
     372            } 
     373 
     374            for (rrlib::xml::tNode::const_iterator conversion_node = node->ChildrenBegin(); conversion_node != node->ChildrenEnd(); ++conversion_node) 
     375            { 
     376              if (conversion_node->Name() == "conversion") 
     377              { 
     378                rrlib::rtti::tType intermediate_type; 
     379                if (conversion_node->HasAttribute("intermediate_type")) 
     380                { 
     381                  intermediate_type = rrlib::rtti::tType::FindType(conversion_node->GetStringAttribute("intermediate_type")); 
     382                } 
     383                if (conversion_node->HasAttribute("operation2")) 
     384                { 
     385                  // Two operations 
     386                  std::string operation1 = conversion_node->GetStringAttribute("operation1"); 
     387                  std::string operation2 = conversion_node->GetStringAttribute("operation2"); 
     388                  connect_options.conversion_operations = rrlib::rtti::conversion::tConversionOperationSequence(operation1, operation2, intermediate_type); 
     389                  if (conversion_node->HasAttribute("parameter1")) 
     390                  { 
     391                    connect_options.conversion_operations.SetParameterValue(0, conversion_node->GetStringAttribute("parameter1")); 
     392                  } 
     393                  if (conversion_node->HasAttribute("parameter2")) 
     394                  { 
     395                    connect_options.conversion_operations.SetParameterValue(1, conversion_node->GetStringAttribute("parameter2")); 
     396                  } 
     397                } 
     398                else if (conversion_node->HasAttribute("operation")) 
     399                { 
     400                  // One operation 
     401                  std::string operation1 = conversion_node->GetStringAttribute("operation"); 
     402                  connect_options.conversion_operations = rrlib::rtti::conversion::tConversionOperationSequence(operation1, "", intermediate_type); 
     403                  if (conversion_node->HasAttribute("parameter")) 
     404                  { 
     405                    connect_options.conversion_operations.SetParameterValue(0, conversion_node->GetStringAttribute("parameter")); 
     406                  } 
     407                } 
     408              } 
     409            } 
     410 
     411            if (source_uri_parsed.scheme.length() == 0 && destination_uri_parsed.scheme.length() == 0) 
     412            { 
     413              core::tAbstractPort* source_port = GetChildPort(source_uri_parsed.path); 
     414              core::tAbstractPort* destination_port = GetChildPort(destination_uri_parsed.path); 
     415 
     416              if (source_port == nullptr && destination_port == nullptr) 
     417              { 
     418                FINROC_LOG_PRINT(WARNING, "Cannot create connector because neither port is available: ", source_uri_parsed.path, ", ", destination_uri_parsed.path); 
     419              } 
     420              else if (source_port == nullptr || source_port->GetFlag(tFlag::VOLATILE))    // source volatile 
     421              { 
     422                connect_options.flags |= core::tConnectionFlag::RECONNECT; 
     423                destination_port->ConnectTo(path_to_this.Append(source_uri_parsed.path), connect_options); 
     424              } 
     425              else if (destination_port == nullptr || destination_port->GetFlag(tFlag::VOLATILE))    // destination volatile 
     426              { 
     427                connect_options.flags |= core::tConnectionFlag::RECONNECT; 
     428                source_port->ConnectTo(path_to_this.Append(destination_uri_parsed.path), connect_options); 
     429              } 
     430              else 
     431              { 
     432                source_port->ConnectTo(*destination_port, connect_options); 
     433              } 
     434            } 
     435            else 
     436            { 
     437              // Create URI connector 
     438              if (source_uri_parsed.scheme.length() && destination_uri_parsed.scheme.length()) 
     439              { 
     440                throw std::runtime_error("Only one port may have an address with an URI scheme"); 
     441              } 
     442              core::tAbstractPort* source_port = GetChildPort(source_uri_parsed.scheme.length() == 0 ? source_uri_parsed.path : destination_uri_parsed.path); 
     443              if (!source_port) 
     444              { 
     445                FINROC_LOG_PRINT(WARNING, "Cannot create connector because port is not available: ", source_uri_parsed.scheme.length() == 0 ? source_uri_parsed.path : destination_uri_parsed.path); 
     446              } 
     447              const core::tURI& scheme_uri = source_uri_parsed.scheme.length() != 0 ? source_uri : destination_uri; 
     448 
     449              // read parameters 
     450              for (rrlib::xml::tNode::const_iterator parameter_node = node->ChildrenBegin(); parameter_node != node->ChildrenEnd(); ++parameter_node) 
     451              { 
     452                if (parameter_node->Name() == "parameter") 
     453                { 
     454                  connect_options.parameters.emplace(parameter_node->GetStringAttribute("name"), parameter_node->GetTextContent()); 
     455                } 
     456              } 
     457 
     458              core::tUriConnector::Create(*source_port, scheme_uri, connect_options); 
     459            } 
     460          } 
     461          catch (const std::exception& e) 
     462          { 
     463            FINROC_LOG_PRINT(WARNING, "Creating connector from ", source_uri.ToString(), " to ", destination_uri.ToString(), " failed. Reason: ", e.what()); 
     464          } 
     465        } 
     466        else if (name == "parameter") // legacy parameter info support 
     467        { 
     468          core::tURI parameter_uri(node->GetStringAttribute("link")); 
     469          rrlib::uri::tURIElements parameter_uri_parsed; 
     470          parameter_uri.Parse(parameter_uri_parsed); 
     471          core::tAbstractPort* parameter = GetChildPort(parameter_uri_parsed.path); 
     472          if (!parameter) 
     473          { 
     474            FINROC_LOG_PRINT(WARNING, "Cannot set config entry, because parameter is not available: ", parameter_uri.ToString()); 
    381475          } 
    382476          else 
    383477          { 
    384             src_port->ConnectTo(*dest_port, core::tConnectionFlag::FINSTRUCTED); 
    385           } 
    386         } 
    387         else if (name == "parameter") // legacy parameter info support 
    388         { 
    389           std::string param = node->GetStringAttribute("link"); 
    390           core::tAbstractPort* parameter = GetChildPort(param); 
    391           if (!parameter) 
    392           { 
    393             FINROC_LOG_PRINT(WARNING, "Cannot set config entry, because parameter is not available: ", param); 
    394           } 
    395           else 
    396           { 
    397478            LoadParameter(*node, *parameter); 
    398479          } 
     
    413494      FINROC_LOG_PRINT(WARNING, "Loading XML '", GetXmlFileString(), "' failed: ", e); 
    414495    } 
     496  } 
     497} 
     498 
     499void tFinstructable::OnInitialization() 
     500{ 
     501  if (!GetFrameworkElement()->GetFlag(tFlag::FINSTRUCTABLE_GROUP)) 
     502  { 
     503    throw std::logic_error("Any class using tFinstructable must set tFlag::FINSTRUCTABLE_GROUP in constructor"); 
    415504  } 
    416505} 
     
    430519      else 
    431520      { 
    432         FINROC_LOG_PRINT(WARNING, "Cannot find '", element.GetQualifiedLink(), "/", name, "'. Parameter entries below are not loaded."); 
     521        FINROC_LOG_PRINT(WARNING, "Cannot find '", element, "/", name, "'. Parameter entries below are not loaded."); 
    433522      } 
    434523    } 
     
    448537      else 
    449538      { 
    450         FINROC_LOG_PRINT(WARNING, "Cannot find parameter '", element.GetQualifiedLink(), "/", name, "'. Parameter entry is not loaded."); 
    451       } 
    452     } 
    453   } 
    454 } 
    455  
    456 std::string tFinstructable::QualifyLink(const std::string& link, const std::string& this_group_link) 
    457 { 
    458   if (link[0] == '/') 
    459   { 
    460     return link; 
    461   } 
    462   return this_group_link + link; 
     539        FINROC_LOG_PRINT(WARNING, "Cannot find parameter '", element, "/", name, "'. Parameter entry is not loaded."); 
     540      } 
     541    } 
     542  } 
    463543} 
    464544 
     
    633713      SerializeChildren(root, *GetFrameworkElement()); 
    634714 
    635       // serialize edges (sorted by port links (we do not want changes in finstruct files depending on whether or not an optional/volatile connector exists)) 
    636       std::string this_qualified_link = GetFrameworkElement()->GetQualifiedName() + "/"; 
    637       std::map<std::pair<std::string, std::string>, std::pair<core::tConnector*, core::internal::tByStringConnector*>> connector_map; 
    638       std::set<core::tConnector*> skip_connectors; 
     715      // serialize connectors (sorted by port URIs (we do not want changes in finstruct files depending on whether or not an optional/volatile connector exists)) 
     716      rrlib::uri::tPath this_path = GetFrameworkElement()->GetPath(); 
     717      std::map<std::pair<rrlib::uri::tURI, rrlib::uri::tURI>, std::pair<core::tConnector*, core::tUriConnector*>> connector_map; 
    639718      bool this_is_outermost_composite_component = GetFrameworkElement()->GetParentWithFlags(tFlag::FINSTRUCTABLE_GROUP) == nullptr; 
    640719 
    641       // First pass: Get ByStringConnectors and fill skip_connectors list 
    642       for (auto it = GetFrameworkElement()->SubElementsBegin(); it != GetFrameworkElement()->SubElementsEnd(); ++it) 
    643       { 
    644         if ((!it->IsPort()) || (!it->IsReady())) 
    645         { 
    646           continue; 
    647         } 
    648         core::tAbstractPort& port = static_cast<core::tAbstractPort&>(*it); 
    649  
    650         // Get ByStringConnectors first 
    651         if (port.by_string_connectors) 
    652         { 
    653           tFrameworkElement* port_parent_group = port.GetParentWithFlags(tFlag::FINSTRUCTABLE_GROUP); 
    654           for (auto & connector : (*port.by_string_connectors)) 
    655           { 
    656             if (!connector->Flags().Get(core::tConnectionFlag::FINSTRUCTED)) 
    657             { 
    658               continue; 
    659             } 
    660             if (connector->GetConnection()) 
    661             { 
    662               skip_connectors.insert(connector->GetConnection()); 
    663             } 
    664  
    665             // connectors should be saved in innermost composite component that contains both ports (common parent); if there is no such port, then save in outermost composite component 
    666             bool source_link = connector->GetPortReferences()[0].link.length(); 
    667             std::string link = source_link ? connector->GetPortReferences()[0].link : connector->GetPortReferences()[1].link; 
    668             tFrameworkElement* common_parent = port_parent_group; 
    669             while (common_parent && (!rrlib::util::StartsWith(link, common_parent->GetQualifiedName()))) 
    670             { 
    671               common_parent = common_parent->GetParentWithFlags(tFlag::FINSTRUCTABLE_GROUP); 
    672             } 
    673             if (common_parent != GetFrameworkElement() && (!(this_is_outermost_composite_component && common_parent == nullptr))) 
    674             { 
    675               // save connector in another group 
    676               continue; 
    677             } 
    678  
    679             std::string this_port_link = GetEdgeLink(port, this_qualified_link); 
    680             std::pair<std::string, std::string> key(source_link ? link : this_port_link, source_link ? this_port_link : link); 
    681             std::pair<core::tConnector*, core::internal::tByStringConnector*> value(connector->GetConnection(), connector.get()); 
    682             connector_map.emplace(key, value); 
    683           } 
    684         } 
    685       } 
    686  
    687       // Second pass: Plain connectors 
     720      // Get (primary) connectors 
    688721      for (auto it = GetFrameworkElement()->SubElementsBegin(); it != GetFrameworkElement()->SubElementsEnd(); ++it) 
    689722      { 
     
    695728        tFrameworkElement* port_parent_group = port.GetParentWithFlags(tFlag::FINSTRUCTABLE_GROUP); 
    696729 
     730        // Plain connectors 
    697731        for (auto it = port.OutgoingConnectionsBegin(); it != port.OutgoingConnectionsEnd(); ++it) // only outgoing edges => we don't get any edges twice 
    698732        { 
    699           // possibly save connector? 
    700  
    701           // only save finstructed edges 
    702           if (!it->Flags().Get(core::tConnectionFlag::FINSTRUCTED)) 
    703           { 
    704             continue; 
    705           } 
    706           // only save edges that are not attached to a tByStringConnector => we don't get any edges twice 
    707           if (skip_connectors.find(&(*it)) != skip_connectors.end()) 
     733          // Checks whether to save connector 
     734          // only save primary finstructed edges 
     735          if ((!it->Flags().Get(core::tConnectionFlag::FINSTRUCTED)) || it->Flags().Get(core::tConnectionFlag::NON_PRIMARY_CONNECTOR)) 
    708736          { 
    709737            continue; 
     
    722750          } 
    723751 
    724           std::pair<std::string, std::string> key(GetEdgeLink(port, this_qualified_link), GetEdgeLink(it->Destination(), this_qualified_link)); 
    725           std::pair<core::tConnector*, core::internal::tByStringConnector*> value(&(*it), nullptr); 
     752          std::pair<rrlib::uri::tURI, rrlib::uri::tURI> key(GetConnectorPath(port.GetPath(), this_path), GetConnectorPath(it->Destination().GetPath(), this_path)); 
     753          std::pair<core::tConnector*, core::tUriConnector*> value(&(*it), nullptr); 
    726754          connector_map.emplace(key, value); 
    727755        } 
     756 
     757        // Get URI connectors 
     758        for (auto & connector : port.UriConnectors()) 
     759        { 
     760          // Checks whether to save connector 
     761          // only save primary finstructed edges 
     762          if ((!connector) || (!connector->Flags().Get(core::tConnectionFlag::FINSTRUCTED)) || connector->Flags().Get(core::tConnectionFlag::NON_PRIMARY_CONNECTOR)) 
     763          { 
     764            continue; 
     765          } 
     766 
     767          std::pair<rrlib::uri::tURI, rrlib::uri::tURI> key(GetConnectorPath(port.GetPath(), this_path), connector->Uri()); 
     768 
     769          // local URI connectors should be saved in innermost composite component that contains both ports (common parent); if there is no such port, then save in outermost composite component 
     770          if (typeid(*connector) == typeid(core::internal::tLocalUriConnector)) 
     771          { 
     772            auto& local_connector = static_cast<core::internal::tLocalUriConnector&>(*connector); 
     773            bool source_uri = local_connector.GetPortReferences()[0].path.Size(); 
     774            rrlib::uri::tPath path = local_connector.GetPortReferences()[source_uri ? 0 : 1].path; 
     775            tFrameworkElement* common_parent = port_parent_group; 
     776            rrlib::uri::tPath parent_group_path = common_parent->GetPath(); 
     777            while (common_parent && path.CountCommonElements(parent_group_path) != parent_group_path.Size()) 
     778            { 
     779              common_parent = common_parent->GetParentWithFlags(tFlag::FINSTRUCTABLE_GROUP); 
     780              parent_group_path = common_parent ? common_parent->GetPath() : parent_group_path; 
     781            } 
     782            if (common_parent != GetFrameworkElement() && (!(this_is_outermost_composite_component && common_parent == nullptr))) 
     783            { 
     784              // save connector in another group 
     785              continue; 
     786            } 
     787 
     788            rrlib::uri::tURI port_uri = key.first; 
     789            key.first = source_uri ? rrlib::uri::tURI(path) : port_uri; 
     790            key.second = source_uri ? port_uri : rrlib::uri::tURI(path); 
     791          } 
     792 
     793          std::pair<core::tConnector*, core::tUriConnector*> value(nullptr, connector.get()); 
     794          connector_map.emplace(key, value); 
     795        } 
    728796      } 
    729797 
     
    731799      { 
    732800        rrlib::xml::tNode& edge = root.AddChildNode("edge"); // TODO: "connector"? 
    733         edge.SetAttribute("src", entry.first.first); 
    734         edge.SetAttribute("dest", entry.first.second); 
    735         // TODO: save more info  (flags optional & reconnect) 
     801        edge.SetAttribute("src", entry.first.first.ToString()); 
     802        edge.SetAttribute("dest", entry.first.second.ToString()); 
     803 
     804        // Save flags 
     805        core::tConnectionFlags cFLAGS_TO_SAVE = core::tConnectionFlag::DIRECTION_TO_DESTINATION | core::tConnectionFlag::DIRECTION_TO_SOURCE | core::tConnectionFlag::OPTIONAL | core::tConnectionFlag::RECONNECT | core::tConnectionFlag::SCHEDULING_NEUTRAL; 
     806        core::tConnectionFlags flags_to_save((entry.second.first ? entry.second.first->Flags() : entry.second.second->Flags()).Raw() & cFLAGS_TO_SAVE.Raw()); 
     807        if (flags_to_save.Raw()) 
     808        { 
     809          edge.SetAttribute("flags", rrlib::serialization::Serialize(flags_to_save)); 
     810        } 
     811 
     812        // Save conversion operation 
     813        const rrlib::rtti::conversion::tConversionOperationSequence& conversion_operations = entry.second.first ? entry.second.first->ConversionOperations() : entry.second.second->ConversionOperations(); 
     814        if (conversion_operations.Size()) 
     815        { 
     816          rrlib::xml::tNode& conversion = root.AddChildNode("conversion"); 
     817          conversion.SetAttribute(conversion_operations.Size() == 2 ? "operation1" : "operation", conversion_operations[0].first); 
     818          if (conversion_operations.GetParameterValue(0)) 
     819          { 
     820            conversion.SetAttribute(conversion_operations.Size() == 2 ? "parameter1" : "parameter", conversion_operations.GetParameterValue(0).ToString()); 
     821          } 
     822          if (conversion_operations.Size() == 2) 
     823          { 
     824            conversion.SetAttribute("operation2", conversion_operations[1].first); 
     825            if (conversion_operations.GetParameterValue(0)) 
     826            { 
     827              conversion.SetAttribute("parameter2", conversion_operations.GetParameterValue(1).ToString()); 
     828            } 
     829          } 
     830          if (conversion_operations.IntermediateType()) 
     831          { 
     832            conversion.SetAttribute("intermediate_type", conversion_operations.IntermediateType().GetName()); 
     833          } 
     834        } 
     835 
     836        // Save parameters of URI connector 
     837        if (entry.second.second) 
     838        { 
     839          core::tUriConnector::tConstParameterDefinitionRange definition_range = entry.second.second->GetParameterDefinitions(); 
     840          core::tUriConnector::tParameterValueRange value_range = entry.second.second->GetParameterValues(); 
     841          assert(definition_range.End() - definition_range.Begin() == value_range.End() - value_range.Begin()); 
     842 
     843          auto definition = definition_range.Begin(); 
     844          auto value = value_range.Begin(); 
     845          for (; definition < definition_range.End(); ++definition, ++value) 
     846          { 
     847            if (!value->Equals(definition->GetDefaultValue())) 
     848            { 
     849              rrlib::xml::tNode& parameter_node = root.AddChildNode("parameter"); 
     850              parameter_node.SetAttribute("name", definition->GetName()); 
     851              value->Serialize(parameter_node); 
     852            } 
     853          } 
     854        } 
    736855      } 
    737856 
     
    767886    } 
    768887  } 
    769   saving_thread = NULL; 
     888  saving_thread = nullptr; 
    770889} 
    771890 
     
    824943      //} 
    825944      n.SetAttribute("type", cma->GetName()); 
    826       if (cps != NULL) 
     945      if (cps != nullptr) 
    827946      { 
    828947        rrlib::xml::tNode& pn = n.AddChildNode("constructor"); 
    829948        cps->Serialize(pn, true); 
    830949      } 
    831       if (spl != NULL) 
     950      if (spl != nullptr) 
    832951      { 
    833952        rrlib::xml::tNode& pn = n.AddChildNode("parameters"); 
     
    848967  assert(!fe.GetFlag(tFlag::FINSTRUCTED) && (!fe.IsReady())); 
    849968  parameters::internal::tStaticParameterList& list = parameters::internal::tStaticParameterList::GetOrCreate(fe); 
    850   const std::vector<tCreateFrameworkElementAction*>& v = tCreateFrameworkElementAction::GetConstructibleElements(); 
    851   list.SetCreateAction(static_cast<int>(std::find(v.begin(), v.end(), &create_action) - v.begin())); 
     969  auto& element_list = tCreateFrameworkElementAction::GetConstructibleElements(); 
     970  for (size_t i = 0, n = element_list.Size(); i < n; ++i) 
     971  { 
     972    if (element_list[i] == &create_action) 
     973    { 
     974      list.SetCreateAction(i); 
     975      break; 
     976    } 
     977  } 
    852978  fe.SetFlag(tFlag::FINSTRUCTED); 
    853979  if (params) 
  • tFinstructable.h

    r87 r90  
    170170 
    171171 
    172   virtual void AnnotatedObjectInitialized() override; 
    173  
    174172  /*! 
    175173   * Helper method to collect .so files that need to be loaded before the contents of 
     
    182180 
    183181  /*! 
    184    * \param cRelative port link 
    185    * \return Port - or null if it couldn't be found 
    186    */ 
    187   core::tAbstractPort* GetChildPort(const std::string& link); 
    188  
    189   /*! 
    190    * \param target_link (as from link edge) 
    191    * \param this_group_link Qualified link of this finstructable group 
    192    * \return Relative link to this port (or absolute link if it is globally unique) 
    193    */ 
    194   std::string GetEdgeLink(const std::string& target_link, const std::string& this_group_link); 
    195  
    196   /*! 
    197    * \param ap Port 
    198    * \param this_group_link Qualified link of this finstructable group 
    199    * \return Relative link to this port (or absolute link if it is globally unique) 
    200    */ 
    201   std::string GetEdgeLink(core::tAbstractPort& ap, const std::string& this_group_link); 
     182   * \param path Relative path to port 
     183   * \return Port - or nullptr if it couldn't be found 
     184   */ 
     185  core::tAbstractPort* GetChildPort(const core::tPath& path); 
     186 
     187  /*! 
     188   * \param target_path Target's absolute path (as from internal URI connector) 
     189   * \param this_group_path Path of this finstructable group 
     190   * \return Relative path to target (or absolute path if it is outside this group) 
     191   */ 
     192  core::tPath GetConnectorPath(const core::tPath& target_path, const core::tPath& this_group_path); 
     193 
     194  /*! 
     195   * \param port Port 
     196   * \param this_group_path Path of this finstructable group 
     197   * \return Relative path to port (or absolute path if it is outside this group) 
     198   */ 
     199  core::tPath GetConnectorPath(core::tAbstractPort& port, const core::tPath& this_group_path); 
    202200 
    203201  /*! 
     
    238236  void LoadParameter(const rrlib::xml::tNode& node, core::tAbstractPort& parameter_port); 
    239237 
     238  virtual void OnInitialization() override; 
     239 
    240240  /*! 
    241241   * Recursive helper function for loading parameter_links section of XML file 
     
    245245   */ 
    246246  void ProcessParameterLinksNode(const rrlib::xml::tNode& node, core::tFrameworkElement& element); 
    247  
    248   /*! 
    249    * Make fully-qualified link from relative one 
    250    * 
    251    * \param link Relative Link 
    252    * \param this_group_link Qualified link of this finstructable group 
    253    * \return Fully-qualified link 
    254    */ 
    255   std::string QualifyLink(const std::string& link, const std::string& this_group_link); 
    256247 
    257248  /*! 
     
    265256 
    266257  /*! 
     258   * Recursive helper function for ScanForCommandLineArgs 
     259   * 
     260   * \param result Result list 
     261   * \param parent Node to scan childs of 
     262   */ 
     263  static void ScanForCommandLineArgsHelper(std::vector<std::string>& result, const rrlib::xml::tNode& parent); 
     264 
     265  /*! 
    267266   * Serialize children of specified framework element 
    268267   * 
     
    273272 
    274273  /*! 
    275    * Recursive helper function for ScanForCommandLineArgs 
    276    * 
    277    * \param result Result list 
    278    * \param parent Node to scan childs of 
    279    */ 
    280   static void ScanForCommandLineArgsHelper(std::vector<std::string>& result, const rrlib::xml::tNode& parent); 
    281  
    282   /*! 
    283274   * Perform some static initialization w.r.t. to state at program startup 
    284275   */ 
  • tPortCreationList.cpp

    r89 r90  
    157157                                  const std::string& name, rrlib::rtti::tType type, const tPortCreateOptions& create_options, core::tAbstractPort* prototype) 
    158158{ 
    159   if (existing_port && existing_port->NameEquals(name) && existing_port->GetDataType() == type && 
     159  if (existing_port && existing_port->GetName() == name && existing_port->GetDataType() == type && 
    160160      existing_port->GetFlag(tFlag::VOLATILE) == flags.Get(tFlag::VOLATILE)) 
    161161  { 
     
    182182  } 
    183183 
    184   FINROC_LOG_PRINT_TO(port_creation_list, DEBUG_VERBOSE_1, "Creating port ", name, " in IOVector ", io_vector.GetQualifiedLink()); 
     184  FINROC_LOG_PRINT_TO(port_creation_list, DEBUG_VERBOSE_1, "Creating port ", name, " in IOVector ", io_vector); 
    185185  core::tAbstractPort* created_port = core::tPortFactory::CreatePort(name, io_vector, type, flags); 
    186186  if (created_port != NULL) 
  • tStandardCreateModuleAction.h

    r65 r90  
    114114  virtual const tConstructorParameters* GetParameterTypes() const override 
    115115  { 
    116     return NULL; 
     116    return nullptr; 
     117  } 
     118 
     119  virtual bool IsDeprecated() const override 
     120  { 
     121    return Tdeprecated; 
    117122  } 
    118123 
Note: See TracChangeset for help on using the changeset viewer.