Changeset 134:4bc25c8cea06 in finroc_plugins_runtime_construction
- Timestamp:
- 27.04.2020 05:59:58 (4 years ago)
- Branch:
- 17.03
- Children:
- 135:c8f6a95b501e, 136:f79534c8ea55
- Phase:
- public
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
tEditableInterfaces.cpp
r126 r134 114 114 } 115 115 116 core::tPortGroup& tEditableInterfaces::LoadInterfacePorts(const rrlib::xml::tNode& node )116 core::tPortGroup& tEditableInterfaces::LoadInterfacePorts(const rrlib::xml::tNode& node, bool mark_created_ports_finstructed, const tOrigin* origin) 117 117 { 118 118 std::string name = node.GetStringAttribute("name"); … … 121 121 if (name == interface.first->GetName()) 122 122 { 123 tPortCreationList port_creation_list(*interface.first, interface.first->GetDefaultPortFlags(), interface.second );123 tPortCreationList port_creation_list(*interface.first, interface.first->GetDefaultPortFlags(), interface.second, mark_created_ports_finstructed, origin); 124 124 node >> port_creation_list; 125 125 return *interface.first; -
tEditableInterfaces.h
r109 r134 86 86 public: 87 87 88 typedef tPortCreationList::tOrigin tOrigin; 89 88 90 /*! Listener notified whenever editable interfaces are changed */ 89 91 class tListener … … 115 117 * 116 118 * \param node XML node to load ports from 119 * \param mark_created_ports_finstructed Whether to flag created ports as 'finstructed'. Only such ports are saved to XML file - and show up in interface editing dialog in finstruct. 120 * \param origin Origin for which to create and manage ports (all ports that do no match origin are not touched) 117 121 * \return Interface whose ports were updated 118 122 * 119 123 * \throw Throws different kinds of std::exceptions if loading fails 120 124 */ 121 core::tPortGroup& LoadInterfacePorts(const rrlib::xml::tNode& node );125 core::tPortGroup& LoadInterfacePorts(const rrlib::xml::tNode& node, bool mark_created_ports_finstructed = true, const tOrigin* origin = nullptr); 122 126 123 127 /*! -
tFinstructable.cpp
r132 r134 45 45 #include "plugins/runtime_construction/tEditableInterfaces.h" 46 46 #include "plugins/runtime_construction/dynamic_loading.h" 47 #include "plugins/runtime_construction/tConstructorCreateModuleAction.h" 47 48 48 49 //---------------------------------------------------------------------- … … 73 74 //---------------------------------------------------------------------- 74 75 76 namespace 77 { 78 79 /*! We do not want to have this prefix in XML file names, as this will not be found when a system installation is used */ 80 const char* cUNWANTED_XML_FILE_PREFIX = "sources/cpp/"; 81 82 /*! Characters that are not escaped in path URIs */ 83 const char* cUNENCODED_RESERVED_CHARACTERS_PATH = "!$&'()*+,;= @"; 84 85 /*! Current version of file format (YYMM) */ 86 const uint cVERSION = 1703; 87 75 88 //---------------------------------------------------------------------- 76 89 // Implementation … … 78 91 79 92 /*! Thread currently saving finstructable group */ 80 staticrrlib::thread::tThread* saving_thread = nullptr;93 rrlib::thread::tThread* saving_thread = nullptr; 81 94 82 95 /*! Temporary variable for saving: .so files that should be loaded prior to instantiating this group */ 83 st atic std::set<tSharedLibrary> dependencies_tmp;96 std::set<tSharedLibrary> dependencies_tmp; 84 97 85 98 /*! Loaded finroc libraries at startup */ 86 static std::set<tSharedLibrary> startup_loaded_finroc_libs; 87 88 /*! We do not want to have this prefix in XML file names, as this will not be found when a system installation is used */ 89 static const char* cUNWANTED_XML_FILE_PREFIX = "sources/cpp/"; 90 91 /*! Characters that are not escaped in path URIs */ 92 static const char* cUNENCODED_RESERVED_CHARACTERS_PATH = "!$&'()*+,;= @"; 93 94 /*! Current version of file format (YYMM) */ 95 static const uint cVERSION = 1703; 96 97 static rrlib::uri::tPath ReplaceInterfaceInPath(const rrlib::uri::tPath& path, const std::string& new_interface) 99 std::set<tSharedLibrary> startup_loaded_finroc_libs; 100 101 102 rrlib::uri::tPath ReplaceInterfaceInPath(const rrlib::uri::tPath& path, const std::string& new_interface) 98 103 { 99 104 if (path.Size() < 2) … … 109 114 return rrlib::uri::tPath(path.IsAbsolute(), path_components.begin(), path_components.end()); 110 115 } 116 117 /*! Specialized tFinstructable class to realize include mechanism */ 118 class tIncludeFinstructable : public tFinstructable 119 { 120 public: 121 /*! 122 * Root framework element that this annotation belongs to 123 * Optional setting that overrides element that annotation is attached to 124 */ 125 core::tFrameworkElement* root_framework_element = nullptr; 126 std::string xml_file; 127 core::tFrameworkElement* origin = nullptr; 128 129 tIncludeFinstructable() : tFinstructable(xml_file) 130 {} 131 }; 132 133 // Returns tIncludeFinstructable if 'finstructable' is one - otherwise nullptr 134 tIncludeFinstructable* IncludeFinstructable(tFinstructable* finstructable) 135 { 136 return typeid(*finstructable) == typeid(tIncludeFinstructable) ? static_cast<tIncludeFinstructable*>(finstructable) : nullptr; 137 } 138 const tIncludeFinstructable* IncludeFinstructable(const tFinstructable* finstructable) 139 { 140 return typeid(*finstructable) == typeid(tIncludeFinstructable) ? static_cast<const tIncludeFinstructable*>(finstructable) : nullptr; 141 } 142 143 144 /*! Framework element with create action for inclusion of finstructable XML files */ 145 class tIncludeElement : public core::tFrameworkElement 146 { 147 public: 148 tIncludeElement(core::tFrameworkElement* parent, const std::string& name, const std::string& xml_file) : 149 tFrameworkElement(GetIncludesParent(parent, true), xml_file), 150 xml_file(xml_file) 151 { 152 tFinstructable::Include(*parent, xml_file, this); 153 } 154 155 std::string xml_file; 156 157 void OnManagedDelete() override 158 { 159 // Remove the whole included structure 160 auto parent = GetParent(); 161 parent = parent ? parent->GetParent() : parent; 162 if (parent && parent->IsReady()) 163 { 164 for (auto it = parent->SubElementsBegin(); it != parent->SubElementsEnd(); ++it) 165 { 166 tOriginDataAnnotation* annotation = it->GetAnnotation<tOriginDataAnnotation>(); 167 if (annotation && annotation->Data().origin == this) 168 { 169 it->ManagedDelete(); 170 } 171 } 172 } 173 } 174 175 static core::tFrameworkElement* GetIncludesParent(core::tFrameworkElement* parent, bool create_if_it_does_not_exist) 176 { 177 auto result = parent->GetChild("Includes"); 178 if ((!result) && create_if_it_does_not_exist) 179 { 180 result = new core::tFrameworkElement(parent, "Includes"); 181 result->Init(); 182 } 183 return result; 184 } 185 }; 186 187 tConstructorCreateModuleAction<tIncludeElement, std::string> cINCLUDE_CREATE_ACTION("Include", "File"); 188 189 190 bool HasNonDefaultFinstructInfo(const parameters::internal::tParameterInfo& info) 191 { 192 for (auto & setting : info.Settings()) 193 { 194 if (setting.high_precedence && setting.origin == nullptr) 195 { 196 return true; 197 } 198 } 199 return false; 200 } 201 202 } 203 111 204 112 205 tFinstructable::tFinstructable(const std::string& xml_file) : … … 168 261 } 169 262 263 core::tFrameworkElement* tFinstructable::GetFrameworkElement() const 264 { 265 auto include_instance = IncludeFinstructable(this); 266 return include_instance ? include_instance->root_framework_element : this->GetAnnotated<core::tFrameworkElement>(); 267 } 268 170 269 std::string tFinstructable::GetLogDescription() const 171 270 { … … 187 286 } 188 287 return s; 288 } 289 290 void tFinstructable::Include(core::tFrameworkElement& parent, const std::string& xml_file, core::tFrameworkElement* origin) 291 { 292 tIncludeFinstructable temp_finstructable; 293 temp_finstructable.xml_file = xml_file; 294 temp_finstructable.root_framework_element = &parent; 295 temp_finstructable.origin = origin; 296 temp_finstructable.LoadXml(); 189 297 } 190 298 … … 227 335 } 228 336 created = action.CreateModule(parent, name, spl); 229 SetFinstructed(*created, action, spl); 337 tOriginData data; 338 auto include_instance = IncludeFinstructable(this); 339 if (include_instance && include_instance->origin) 340 { 341 data.origin = include_instance->origin; 342 SetFinstructed(*created, action, spl, data); 343 } 344 else if (!include_instance) 345 { 346 SetFinstructed(*created, action, spl, data); 347 } 230 348 if (parameters) 231 349 { … … 273 391 else 274 392 { 393 auto include_instance = IncludeFinstructable(this); 394 bool high_precendence = include_instance == nullptr; 395 auto origin = include_instance ? include_instance->origin : nullptr; 275 396 if (outermost_group && node.HasAttribute("cmdline") && (!IsResponsibleForConfigFileConnections(parameter_port))) 276 397 { 277 pi->SetCommandLineOption(node.GetStringAttribute("cmdline") );398 pi->SetCommandLineOption(node.GetStringAttribute("cmdline"), high_precendence, origin); 278 399 } 279 400 else 280 401 { 281 pi->Deserialize(node, true, outermost_group);402 pi->Deserialize(node, high_precendence, outermost_group, origin); 282 403 } 283 404 try … … 295 416 { 296 417 { 418 auto include_instance = IncludeFinstructable(this); 419 tOriginData origin_data; 420 if (include_instance && include_instance->origin) 421 { 422 origin_data.origin = include_instance->origin; 423 } 424 297 425 rrlib::thread::tLock lock2(core::tRuntimeEnvironment::GetInstance().GetStructureMutex()); 298 426 try … … 359 487 Instantiate(*node, GetFrameworkElement()); 360 488 } 489 if (name == "include") 490 { 491 std::string file; 492 try 493 { 494 file = node->GetStringAttribute("file"); 495 auto created = new tIncludeElement(this->GetFrameworkElement(), file, file); 496 origin_data.order = std::chrono::steady_clock::now().time_since_epoch().count(); 497 if (!include_instance) 498 { 499 created->SetFlag(tFlag::FINSTRUCTED); 500 } 501 created->EmplaceAnnotation<tOriginDataAnnotation>(origin_data); 502 created->Init(); 503 } 504 catch (const std::exception& e) 505 { 506 FINROC_LOG_PRINT(ERROR, "Including ", file, " failed: ", e); 507 } 508 } 361 509 } 362 510 … … 373 521 try 374 522 { 375 core::tPortGroup& loaded_interface = editable_interfaces->LoadInterfacePorts(*node); 523 auto include_instance = IncludeFinstructable(this); 524 core::tPortGroup& loaded_interface = editable_interfaces->LoadInterfacePorts(*node, !include_instance, include_instance ? include_instance->origin : nullptr); 376 525 377 526 // Move RPC port to suitable interfaces when loading legacy files … … 418 567 } 419 568 } 420 else if (name == "element" )569 else if (name == "element" || name == "include") 421 570 { 422 571 // already instantiated … … 443 592 destination_uri_parsed.path = rrlib::uri::tPath(destination_string); 444 593 } 445 core::tUriConnectOptions connect_options(core::tConnectionFlag::FINSTRUCTED); 594 core::tUriConnectOptions connect_options; 595 connect_options.flags.Set(core::tConnectionFlag::FINSTRUCTED, !static_cast<bool>(include_instance)); // TODO attach origin data to connectors also 446 596 if (node->HasAttribute("flags")) 447 597 { … … 713 863 bool is_responsible_for_parameter_links = IsResponsibleForConfigFileConnections(*port); 714 864 715 if (info && info->HasNonDefaultFinstructInfo() && (is_responsible_for_parameter_links || (outermost_group && info->GetCommandLineOption().length())))865 if (info && HasNonDefaultFinstructInfo(*info) && (is_responsible_for_parameter_links || (outermost_group && info->GetCommandLineOption().length()))) 716 866 { 717 867 // Save Parameter … … 725 875 else 726 876 { 727 info->Serialize(parameter_node, true, outermost_group );877 info->Serialize(parameter_node, true, outermost_group, nullptr); 728 878 } 729 879 result = true; … … 1057 1207 void tFinstructable::SerializeChildren(rrlib::xml::tNode& node, tFrameworkElement& current) 1058 1208 { 1059 for (auto child = current.ChildrenBegin(); child != current.ChildrenEnd(); ++child) 1060 { 1209 std::vector<std::pair<tOriginData, core::tFrameworkElement*>> children_to_serialize; 1210 std::vector<core::tFrameworkElement*> elements_to_scan = { ¤t }; 1211 auto include_parent = tIncludeElement::GetIncludesParent(¤t, false); 1212 if (include_parent) 1213 { 1214 elements_to_scan.push_back(include_parent); 1215 } 1216 for (auto element_to_scan : elements_to_scan) 1217 { 1218 for (auto child = element_to_scan->ChildrenBegin(); child != element_to_scan->ChildrenEnd(); ++child) 1219 { 1220 auto origin_data = child->GetAnnotation<tOriginDataAnnotation>(); 1221 if (child->IsReady() && child->GetFlag(tFlag::FINSTRUCTED) && origin_data && (child->GetAnnotation<parameters::internal::tStaticParameterList>() || typeid(*child) == typeid(tIncludeElement))) 1222 { 1223 children_to_serialize.emplace_back(origin_data->Data(), &*child); 1224 } 1225 } 1226 } 1227 1228 std::sort(children_to_serialize.begin(), children_to_serialize.end()); 1229 1230 for (auto & child_entry : children_to_serialize) 1231 { 1232 auto child = child_entry.second; 1233 1234 if (typeid(*child) == typeid(tIncludeElement)) 1235 { 1236 rrlib::xml::tNode& n = node.AddChildNode("include"); 1237 n.SetAttribute("file", static_cast<tIncludeElement*>(child)->xml_file); 1238 continue; 1239 } 1240 1061 1241 parameters::internal::tStaticParameterList* spl = child->GetAnnotation<parameters::internal::tStaticParameterList>(); 1062 1242 tConstructorParameters* cps = child->GetAnnotation<tConstructorParameters>(); 1063 if (child->IsReady() && child->GetFlag(tFlag::FINSTRUCTED)) 1064 { 1065 // serialize framework element 1066 rrlib::xml::tNode& n = node.AddChildNode("element"); 1067 n.SetAttribute("name", child->GetName()); 1068 tCreateFrameworkElementAction* cma = tCreateFrameworkElementAction::GetConstructibleElements()[spl->GetCreateAction()]; 1069 n.SetAttribute("group", cma->GetModuleGroup().ToString()); 1070 //if (boost::ends_with(cma->GetModuleGroup(), ".so")) 1071 //{ 1072 AddDependency(cma->GetModuleGroup()); 1073 //} 1074 n.SetAttribute("type", cma->GetName()); 1075 if (cps != nullptr) 1076 { 1077 rrlib::xml::tNode& pn = n.AddChildNode("constructor"); 1078 cps->Serialize(pn, true); 1079 } 1080 if (spl != nullptr) 1081 { 1082 rrlib::xml::tNode& pn = n.AddChildNode("parameters"); 1083 spl->Serialize(pn, true); 1084 } 1085 1086 // serialize its children 1087 if (!child->GetFlag(tFlag::FINSTRUCTABLE_GROUP)) 1088 { 1089 SerializeChildren(n, *child); 1090 } 1091 } 1092 } 1093 } 1094 1095 void tFinstructable::SetFinstructed(tFrameworkElement& fe, tCreateFrameworkElementAction& create_action, tConstructorParameters* params) 1243 1244 // serialize framework element 1245 rrlib::xml::tNode& n = node.AddChildNode("element"); 1246 n.SetAttribute("name", child->GetName()); 1247 assert(spl); 1248 tCreateFrameworkElementAction* cma = tCreateFrameworkElementAction::GetConstructibleElements()[spl->GetCreateAction()]; 1249 n.SetAttribute("group", cma->GetModuleGroup().ToString()); 1250 //if (boost::ends_with(cma->GetModuleGroup(), ".so")) 1251 //{ 1252 AddDependency(cma->GetModuleGroup()); 1253 //} 1254 n.SetAttribute("type", cma->GetName()); 1255 if (cps) 1256 { 1257 rrlib::xml::tNode& pn = n.AddChildNode("constructor"); 1258 cps->Serialize(pn, true); 1259 } 1260 if (spl) 1261 { 1262 rrlib::xml::tNode& pn = n.AddChildNode("parameters"); 1263 spl->Serialize(pn, true); 1264 } 1265 1266 // serialize its children 1267 if (!child->GetFlag(tFlag::FINSTRUCTABLE_GROUP)) 1268 { 1269 SerializeChildren(n, *child); 1270 } 1271 } 1272 } 1273 1274 void tFinstructable::SetFinstructed(tFrameworkElement& fe, tCreateFrameworkElementAction& create_action, tConstructorParameters* params, tOriginData origin_data) 1096 1275 { 1097 1276 assert(!fe.GetFlag(tFlag::FINSTRUCTED) && (!fe.IsReady())); … … 1106 1285 } 1107 1286 } 1108 fe.SetFlag(tFlag::FINSTRUCTED); 1287 bool include_finstructed = origin_data.origin; 1288 fe.SetFlag(tFlag::FINSTRUCTED, (!include_finstructed)); 1109 1289 if (params) 1110 1290 { 1111 1291 fe.AddAnnotation<tConstructorParameters>(*params); 1112 1292 } 1293 1294 origin_data.order = std::chrono::steady_clock::now().time_since_epoch().count(); 1295 fe.EmplaceAnnotation<tOriginDataAnnotation>(origin_data); 1113 1296 } 1114 1297 -
tFinstructable.h
r90 r134 54 54 //---------------------------------------------------------------------- 55 55 #include "plugins/runtime_construction/tCreateFrameworkElementAction.h" 56 #include "plugins/runtime_construction/tOriginData.h" 56 57 57 58 //---------------------------------------------------------------------- … … 116 117 117 118 /*! 119 * "Includes" finstructable XML file: Adds all structure defined in XML file to specified parent element. 120 * Note that the created structure is not marked 'finstructed' (so that saving the main file does not suddenly include all of it). 121 * 122 * \param parent Framework element to add structure to 123 * \param xml_file Finstructable XML file containing structure to add 124 * \param origin Origin (optional). If set, adds tOriginDataAnnotation with this origin to created elements. 125 */ 126 static void Include(core::tFrameworkElement& parent, const std::string& xml_file, core::tFrameworkElement* origin = nullptr); 127 128 /*! 118 129 * Loads and instantiates contents of xml file 119 130 * … … 145 156 * \param create_action Action with which framework element was created 146 157 * \param params Parameters that module was created with (may be null) 147 */ 148 static void SetFinstructed(core::tFrameworkElement& fe, tCreateFrameworkElementAction& create_action, tConstructorParameters* params); 158 * \param origin_data Origin data to attach (if not set, order will be set to steady_clock time) 159 */ 160 static void SetFinstructed(core::tFrameworkElement& fe, tCreateFrameworkElementAction& create_action, tConstructorParameters* params, tOriginData origin_data = tOriginData()); 149 161 150 162 /*! … … 202 214 * \return Root framework element that this annotation belongs to 203 215 */ 204 core::tFrameworkElement* GetFrameworkElement() const 205 { 206 return this->GetAnnotated<core::tFrameworkElement>(); 207 } 216 core::tFrameworkElement* GetFrameworkElement() const; 208 217 209 218 /*! -
tPortCreationList.cpp
r126 r134 108 108 selectable_create_options(), 109 109 list(), 110 io_vector( NULL),110 io_vector(nullptr), 111 111 flags(tFlags()), 112 ports_flagged_finstructed(true) 112 ports_flagged_finstructed(true), 113 origin(nullptr) 113 114 {} 114 115 115 tPortCreationList::tPortCreationList(core::tFrameworkElement& port_group, tFlags flags, const tPortCreateOptions& selectable_create_options, bool ports_flagged_finstructed ) :116 tPortCreationList::tPortCreationList(core::tFrameworkElement& port_group, tFlags flags, const tPortCreateOptions& selectable_create_options, bool ports_flagged_finstructed, const tOrigin* origin) : 116 117 selectable_create_options(), 117 118 list(), 118 119 io_vector(&port_group), 119 120 flags(flags | (ports_flagged_finstructed ? tFlag::FINSTRUCTED : tFlag::PORT)), 120 ports_flagged_finstructed(ports_flagged_finstructed) 121 ports_flagged_finstructed(ports_flagged_finstructed), 122 origin(origin) 121 123 { 122 124 if (!flags.Get(tFlag::SHARED) && selectable_create_options.Get(tPortCreateOption::SHARED)) … … 133 135 { 134 136 rrlib::thread::tLock lock(io_vector->GetStructureMutex()); 135 CheckPort( NULL, *io_vector, flags, name, dt, create_options, NULL);137 CheckPort(nullptr, *io_vector, flags, name, dt, create_options, nullptr, this->GetSize()); 136 138 } 137 139 … … 139 141 { 140 142 rrlib::thread::tLock lock(io_vector->GetStructureMutex()); 141 std::vector<core::tAbstractPort*>ports1;142 GetPorts(*this->io_vector, ports1, ports_flagged_finstructed );143 std::vector<core::tAbstractPort*>ports2;144 GetPorts(io_vector_, ports2, ports_flagged_finstructed );143 tGetPortsResult ports1; 144 GetPorts(*this->io_vector, ports1, ports_flagged_finstructed, origin); 145 tGetPortsResult ports2; 146 GetPorts(io_vector_, ports2, ports_flagged_finstructed, origin); 145 147 146 148 for (size_t i = 0u; i < ports1.size(); i++) 147 149 { 148 core::tAbstractPort* ap1 = ports1[i] ;149 core::tAbstractPort* ap2 = i < ports2.size() ? ports2[i] : NULL;150 CheckPort(ap2, io_vector_, flags_, ap1->GetName(), ap1->GetDataType(), ToPortCreateOptions(ap1->GetAllFlags(), selectable_create_options), ap1 );150 core::tAbstractPort* ap1 = ports1[i].second; 151 core::tAbstractPort* ap2 = i < ports2.size() ? ports2[i].second : nullptr; 152 CheckPort(ap2, io_vector_, flags_, ap1->GetName(), ap1->GetDataType(), ToPortCreateOptions(ap1->GetAllFlags(), selectable_create_options), ap1, i); 151 153 } 152 154 for (size_t i = ports1.size(); i < ports2.size(); i++) 153 155 { 154 ports2[i] ->ManagedDelete();156 ports2[i].second->ManagedDelete(); 155 157 } 156 158 } 157 159 158 160 void tPortCreationList::CheckPort(core::tAbstractPort* existing_port, core::tFrameworkElement& io_vector, tFlags flags, 159 const std::string& name, rrlib::rtti::tType type, const tPortCreateOptions& create_options, core::tAbstractPort* prototype )161 const std::string& name, rrlib::rtti::tType type, const tPortCreateOptions& create_options, core::tAbstractPort* prototype, size_t index) 160 162 { 161 163 if (existing_port && existing_port->GetName() == name && existing_port->GetDataType() == type && … … 164 166 bool create_output_port = create_options.Get(tPortCreateOption::OUTPUT) || flags.Get(tFlag::OUTPUT_PORT); 165 167 bool create_shared_port = create_options.Get(tPortCreateOption::SHARED) || flags.Get(tFlag::SHARED); 168 auto annotation = existing_port->GetAnnotation<tOriginDataAnnotation>(); 166 169 if (((!selectable_create_options.Get(tPortCreateOption::OUTPUT)) || (existing_port->GetFlag(tFlag::OUTPUT_PORT) == create_output_port)) && 167 ((!selectable_create_options.Get(tPortCreateOption::SHARED)) || (existing_port->GetFlag(tFlag::SHARED) == create_shared_port)) )170 ((!selectable_create_options.Get(tPortCreateOption::SHARED)) || (existing_port->GetFlag(tFlag::SHARED) == create_shared_port)) && annotation) 168 171 { 169 172 // port is as it should be 173 annotation->Data().order = index; // possibly adjust index 170 174 return; 171 175 } … … 186 190 FINROC_LOG_PRINT_TO(port_creation_list, DEBUG_VERBOSE_1, "Creating port ", name, " in IOVector ", io_vector); 187 191 core::tAbstractPort* created_port = core::tPortFactory::CreatePort(name, io_vector, type, flags); 188 if (created_port != NULL) 189 { 192 if (created_port) 193 { 194 tOriginData origin_data; 195 origin_data.origin = origin; 196 origin_data.order = static_cast<tOriginData::tOrder>(index); 197 created_port->EmplaceAnnotation<tOriginDataAnnotation>(origin_data); 190 198 created_port->Init(); 191 199 } … … 196 204 } 197 205 198 void tPortCreationList::GetPorts(const core::tFrameworkElement& elem, std::vector<core::tAbstractPort*>& result, bool finstructed_ports_only)206 void tPortCreationList::GetPorts(const core::tFrameworkElement& elem, tGetPortsResult& result, bool ports_flagged_finstructed, const tOrigin* origin) 199 207 { 200 208 result.clear(); 201 209 for (auto it = elem.ChildPortsBegin(); it != elem.ChildPortsEnd(); ++it) 202 210 { 203 if ((!finstructed_ports_only) || it->GetFlag(tFlag::FINSTRUCTED)) 204 { 205 result.push_back(&(*it)); 206 } 211 tOriginDataAnnotation* origin_annotation = it->GetAnnotation<tOriginDataAnnotation>(); 212 if (origin_annotation && ports_flagged_finstructed == it->GetFlag(tFlag::FINSTRUCTED) && origin_annotation->Data().origin == origin) 213 { 214 result.emplace_back(origin_annotation->Data().order, &(*it)); 215 } 216 } 217 218 std::sort(result.begin(), result.end()); 219 220 size_t expected_index = 0; 221 for (auto & entry : result) 222 { 223 if (static_cast<size_t>(entry.first) != expected_index) 224 { 225 FINROC_LOG_PRINT(WARNING, "Ports do not have expected indices. Adjusting."); 226 expected_index = 0; 227 for (auto & entry : result) 228 { 229 entry.second->GetAnnotation<tOriginDataAnnotation>()->Data().order = expected_index; 230 expected_index++; 231 } 232 break; 233 } 234 expected_index++; 207 235 } 208 236 } … … 215 243 } 216 244 int count = 0; 217 for (auto it = io_vector->ChildrenBegin(); it != io_vector->ChildrenEnd(); ++it) 218 { 219 count++; 245 for (auto it = io_vector->ChildPortsBegin(); it != io_vector->ChildPortsEnd(); ++it) 246 { 247 tOriginDataAnnotation* origin_annotation = it->GetAnnotation<tOriginDataAnnotation>(); 248 if (origin_annotation && ports_flagged_finstructed == it->GetFlag(tFlag::FINSTRUCTED) && origin_annotation->Data().origin == origin) 249 { 250 count++; 251 } 220 252 } 221 253 return count; … … 224 256 void tPortCreationList::InitialSetup(core::tFrameworkElement& managed_io_vector, tFlags port_creation_flags, const tPortCreateOptions& selectable_create_options) 225 257 { 226 assert((io_vector == NULL|| io_vector == &managed_io_vector) && list.empty());258 assert((io_vector == nullptr || io_vector == &managed_io_vector) && list.empty()); 227 259 io_vector = &managed_io_vector; 228 260 flags = port_creation_flags; … … 243 275 { 244 276 stream.WriteByte(list.selectable_create_options.Raw()); 245 if ( list.io_vector == NULL)277 if (!list.io_vector) 246 278 { 247 279 int size = list.list.size(); … … 258 290 { 259 291 rrlib::thread::tLock lock(list.io_vector->GetStructureMutex()); 260 std::vector<core::tAbstractPort*>ports;261 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed );292 tPortCreationList::tGetPortsResult ports; 293 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed, list.origin); 262 294 int size = ports.size(); 263 295 stream.WriteInt(size); 264 296 for (int i = 0; i < size; i++) 265 297 { 266 core::tAbstractPort* p = ports[i] ;298 core::tAbstractPort* p = ports[i].second; 267 299 stream.WriteString(p->GetName()); 268 300 stream.WriteString(p->GetDataType().GetName()); … … 275 307 rrlib::serialization::tInputStream& operator >> (rrlib::serialization::tInputStream& stream, tPortCreationList& list) 276 308 { 277 if ( list.io_vector == NULL)309 if (!list.io_vector) 278 310 { 279 311 list.selectable_create_options = tPortCreateOptions(stream.ReadByte()); … … 292 324 stream.ReadByte(); // skip selectable create options, as this is not defined by finstruct 293 325 size_t size = stream.ReadInt(); 294 std::vector<core::tAbstractPort*>existing_ports;295 list.GetPorts(*list.io_vector, existing_ports, list.ports_flagged_finstructed );326 tPortCreationList::tGetPortsResult existing_ports; 327 list.GetPorts(*list.io_vector, existing_ports, list.ports_flagged_finstructed, list.origin); 296 328 for (size_t i = 0u; i < size; i++) 297 329 { … … 306 338 tPortCreateOptions create_options(stream.ReadByte()); 307 339 308 core::tAbstractPort* existing_port_with_this_name = NULL;340 core::tAbstractPort* existing_port_with_this_name = nullptr; 309 341 for (auto it = existing_ports.begin(); it != existing_ports.end(); ++it) 310 342 { 311 if ( (*it)->GetName() == name)343 if (it->second->GetName() == name) 312 344 { 313 existing_port_with_this_name = *it;345 existing_port_with_this_name = it->second; 314 346 existing_ports.erase(it); 315 347 break; 316 348 } 317 349 } 318 list.CheckPort(existing_port_with_this_name, *list.io_vector, list.flags, name, type, create_options, NULL);350 list.CheckPort(existing_port_with_this_name, *list.io_vector, list.flags, name, type, create_options, nullptr, i); 319 351 } 320 352 … … 322 354 for (size_t i = 0; i < existing_ports.size(); i++) 323 355 { 324 existing_ports[i] ->ManagedDelete();356 existing_ports[i].second->ManagedDelete(); 325 357 } 326 358 } … … 340 372 node.SetAttribute("showOutputSelection", list.selectable_create_options.Get(tPortCreateOption::OUTPUT)); 341 373 } 342 std::vector<core::tAbstractPort*>ports;343 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed );374 tPortCreationList::tGetPortsResult ports; 375 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed, list.origin); 344 376 int size = ports.size(); 345 377 for (int i = 0; i < size; i++) 346 378 { 347 core::tAbstractPort* p = ports[i] ;379 core::tAbstractPort* p = ports[i].second; 348 380 rrlib::xml::tNode& child = node.AddChildNode("port"); 349 381 child.SetAttribute("name", p->GetName()); … … 370 402 371 403 rrlib::thread::tLock lock(list.io_vector->GetStructureMutex()); 372 if ( !list.ports_flagged_finstructed)404 if ((!list.ports_flagged_finstructed) && node.HasAttribute("showOutputSelection")) 373 405 { 374 406 list.selectable_create_options.Set(tPortCreateOption::OUTPUT, node.GetBoolAttribute("showOutputSelection")); 375 407 } 376 std::vector<core::tAbstractPort*>ports;377 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed );408 tPortCreationList::tGetPortsResult ports; 409 list.GetPorts(*list.io_vector, ports, list.ports_flagged_finstructed, list.origin); 378 410 size_t i = 0u; 379 411 std::set<std::string> missing_types; 380 412 for (rrlib::xml::tNode::const_iterator port = node.ChildrenBegin(); port != node.ChildrenEnd(); ++port, ++i) 381 413 { 382 core::tAbstractPort* ap = i < ports.size() ? ports[i] : NULL;414 core::tAbstractPort* ap = i < ports.size() ? ports[i].second : nullptr; 383 415 std::string port_name = port->Name(); 384 416 assert(port_name.compare("port") == 0); … … 408 440 } 409 441 410 list.CheckPort(ap, *list.io_vector, list.flags, port->GetStringAttribute("name"), dt, create_options, NULL);442 list.CheckPort(ap, *list.io_vector, list.flags, port->GetStringAttribute("name"), dt, create_options, nullptr, i); 411 443 } 412 444 for (; i < ports.size(); i++) 413 445 { 414 ports[i] ->ManagedDelete();446 ports[i].second->ManagedDelete(); 415 447 } 416 448 -
tPortCreationList.h
r109 r134 48 48 //---------------------------------------------------------------------- 49 49 #include "plugins/runtime_construction/tDataTypeReference.h" 50 #include "plugins/runtime_construction/tOriginData.h" 50 51 51 52 //---------------------------------------------------------------------- … … 102 103 public: 103 104 105 typedef tOriginData::tOrigin tOrigin; 106 107 104 108 tPortCreationList(); 105 109 … … 109 113 * \param selectable_create_options Which creation options should be visible and selectable in finstruct? 110 114 * \param ports_flagged_finstructed Deal only with ports flagged finstructed? 115 * \param origin Origin for which to create and manage ports (all ports that do no match origin are not touched) 111 116 */ 112 117 tPortCreationList(core::tFrameworkElement& port_group, tFlags flags, 113 const tPortCreateOptions& selectable_create_options, bool ports_flagged_finstructed = true );118 const tPortCreateOptions& selectable_create_options, bool ports_flagged_finstructed = true, const tOrigin* origin = nullptr); 114 119 115 120 tPortCreationList(tPortCreationList &&) = delete; … … 170 175 friend const rrlib::xml::tNode& operator >> (const rrlib::xml::tNode& node, tPortCreationList& list); 171 176 177 typedef std::vector<std::pair<tOriginData::tOrder, core::tAbstractPort*>> tGetPortsResult; 178 172 179 /*! 173 180 * Entry in list … … 211 218 */ 212 219 bool ports_flagged_finstructed; 220 221 /*! Origin for which to create and manage ports (all ports that do no match origin are not touched) */ 222 const tOrigin* origin; 213 223 214 224 /*! … … 222 232 * \param create_options Selected create options for port 223 233 * \param prototype Port prototype (only interesting for listener) 234 * \param index Index for origin data 224 235 */ 225 236 void CheckPort(core::tAbstractPort* existing_port, core::tFrameworkElement& io_vector, tFlags flags, const std::string& name, 226 rrlib::rtti::tType type, const tPortCreateOptions& create_options, core::tAbstractPort* prototype );227 228 /*! 229 * Returns all child ports of specified framework element 237 rrlib::rtti::tType type, const tPortCreateOptions& create_options, core::tAbstractPort* prototype, size_t index); 238 239 /*! 240 * Returns all child ports of specified framework element with specified origin 230 241 * 231 242 * \param elem Framework Element 232 243 * \param result List containing result 233 * \param finstructed_ports_only Only retrieve finstructed ports? 234 */ 235 static void GetPorts(const core::tFrameworkElement& elem, std::vector<core::tAbstractPort*>& result, bool finstructed_ports_only); 244 * \param ports_flagged_finstructed Whether to return ports with FINSTRUCTED flag set - or without 245 * \param origin Origin ports must have 246 */ 247 static void GetPorts(const core::tFrameworkElement& elem, tGetPortsResult& result, bool ports_flagged_finstructed, const tOrigin* origin); 236 248 }; 237 249
Note: See TracChangeset
for help on using the changeset viewer.