Changeset 17:1f553643f4a9 in finroc_plugins_composite_ports
- Timestamp:
- 24.08.2020 00:42:48 (2 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
examples/example.finroc
r10 r17 25 25 <edge src="Aggregator/Sensor Output/Fancy 1" dest="Group With User/Sensor Input/I%2FO Interconnected"/> 26 26 <edge src="Aggregator/Sensor Output/Fancy 2" dest="Group With User/Sensor Input/Fancy 2"/> 27 <edge src="Aggregator/Sensor Output/Fancy Partial Out" dest="Group With User/Sensor Input/Fancy Partial"/> 27 28 <edge src="Aggregator/Sensor Output/Input Output Interface 4" dest="Group With User/Sensor Input/I%2FO Interface 3"/> 28 29 <edge src="Aggregator/Sensor Output/Input Output Interface 5" dest="Group With User/Sensor Input/I%2FO Interface 4"/> 29 30 <edge src="Aggregator/Sensor Output/Simple 1" dest="Group With User/Sensor Input/Simple 3"/> 30 31 <edge src="Aggregator/Sensor Output/Simple 4" dest="Group With User/Sensor Input/Simple 4"/> 32 <edge src="Group With User/Controller Output/Fancy Partial" dest="Aggregator Coded/Controller Input/Fancy 2"/> 31 33 </Finstructable> -
examples/gAggregator.xml
r9 r17 14 14 <port name="Fancy 2" type="finroc.composite_ports.examples.interfaces.Fancy"/> 15 15 <port name="Plain Sensor Output" type="double"/> 16 <port name="Fancy Partial Out" type="finroc.composite_ports.examples.interfaces.Fancy (partial)"/> 17 </interface> 18 <interface name="Controller Input"> 19 <port name="Fancy Partial In" type="finroc.composite_ports.examples.interfaces.Fancy (partial)"/> 16 20 </interface> 17 21 <interface name="Parameters"> … … 28 32 </parameters> 29 33 </element> 34 <edge src="Controller Input/Fancy Partial In" dest="Module 1/Controller Input/Fancy Partial"/> 30 35 <edge src="Module 1/Sensor Output/Fancy" dest="Sensor Output/Fancy 1"/> 36 <edge src="Module 1/Sensor Output/Fancy" dest="Sensor Output/Fancy Partial Out"/> 31 37 <edge src="Module 1/Sensor Output/I%2FO Interface 1" dest="Sensor Output/Input Output Interface 1"/> 32 38 <edge src="Module 1/Sensor Output/I%2FO Interface 2" dest="Sensor Output/Input Output Interface 2"/> -
examples/gAggregatorCoded.cpp
r9 r17 80 80 tSenseControlGroup(parent, name, structure_config_file, false), 81 81 fancy_1("Fancy 1", this), 82 fancy_2("Fancy 2", this) 82 fancy_2("Fancy 2", this), 83 fancy_partial_in("Fancy Partial", &GetControllerInputs()), 84 fancy_partial_out("Fancy Partial", &GetSensorOutputs()) 83 85 { 84 86 auto module_1 = new mInterfaceImplementer1(this, "Module 1"); … … 93 95 composite_ports::ConnectFirstChildComponentInterface(*this, fancy_1); 94 96 module_2->fancy.ConnectTo(fancy_2); 97 98 module_1->fancy_partial_out.ConnectTo(fancy_partial_out); 99 module_1->fancy_partial_in.ConnectTo(fancy_1); 95 100 } 96 101 -
examples/gAggregatorCoded.h
r9 r17 84 84 std::vector<interfaces::tInputOutput<tSensorOutput>> input_output_interfaces; 85 85 interfaces::tFancy<tSensorOutput> fancy_1, fancy_2; 86 interfaces::tFancy<tSensorOutput> fancy_partial_in, fancy_partial_out; 86 87 87 88 tSensorOutput<double> so_plain_sensor_output; -
examples/gUser.xml
r10 r17 13 13 <port name="Simple 4" type="finroc.composite_ports.examples.interfaces.Simple"/> 14 14 <port name="I/O Interconnected" type="finroc.composite_ports.examples.interfaces.InputOutput"/> 15 <port name="Fancy Partial" type="finroc.composite_ports.examples.interfaces.Fancy (partial)"/> 16 </interface> 17 <interface name="Controller Output"> 18 <port name="Fancy Partial" type="finroc.composite_ports.examples.interfaces.Fancy (partial)"/> 15 19 </interface> 16 20 <element name="Interface User" group="finroc_plugins_composite_ports_example" type="InterfaceUser"> 17 21 <parameters/> 18 22 </element> 23 <edge src="Interface User/Controller Output/Fancy Partial" dest="Controller Output/Fancy Partial"/> 19 24 <edge src="Sensor Input/Fancy 1" dest="Interface User/Sensor Input/Fancy 1"/> 20 25 <edge src="Sensor Input/Fancy 2" dest="Interface User/Sensor Input/Fancy 2"/> 26 <edge src="Sensor Input/Fancy 2" dest="Interface User/Sensor Input/Fancy Partial"/> 21 27 <edge src="Sensor Input/I%2FO Interface 1" dest="Interface User/Sensor Input/I%2FO Interface 1"/> 22 28 <edge src="Sensor Input/I%2FO Interface 2" dest="Interface User/Sensor Input/I%2FO Interface 2"/> -
examples/interfaces/tInputOutput.h
r9 r17 81 81 public: 82 82 83 typedef composite_ports::tInterface<TSensorPort> tBase; 84 83 85 template <typename T> 84 86 using tControllerPort = typename composite_ports::port_relation::tCounterPart<TSensorPort>::template type<T>; … … 94 96 template <typename TParent> 95 97 tInputOutput(const std::string& name, TParent parent, const rrlib::rtti::tType& interface_type = cINPUT_OUTPUT_TYPE) : 96 composite_ports::tInterface<TSensorPort>(interface_type, parent, name),98 tBase(interface_type, parent, name, tBase::tPrimaryPortType::SENSOR_PORT), 97 99 status("Status", this), 98 100 measured_data("Measured Data", this), -
examples/mInterfaceImplementer1.cpp
r9 r17 77 77 so_simple_1("Simple 1", this), 78 78 so_simple_2("Simple 2", this), 79 fancy("Fancy", this) 79 fancy("Fancy", this), 80 fancy_partial_in("Fancy Partial", &GetControllerInputs()), 81 fancy_partial_out("Fancy Partial", &GetSensorOutputs()) 80 82 { 81 83 so_simple_1.id.SetDefault("George"); -
examples/mInterfaceImplementer1.h
r9 r17 42 42 // External includes (system with <>, local with "") 43 43 //---------------------------------------------------------------------- 44 #include "core/tRuntimeEnvironment.h" 44 45 45 46 //---------------------------------------------------------------------- … … 85 86 86 87 interfaces::tFancy<tSensorOutput> fancy; 88 interfaces::tFancy<tSensorOutput> fancy_partial_in, fancy_partial_out; 87 89 88 90 tSensorOutput<double> so_plain_sensor_output; -
examples/mInterfaceUser.cpp
r9 r17 74 74 //---------------------------------------------------------------------- 75 75 mInterfaceUser::mInterfaceUser(core::tFrameworkElement *parent, const std::string &name) : 76 tSenseControlModule(parent, name, false) 76 tSenseControlModule(parent, name, false), 77 fancy_partial_in("Fancy Partial", &GetSensorInputs()), 78 fancy_partial_out("Fancy Partial", &GetControllerOutputs()) 77 79 { 78 80 this->ResizePortVector(si_simple, 4, "Simple "); -
examples/mInterfaceUser.h
r9 r17 83 83 std::vector<interfaces::tFancy<tSensorInput>> fancy_vector; 84 84 85 interfaces::tFancy<tSensorInput> fancy_partial_in, fancy_partial_out; 86 85 87 //---------------------------------------------------------------------- 86 88 // Public methods and typedefs -
internal/tGenericPortType.h
r16 r17 89 89 90 90 tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 91 if (!parent_backend) 92 { 93 return; 94 } 91 95 static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), rest...); 92 96 } … … 117 121 118 122 tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 123 if (!parent_backend) 124 { 125 return; 126 } 119 127 core::tPortWrapperBase::tConstructorArguments<data_ports::tPortCreationInfo<T>> creation_info(name, parent_backend, rrlib::rtti::tDataType<T>(), parent_backend->GetDefaultPortFlags(true), rest...); 120 128 assert(creation_info.data_type); … … 151 159 152 160 tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 161 if (!parent_backend) 162 { 163 return; 164 } 165 153 166 // Create port instance via factory 154 167 core::tFrameworkElementFlags extra_flags = parent_backend->CreateOutputPort(Tprimary_interface_relations) ? (core::tFrameworkElementFlag::OUTPUT_PORT | core::tFrameworkElementFlag::EMITS_DATA) : (core::tFrameworkElementFlag::ACCEPTS_DATA | core::tFrameworkElementFlag::PORT); … … 184 197 185 198 tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 199 if (!parent_backend) 200 { 201 return; 202 } 203 186 204 static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), std::forward<TRest>(rest)...); 187 205 } -
internal/tInterfaceTypeInfo.cpp
r14 r17 91 91 } 92 92 93 tInterfaceTypeInfo::tCreateFunction create_function = static_cast<const tInterfaceTypeInfo&>(type.SharedTypeInfo()).CreateFunction(); 93 auto& interface_type_info = static_cast<const tInterfaceTypeInfo&>(type.SharedTypeInfo()); 94 tInterfaceTypeInfo::tCreateFunction create_function = interface_type_info.CreateFunction(); 94 95 if (!create_function) 95 96 { 96 97 throw std::runtime_error("No create action registered for interface type (typically done in rtti.cpp)"); 98 } 99 100 tInterfaceBase::tScopedExtraConstructorParameters extra_contructor_parameters; 101 if (interface_type_info.GetFullType() != type) 102 { 103 extra_contructor_parameters = tInterfaceBase::tScopedExtraConstructorParameters::Get(); 104 extra_contructor_parameters->partial_interface = true; 97 105 } 98 106 … … 118 126 } 119 127 128 tInterfaceTypeInfo::tInterfaceTypeInfo(const rrlib::rtti::detail::tTypeInfo* type_info, tCreateFunction create_function, int auto_registered, bool create_partial_type, const std::type_info& partial_type_info) : 129 tSharedInfo(type_info, GenerateName(type_info->std_type_info.name()), nullptr, 0), 130 create_function(create_function) 131 { 132 this->type_info_full = type_info; 133 if (create_partial_type) 134 { 135 this->type_info_partial = new rrlib::rtti::detail::tTypeInfo(partial_type_info, type_info->type_traits, type_info, type_info->element_type, nullptr, type_info->size); 136 auto partial_shared_info = new tInterfaceTypeInfo(this->type_info_partial, create_function, rrlib::util::tManagedConstCharPointer((rrlib::rtti::tType(type_info).GetName() + " (partial)").c_str(), true)); 137 this->type_info_partial->shared_info = partial_shared_info; 138 partial_shared_info->type_info_full = type_info; 139 partial_shared_info->type_info_partial = this->type_info_partial; 140 assert(GetPartialType().GetHandle() == GetFullType().GetHandle() + 1); 141 } 142 } 143 144 tInterfaceTypeInfo::~tInterfaceTypeInfo() 145 { 146 if (this->type_info_partial && this->type_info_full->shared_info == this) 147 { 148 tInterfaceTypeInfo* shared_info_partial = static_cast<tInterfaceTypeInfo*>(this->type_info_partial->shared_info); 149 delete shared_info_partial; 150 delete this->type_info_partial; 151 } 152 } 153 120 154 rrlib::util::tManagedConstCharPointer tInterfaceTypeInfo::GenerateName(const char* rtti_name) 121 155 { -
internal/tInterfaceTypeInfo.h
r0 r17 86 86 typedef tInterfaceBase(*tCreateFunction)(const std::string& name, core::tPortGroup* parent); 87 87 88 tInterfaceTypeInfo(const rrlib::rtti::detail::tTypeInfo* type_info, tCreateFunction create_function, int auto_registered) : 89 tSharedInfo(type_info, GenerateName(type_info->std_type_info.name()), nullptr, 0), 88 tInterfaceTypeInfo(const rrlib::rtti::detail::tTypeInfo* type_info, tCreateFunction create_function, int auto_registered, bool create_partial_type, const std::type_info& partial_type_info); 89 90 tInterfaceTypeInfo(const rrlib::rtti::detail::tTypeInfo* type_info, tCreateFunction create_function, rrlib::util::tManagedConstCharPointer name) : 91 tSharedInfo(type_info, std::move(name), nullptr, 0), 90 92 create_function(create_function) 91 93 {} 94 95 ~tInterfaceTypeInfo(); 92 96 93 97 /*! … … 110 114 } 111 115 116 /*! 117 * \return Full type of interface 118 */ 119 rrlib::rtti::tType GetFullType() const 120 { 121 return rrlib::rtti::tType(type_info_full); 122 } 123 124 /*! 125 * \return Partial type in case this interface type has one 126 */ 127 rrlib::rtti::tType GetPartialType() const 128 { 129 return type_info_partial ? rrlib::rtti::tType(type_info_partial) : rrlib::rtti::tType(); 130 } 131 112 132 //---------------------------------------------------------------------- 113 133 // Private fields and methods … … 117 137 /*! Create function for this interface type (generic instance) */ 118 138 tCreateFunction create_function; 139 140 /*! Pointer to partial type info in case this interface type has a partial type info (created and deleted by this class) */ 141 rrlib::rtti::detail::tTypeInfo* type_info_partial = nullptr; 142 143 /*! Pointer to full type info this interface type has a partial type info */ 144 const rrlib::rtti::detail::tTypeInfo* type_info_full = nullptr; 119 145 120 146 /*! Generates interface type name from rtti name */ -
internal/tTypeInfo.h
r10 r17 55 55 { 56 56 57 //---------------------------------------------------------------------- 58 // Forward declarations / typedefs / enums 59 //---------------------------------------------------------------------- 60 57 61 template <template <typename> class TPrimaryPort> 58 62 class tInterface; … … 76 80 static constexpr const rrlib::rtti::detail::tTypeInfo& cTYPE_INFO = rrlib::rtti::detail::tTypeInfo::cNULL_TYPE_INFO; 77 81 }; 78 79 //----------------------------------------------------------------------80 // Forward declarations / typedefs / enums81 //----------------------------------------------------------------------82 82 83 83 //---------------------------------------------------------------------- … … 115 115 116 116 template <typename TGeneric> 117 tInterfaceTypeInfo tTypeInfo<TGeneric>::shared_info(&tTypeInfo<TGeneric>::cTYPE_INFO, &tTypeInfo<TGeneric>::Create, 0 );117 tInterfaceTypeInfo tTypeInfo<TGeneric>::shared_info(&tTypeInfo<TGeneric>::cTYPE_INFO, &tTypeInfo<TGeneric>::Create, 0, tInterfaceBase::GetPrimaryPortType<TGeneric>() != tInterfaceBase::tPrimaryPortType::ANY, typeid(tTypeInfo<TGeneric>)); 118 118 119 119 -
tInterface.h
r16 r17 108 108 public: 109 109 110 typedef typename std::conditional<cCONVENIENCE_PORT, structure::tComponent*, core::tPortGroup*>::type tParent;111 110 typedef tInterfaceBase tBase; 112 111 … … 122 121 /*! 123 122 * \param interface_type Interface type 124 * \param parent Parent (component for convenience ports as template arguments - and port group(s) otherwise)123 * \param parent Parent port group (if TPrimaryPort is a convenience port, this will create a partial interface) 125 124 * \param name Name of interface (must be unique in parent) 126 * \param p ort_type_relation If this port composite interface has multiple data port types, specifies how they are typically related (relevant for generic instantiation)125 * \param primary_port_type Type of ports with relation id zero 127 126 * \param custom_connect_function Custom connect function for this interface 128 127 */ 129 tInterface(const rrlib::rtti::tType& interface_type, tParent parent, const std::string& name, const tConnectFunction& custom_connect_function = tConnectFunction()) : 130 tInterfaceBase(new tInterfaceBase::tBackend(interface_type, parent, GetPrimaryPortTypeParent(parent), cPRIMARY_RELATION_ID, name, cCONVENIENCE_PORT, custom_connect_function, GetDefaultCreateMissingInterfaceFunction(parent))) 128 tInterface(const rrlib::rtti::tType& interface_type, core::tPortGroup* parent, const std::string& name, tPrimaryPortType primary_port_type = tPrimaryPortType::ANY, const tConnectFunction& custom_connect_function = tConnectFunction()) : 129 tInterfaceBase(new tInterfaceBase::tBackend(interface_type, parent, parent, cPRIMARY_RELATION_ID, name, cCONVENIENCE_PORT, custom_connect_function, GetDefaultCreateMissingInterfaceFunction(parent), primary_port_type, cCONVENIENCE_PORT)) 130 { 131 } 132 133 /*! 134 * \param interface_type Interface type 135 * \param parent Parent component 136 * \param name Name of interface (must be unique in parent) 137 * \param primary_port_type Type of ports with relation id zero 138 * \param custom_connect_function Custom connect function for this interface 139 */ 140 template <bool Tenable = cCONVENIENCE_PORT> 141 tInterface(typename std::enable_if<Tenable, const rrlib::rtti::tType&>::type interface_type, structure::tComponent* parent, const std::string& name, tPrimaryPortType primary_port_type = tPrimaryPortType::ANY, const tConnectFunction& custom_connect_function = tConnectFunction()) : 142 tInterfaceBase(new tInterfaceBase::tBackend(interface_type, parent, GetPrimaryPortTypeParent(parent), cPRIMARY_RELATION_ID, name, cCONVENIENCE_PORT, custom_connect_function, GetDefaultCreateMissingInterfaceFunction(parent), primary_port_type, false)) 131 143 { 132 144 } … … 138 150 * \param parent Parent port composite interface 139 151 * \param name Name of interface (must be unique in parent) 152 * \param primary_port_type Type of ports with relation id zero 140 153 * \param custom_connect_function Custom connect function for this interface 141 154 */ 142 155 template <typename TParent, bool Tenable = std::is_base_of<tInterfaceBase, typename std::decay<TParent>::type>::value> 143 tInterface(typename std::enable_if<Tenable, const rrlib::rtti::tType&>::type interface_type, TParent* parent, const std::string& name, const tConnectFunction& custom_connect_function = tConnectFunction()) :144 tInterfaceBase( parent->Backend() ? new tInterfaceBase::tBackend(interface_type, cCONVENIENCE_PORT ? parent->ParentComponent() : parent->Backend(), parent->Backend()->GetBackend(cPRIMARY_RELATION_ID), cPRIMARY_RELATION_ID, name, cCONVENIENCE_PORT, custom_connect_function) : nullptr)156 tInterface(typename std::enable_if<Tenable, const rrlib::rtti::tType&>::type interface_type, TParent* parent, const std::string& name, tPrimaryPortType primary_port_type = tPrimaryPortType::ANY, const tConnectFunction& custom_connect_function = tConnectFunction()) : 157 tInterfaceBase(CreateBackend(interface_type, *parent, name, primary_port_type, custom_connect_function)) 145 158 { 146 159 } 147 160 148 161 /*! Helper constructor to extract interface type */ 149 tInterface(const rrlib::rtti::tType& interface_type, tInterfaceTypeData* parent, const std::string& name, const tConnectFunction& custom_connect_function = tConnectFunction()) :162 tInterface(const rrlib::rtti::tType& interface_type, tInterfaceTypeData* parent, const std::string& name, tPrimaryPortType primary_port_type = tPrimaryPortType::ANY, const tConnectFunction& custom_connect_function = tConnectFunction()) : 150 163 tInterfaceBase() 151 164 { 152 165 parent->type = interface_type; 166 parent->primary_port_type = primary_port_type; 153 167 } 154 168 … … 162 176 163 177 template <int Tconvenience_port = cCONVENIENCE_PORT> 164 static core::tFrameworkElement* GetPrimaryPortTypeParent(typename std::enable_if<Tconvenience_port, tParent>::type parent)178 static core::tFrameworkElement* GetPrimaryPortTypeParent(typename std::enable_if<Tconvenience_port, structure::tComponent*>::type parent) 165 179 { 166 180 return &TPrimaryPort<double>::GetParentInterface(static_cast<typename TPrimaryPort<double>::tComponent&>(*parent)); 167 181 } 168 182 169 static core::tFrameworkElement* GetPrimaryPortTypeParent(core::tPortGroup* parent)170 {171 return parent;172 }173 174 183 template <int Tconvenience_port = cCONVENIENCE_PORT> 175 static constexpr tCreateMissingComponentInterfaceFunction GetDefaultCreateMissingInterfaceFunction(typename std::enable_if<Tconvenience_port, tParent>::type parent)184 static constexpr tCreateMissingComponentInterfaceFunction GetDefaultCreateMissingInterfaceFunction(typename std::enable_if<Tconvenience_port, core::tFrameworkElement*>::type parent) 176 185 { 177 186 return tInterfaceBase::GetDefaultCreateMissingInterfaceFunction<typename TPrimaryPort<double>::tComponent>(); 178 187 } 179 static constexpr tCreateMissingComponentInterfaceFunction GetDefaultCreateMissingInterfaceFunction(core::tPortGroup* parent) 188 template <int Tconvenience_port = cCONVENIENCE_PORT> 189 static constexpr tCreateMissingComponentInterfaceFunction GetDefaultCreateMissingInterfaceFunction(typename std::enable_if < !Tconvenience_port, core::tFrameworkElement* >::type parent) 180 190 { 181 191 return nullptr; 182 192 } 183 193 194 static tBackend* CreateBackend(rrlib::rtti::tType interface_type, tInterfaceBase& parent, const std::string& name, tPrimaryPortType primary_port_type, const tConnectFunction& custom_connect_function) 195 { 196 if (parent.Backend() == nullptr) 197 { 198 return nullptr; 199 } 200 tBackend* parent_backend = parent.Backend()->GetBackend(cPRIMARY_RELATION_ID); 201 bool partial_interface = false; 202 assert(parent_backend || parent.Backend()->IsPartialInterface()); 203 if (!parent_backend) 204 { 205 const internal::tInterfaceTypeInfo& info = static_cast<const internal::tInterfaceTypeInfo&>(interface_type.SharedTypeInfo()); 206 interface_type = info.GetPartialType(); 207 partial_interface = interface_type && primary_port_type != tPrimaryPortType::ANY; 208 if (partial_interface) 209 { 210 parent_backend = parent.Backend(); 211 } 212 } 213 return parent_backend ? new tInterfaceBase::tBackend(interface_type, cCONVENIENCE_PORT ? parent.ParentComponent() : parent.Backend(), parent_backend, cPRIMARY_RELATION_ID, name, cCONVENIENCE_PORT, custom_connect_function, nullptr, parent.Backend()->PrimaryPortType(), partial_interface) : nullptr; 214 } 215 184 216 }; 185 217 -
tInterfaceBase.cpp
r16 r17 115 115 } 116 116 117 core::tAbstractPortCreationInfo MakeCreationInfo(const rrlib::rtti::tType& interface_type, const std::string& name, core::tFrameworkElement& parent_interface )117 core::tAbstractPortCreationInfo MakeCreationInfo(const rrlib::rtti::tType& interface_type, const std::string& name, core::tFrameworkElement& parent_interface, bool partial_interface) 118 118 { 119 119 core::tAbstractPortCreationInfo result; 120 120 result.data_type = interface_type; 121 if (partial_interface) 122 { 123 auto partial_type = static_cast<const internal::tInterfaceTypeInfo&>(interface_type.SharedTypeInfo()).GetPartialType(); 124 result.data_type = partial_type ? partial_type : result.data_type; 125 } 121 126 result.parent = &parent_interface; 122 127 result.flags |= tFlag::INTERFACE; … … 171 176 return; 172 177 } 178 173 179 creation_info.parent = &Backend()->primary_backend; 174 180 … … 181 187 creation_info.flags |= core::tFrameworkElementFlags(creation_info.parent->GetAllFlags().Raw() & cRELEVANT_FLAGS); 182 188 189 if (Backend()->primary_backend.IsPartialInterface() && Backend()->primary_backend.PrimaryPortType() != tPrimaryPortType::ANY && Backend()->primary_backend.relation_backend_mapping.front().second == nullptr) 190 { 191 creation_info.flags |= tFlag::DELETED; 192 } 193 183 194 return; 184 195 } 185 196 186 187 tInterfaceBase::tBackend::tBackend(const rrlib::rtti::tType& interface_type, core::tFrameworkElement* parent_component, core::tFrameworkElement* parent, int primary_relation_id, const std::string& name, bool convenience_port_type, const tConnectFunction& custom_connect_function, tCreateMissingComponentInterfaceFunction create_missing_component_interface_function) : 188 tAbstractPort(MakeCreationInfo(interface_type, name, *parent)), 197 core::tConnector* tInterfaceBase::ConnectTo(const tInterfaceBase& partner, const core::tConnectOptions& connect_options) 198 { 199 if (Backend() && partner.Backend()) 200 { 201 for (auto this_backend : Backend()->relation_backend_mapping) 202 { 203 for (auto other_backend : partner.Backend()->primary_backend.relation_backend_mapping) 204 { 205 if (this_backend.second && other_backend.second && this_backend.first - Backend()->primary_relation_id == other_backend.first - partner.Backend()->primary_relation_id) 206 { 207 return this_backend.second->ConnectTo(*other_backend.second, connect_options); 208 } 209 } 210 } 211 } 212 return nullptr; 213 } 214 215 216 tInterfaceBase::tBackend::tBackend(const rrlib::rtti::tType& interface_type, core::tFrameworkElement* parent_component, core::tFrameworkElement* parent, int primary_relation_id, const std::string& name, bool convenience_port_type, const tConnectFunction& custom_connect_function, tCreateMissingComponentInterfaceFunction create_missing_component_interface_function, tPrimaryPortType primary_port_type, bool partial_interface) : 217 tAbstractPort(MakeCreationInfo(interface_type, name, *parent, partial_interface || tScopedExtraConstructorParameters::Get()->partial_interface)), 189 218 parent_component(parent_component), 190 219 primary_backend(*this), … … 192 221 convenience_port_type(convenience_port_type), 193 222 primary_relation_id(primary_relation_id), 194 create_missing_component_interface_function(create_missing_component_interface_function) 223 create_missing_component_interface_function(create_missing_component_interface_function), 224 primary_port_type(primary_port_type), 225 partial_interface(static_cast<const internal::tInterfaceTypeInfo&>(GetDataType().SharedTypeInfo()).GetFullType() != GetDataType()) 195 226 { 196 227 all_backends.emplace_back(this); 197 relation_backend_mapping.emplace_back(primary_relation_id, this); 228 tBackend* primary_relation_backend = this; 229 if (this->partial_interface && primary_port_type != tPrimaryPortType::ANY) 230 { 231 auto aggregator = GetAggregator(*this); 232 bool sensor_parent = (aggregator && aggregator->GetFlag(tFlag::SENSOR_DATA)); 233 bool controller_parent = (aggregator && aggregator->GetFlag(tFlag::CONTROLLER_DATA)); 234 if ((sensor_parent && primary_port_type == tPrimaryPortType::CONTROLLER_PORT) || (controller_parent && primary_port_type == tPrimaryPortType::SENSOR_PORT)) 235 { 236 primary_relation_backend = nullptr; 237 } 238 } 239 relation_backend_mapping.emplace_back(primary_relation_id, primary_relation_backend); 198 240 } 199 241 … … 203 245 convenience_port_type(false), 204 246 primary_relation_id(primary.primary_relation_id), 205 create_missing_component_interface_function(nullptr) 247 create_missing_component_interface_function(nullptr), 248 primary_port_type(primary.primary_port_type), 249 partial_interface(primary.partial_interface) 206 250 { 207 251 } … … 253 297 } 254 298 } 255 throw std::runtime_error("Un pecified port direction");299 throw std::runtime_error("Unspecified port direction"); 256 300 } 257 301 … … 282 326 283 327 core::tFrameworkElement* parent = nullptr; 328 bool do_not_create_primary_port_type = relation_backend_mapping.front().second == nullptr; 329 bool partial_interface_direction_is_output = this->GetParent()->GetFlag(tFlag::INTERFACE_FOR_OUTPUTS); 330 bool partial_interface_primary_relation_direction_is_output = !partial_interface_direction_is_output; 284 331 if (GetParent() && typeid(*GetParent()).name() == typeid(tBackend).name()) 285 332 { … … 315 362 } 316 363 364 tFrameworkElement* parent_candidate = (relation_list.empty() && do_not_create_primary_port_type) ? nullptr : component_interface; 365 core::tFrameworkElementFlags use_these_original_flags; 366 if (do_not_create_primary_port_type) 367 { 368 assert(partial_interface && primary_port_type != tPrimaryPortType::ANY); 369 use_these_original_flags = tFlag::INTERFACE_FOR_DATA_PORTS | (primary_port_type == tPrimaryPortType::SENSOR_PORT ? tFlag::SENSOR_DATA : tFlag::CONTROLLER_DATA) | (partial_interface_primary_relation_direction_is_output ? tFlag::INTERFACE_FOR_OUTPUTS : tFlag::INTERFACE_FOR_INPUTS); 370 use_these_original_flags.Set(tFlag::PROXY_INTERFACE, component_interface->GetFlag(tFlag::PROXY_INTERFACE)); 371 } 372 317 373 for (int opcode : relation_list) 318 374 { 319 core::tFrameworkElementFlags original_flags = component_interface->GetAllFlags(); 375 core::tFrameworkElementFlags original_flags = use_these_original_flags.Raw() ? use_these_original_flags : parent_candidate->GetAllFlags(); 376 use_these_original_flags = core::tFrameworkElementFlags(); 320 377 core::tFrameworkElementFlags target_set_flags = core::tFrameworkElementFlags(original_flags.Raw() & relevant_flags.Raw()); 321 378 core::tFrameworkElementFlags target_unset_flags = core::tFrameworkElementFlags((~original_flags.Raw()) & relevant_flags.Raw()); … … 406 463 } 407 464 465 if ((!new_candidate) && this->IsPartialInterface() && ((partial_interface_direction_is_output && (!target_set_flags.Get(tFlag::INTERFACE_FOR_OUTPUTS))) || ((!partial_interface_direction_is_output) && target_set_flags.Get(tFlag::INTERFACE_FOR_OUTPUTS)))) 466 { 467 use_these_original_flags = target_set_flags; 468 parent_candidate = nullptr; 469 continue; 470 } 471 408 472 // Not-yet-created component interfaces - until there is a generic way to do this 409 473 if ((!new_candidate) && create_missing_component_interface_function) … … 415 479 { 416 480 component_interface = new_candidate; 481 parent_candidate = new_candidate; 417 482 } 418 483 else … … 425 490 } 426 491 427 parent = component_interface; 428 } 429 430 for (auto & entry : relation_backend_mapping) 431 { 432 if (entry.second->GetParent() == parent) 433 { 434 auto backend = entry.second; 492 parent = parent_candidate; 493 } 494 495 if (parent && partial_interface) 496 { 497 if ((partial_interface_direction_is_output && parent->GetFlag(tFlag::INTERFACE_FOR_INPUTS)) || ((!partial_interface_direction_is_output) && parent->GetFlag(tFlag::INTERFACE_FOR_OUTPUTS))) 498 { 499 parent = nullptr; 500 } 501 } 502 503 if (!parent) 504 { 505 relation_backend_mapping.emplace_back(primary_relation_id, nullptr); 506 return nullptr; 507 } 508 509 for (auto backend : all_backends) 510 { 511 if (backend->GetParent() == parent) 512 { 435 513 relation_backend_mapping.emplace_back(primary_relation_id, backend); 436 514 return backend; … … 439 517 440 518 // Create new backend below this parent 519 assert(parent != this->GetParent()); 441 520 core::tAbstractPortCreationInfo secondary_creation_info; 442 521 secondary_creation_info.data_type = this->GetDataType(); … … 506 585 for (auto other_backend : other.primary_backend.primary_backend.relation_backend_mapping) 507 586 { 508 if (this_backend. first - primary_backend.primary_relation_id == other_backend.first - other.primary_backend.primary_relation_id && (connect_all_backends || this_backend.second == this || other_backend.second == &other))587 if (this_backend.second && other_backend.second && this_backend.first - primary_backend.primary_relation_id == other_backend.first - other.primary_backend.primary_relation_id && (connect_all_backends || this_backend.second == this || other_backend.second == &other)) 509 588 { 510 589 core::tConnectionFlag direction = (this->IsOutputPort() == this_backend.second->IsOutputPort() ? partner_is_destination : (!partner_is_destination)) ? core::tConnectionFlag::DIRECTION_TO_DESTINATION : core::tConnectionFlag::DIRECTION_TO_SOURCE; … … 613 692 } 614 693 694 tInterfaceBase::tScopedExtraConstructorParameters tInterfaceBase::tScopedExtraConstructorParameters::Get() 695 { 696 static tExtraConstructorParameters parameters; 697 return tScopedExtraConstructorParameters(core::tRuntimeEnvironment::GetInstance().GetStructureMutex(), ¶meters); // 698 } 699 615 700 616 701 //---------------------------------------------------------------------- -
tInterfaceBase.h
r16 r17 100 100 public: 101 101 102 /*! 103 * Allows to specify type of primary port 104 * Is set, this allows to instantiate interfaces partially 105 */ 106 enum tPrimaryPortType 107 { 108 ANY, 109 CONTROLLER_PORT, 110 SENSOR_PORT 111 }; 112 102 113 class tBackend; 103 114 typedef std::function<std::string(tBackend&, tBackend&)> tConnectFunction; //!< First backend is data source primary backend, second backend is data destination primary backend … … 122 133 return static_cast<tBackend*>(this->GetWrapped()); 123 134 } 135 136 /*! 137 * Connect interface to specified partner interface 138 * 139 * \param partner Interface to connect this interface to 140 * \param connect_options Any connect options to apply 141 * \return Pointer to connector object if connecting succeeded. nullptr otherwise. 142 * \throw Throws std::invalid_argument on invalid connect options 143 */ 144 core::tConnector* ConnectTo(const tInterfaceBase& partner, const core::tConnectOptions& connect_options = core::tConnectOptions()); 124 145 125 146 /*! … … 132 153 */ 133 154 static std::vector<tInterfaceBase> FindInterfacesBelow(core::tFrameworkElement& parent, const rrlib::rtti::tType& type, bool skip_derived_interfaces = false); 155 156 /*! 157 * \return Returns primary port type of interface type TInterface 158 */ 159 template <typename TInterface> 160 static tPrimaryPortType GetPrimaryPortType() 161 { 162 tInterfaceTypeData result; 163 TInterface temp_instance("", &result); 164 return result.primary_port_type; 165 } 134 166 135 167 /*! … … 172 204 * \param custom_connect_function Custom connect function for this interface 173 205 * \param create_missing_component_interface_function Function to create missing component interface 174 */ 175 tBackend(const rrlib::rtti::tType& interface_type, core::tFrameworkElement* parent_component, core::tFrameworkElement* parent, int primary_relation_id, const std::string& name, bool convenience_port, const tConnectFunction& custom_connect_function = tConnectFunction(), tCreateMissingComponentInterfaceFunction create_missing_component_interface_function = nullptr); 206 * \param primary_port_type Type of ports with relation id zero 207 * \param partial_interface Whether to instantiate a partial interface (this parameter is merged with scoped extra constructor parameters) 208 */ 209 tBackend(const rrlib::rtti::tType& interface_type, core::tFrameworkElement* parent_component, core::tFrameworkElement* parent, int primary_relation_id, const std::string& name, bool convenience_port, const tConnectFunction& custom_connect_function = tConnectFunction(), tCreateMissingComponentInterfaceFunction create_missing_component_interface_function = nullptr, tPrimaryPortType primary_port_type = tPrimaryPortType::ANY, bool partial_interface = false); 176 210 177 211 /*! … … 199 233 200 234 /*! 235 * \return Whether this interface is a partial interface 236 */ 237 bool IsPartialInterface() const 238 { 239 return partial_interface; 240 } 241 242 /*! 201 243 * \return Whether this is the primary backend 202 244 */ … … 204 246 { 205 247 return &primary_backend == this; 248 } 249 250 /*! 251 * \return Type of ports with relation id zero (as specified in constructor) 252 */ 253 tPrimaryPortType PrimaryPortType() const 254 { 255 return primary_port_type; 206 256 } 207 257 … … 272 322 tCreateMissingComponentInterfaceFunction create_missing_component_interface_function; 273 323 324 /*! Type of ports with relation id zero */ 325 tPrimaryPortType primary_port_type; 326 327 /*! Whether this interface is a partial interface */ 328 bool partial_interface; 329 274 330 /*! 275 331 * Constructor for secondary instances … … 312 368 } 313 369 370 /*! Additional constructor parameters that are not passed through tInterface constructor - for convenience and backward-compatibility */ 371 struct tExtraConstructorParameters 372 { 373 bool partial_interface = false; 374 }; 375 376 class tScopedExtraConstructorParameters 377 { 378 public: 379 380 tScopedExtraConstructorParameters() : 381 parameters(nullptr) 382 {} 383 384 tScopedExtraConstructorParameters(tScopedExtraConstructorParameters && other) : 385 parameters(nullptr) 386 { 387 this->lock = std::move(other.lock); 388 std::swap(parameters, other.parameters); 389 } 390 391 tScopedExtraConstructorParameters& operator=(tScopedExtraConstructorParameters && other) 392 { 393 this->lock = std::move(other.lock); 394 std::swap(parameters, other.parameters); 395 return *this; 396 } 397 398 inline tExtraConstructorParameters* operator->() 399 { 400 return parameters; 401 } 402 403 static tScopedExtraConstructorParameters Get(); 404 405 ~tScopedExtraConstructorParameters() 406 { 407 if (parameters) 408 { 409 *parameters = tExtraConstructorParameters(); 410 } 411 } 412 413 private: 414 415 tScopedExtraConstructorParameters(rrlib::thread::tRecursiveMutex& mutex, tExtraConstructorParameters* parameters) : 416 lock(mutex), 417 parameters(parameters) 418 {} 419 420 rrlib::thread::tLock lock; 421 tExtraConstructorParameters* parameters; 422 }; 423 314 424 //---------------------------------------------------------------------- 315 425 // Private fields and methods … … 319 429 template <template <typename> class TPort> 320 430 friend class tInterface; 321 322 /*! Helper class to extract type info about on interfaces */ 431 friend class internal::tInterfaceFactory; 432 433 /*! Helper class to extract type info on interfaces */ 323 434 struct tInterfaceTypeData 324 435 { 325 436 rrlib::rtti::tType type; 437 tPrimaryPortType primary_port_type; 326 438 }; 327 439
Note: See TracChangeset
for help on using the changeset viewer.