Changeset 17:1f553643f4a9 in finroc_plugins_composite_ports


Ignore:
Timestamp:
24.08.2020 00:42:48 (17 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
default
Phase:
public
Message:

Adds option to instantiate only one half of an interface consisting of multiple port types (all ports of one direction)

Files:
17 edited

Legend:

Unmodified
Added
Removed
  • examples/example.finroc

    r10 r17  
    2525  <edge src="Aggregator/Sensor Output/Fancy 1" dest="Group With User/Sensor Input/I%2FO Interconnected"/> 
    2626  <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"/> 
    2728  <edge src="Aggregator/Sensor Output/Input Output Interface 4" dest="Group With User/Sensor Input/I%2FO Interface 3"/> 
    2829  <edge src="Aggregator/Sensor Output/Input Output Interface 5" dest="Group With User/Sensor Input/I%2FO Interface 4"/> 
    2930  <edge src="Aggregator/Sensor Output/Simple 1" dest="Group With User/Sensor Input/Simple 3"/> 
    3031  <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"/> 
    3133</Finstructable> 
  • examples/gAggregator.xml

    r9 r17  
    1414    <port name="Fancy 2" type="finroc.composite_ports.examples.interfaces.Fancy"/> 
    1515    <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)"/> 
    1620  </interface> 
    1721  <interface name="Parameters"> 
     
    2832    </parameters> 
    2933  </element> 
     34  <edge src="Controller Input/Fancy Partial In" dest="Module 1/Controller Input/Fancy Partial"/> 
    3035  <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"/> 
    3137  <edge src="Module 1/Sensor Output/I%2FO Interface 1" dest="Sensor Output/Input Output Interface 1"/> 
    3238  <edge src="Module 1/Sensor Output/I%2FO Interface 2" dest="Sensor Output/Input Output Interface 2"/> 
  • examples/gAggregatorCoded.cpp

    r9 r17  
    8080  tSenseControlGroup(parent, name, structure_config_file, false), 
    8181  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()) 
    8385{ 
    8486  auto module_1 = new mInterfaceImplementer1(this, "Module 1"); 
     
    9395  composite_ports::ConnectFirstChildComponentInterface(*this, fancy_1); 
    9496  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); 
    95100} 
    96101 
  • examples/gAggregatorCoded.h

    r9 r17  
    8484  std::vector<interfaces::tInputOutput<tSensorOutput>> input_output_interfaces; 
    8585  interfaces::tFancy<tSensorOutput> fancy_1, fancy_2; 
     86  interfaces::tFancy<tSensorOutput> fancy_partial_in, fancy_partial_out; 
    8687 
    8788  tSensorOutput<double> so_plain_sensor_output; 
  • examples/gUser.xml

    r10 r17  
    1313    <port name="Simple 4" type="finroc.composite_ports.examples.interfaces.Simple"/> 
    1414    <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)"/> 
    1519  </interface> 
    1620  <element name="Interface User" group="finroc_plugins_composite_ports_example" type="InterfaceUser"> 
    1721    <parameters/> 
    1822  </element> 
     23  <edge src="Interface User/Controller Output/Fancy Partial" dest="Controller Output/Fancy Partial"/> 
    1924  <edge src="Sensor Input/Fancy 1" dest="Interface User/Sensor Input/Fancy 1"/> 
    2025  <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"/> 
    2127  <edge src="Sensor Input/I%2FO Interface 1" dest="Interface User/Sensor Input/I%2FO Interface 1"/> 
    2228  <edge src="Sensor Input/I%2FO Interface 2" dest="Interface User/Sensor Input/I%2FO Interface 2"/> 
  • examples/interfaces/tInputOutput.h

    r9 r17  
    8181public: 
    8282 
     83  typedef composite_ports::tInterface<TSensorPort> tBase; 
     84 
    8385  template <typename T> 
    8486  using tControllerPort = typename composite_ports::port_relation::tCounterPart<TSensorPort>::template type<T>; 
     
    9496  template <typename TParent> 
    9597  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), 
    9799    status("Status", this), 
    98100    measured_data("Measured Data", this), 
  • examples/mInterfaceImplementer1.cpp

    r9 r17  
    7777  so_simple_1("Simple 1", this), 
    7878  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()) 
    8082{ 
    8183  so_simple_1.id.SetDefault("George"); 
  • examples/mInterfaceImplementer1.h

    r9 r17  
    4242// External includes (system with <>, local with "") 
    4343//---------------------------------------------------------------------- 
     44#include "core/tRuntimeEnvironment.h" 
    4445 
    4546//---------------------------------------------------------------------- 
     
    8586 
    8687  interfaces::tFancy<tSensorOutput> fancy; 
     88  interfaces::tFancy<tSensorOutput> fancy_partial_in, fancy_partial_out; 
    8789 
    8890  tSensorOutput<double> so_plain_sensor_output; 
  • examples/mInterfaceUser.cpp

    r9 r17  
    7474//---------------------------------------------------------------------- 
    7575mInterfaceUser::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()) 
    7779{ 
    7880  this->ResizePortVector(si_simple, 4, "Simple "); 
  • examples/mInterfaceUser.h

    r9 r17  
    8383  std::vector<interfaces::tFancy<tSensorInput>> fancy_vector; 
    8484 
     85  interfaces::tFancy<tSensorInput> fancy_partial_in, fancy_partial_out; 
     86 
    8587//---------------------------------------------------------------------- 
    8688// Public methods and typedefs 
  • internal/tGenericPortType.h

    r16 r17  
    8989 
    9090    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 
     91    if (!parent_backend) 
     92    { 
     93      return; 
     94    } 
    9195    static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), rest...); 
    9296  } 
     
    117121 
    118122    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 
     123    if (!parent_backend) 
     124    { 
     125      return; 
     126    } 
    119127    core::tPortWrapperBase::tConstructorArguments<data_ports::tPortCreationInfo<T>> creation_info(name, parent_backend, rrlib::rtti::tDataType<T>(), parent_backend->GetDefaultPortFlags(true), rest...); 
    120128    assert(creation_info.data_type); 
     
    151159 
    152160    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 
     161    if (!parent_backend) 
     162    { 
     163      return; 
     164    } 
     165 
    153166    // Create port instance via factory 
    154167    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); 
     
    184197 
    185198    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations); 
     199    if (!parent_backend) 
     200    { 
     201      return; 
     202    } 
     203 
    186204    static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), std::forward<TRest>(rest)...); 
    187205  } 
  • internal/tInterfaceTypeInfo.cpp

    r14 r17  
    9191    } 
    9292 
    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(); 
    9495    if (!create_function) 
    9596    { 
    9697      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; 
    97105    } 
    98106 
     
    118126} 
    119127 
     128tInterfaceTypeInfo::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 
     144tInterfaceTypeInfo::~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 
    120154rrlib::util::tManagedConstCharPointer tInterfaceTypeInfo::GenerateName(const char* rtti_name) 
    121155{ 
  • internal/tInterfaceTypeInfo.h

    r0 r17  
    8686  typedef tInterfaceBase(*tCreateFunction)(const std::string& name, core::tPortGroup* parent); 
    8787 
    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), 
    9092    create_function(create_function) 
    9193  {} 
     94 
     95  ~tInterfaceTypeInfo(); 
    9296 
    9397  /*! 
     
    110114  } 
    111115 
     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 
    112132//---------------------------------------------------------------------- 
    113133// Private fields and methods 
     
    117137  /*! Create function for this interface type (generic instance) */ 
    118138  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; 
    119145 
    120146  /*! Generates interface type name from rtti name */ 
  • internal/tTypeInfo.h

    r10 r17  
    5555{ 
    5656 
     57//---------------------------------------------------------------------- 
     58// Forward declarations / typedefs / enums 
     59//---------------------------------------------------------------------- 
     60 
    5761template <template <typename> class TPrimaryPort> 
    5862class tInterface; 
     
    7680  static constexpr const rrlib::rtti::detail::tTypeInfo& cTYPE_INFO = rrlib::rtti::detail::tTypeInfo::cNULL_TYPE_INFO; 
    7781}; 
    78  
    79 //---------------------------------------------------------------------- 
    80 // Forward declarations / typedefs / enums 
    81 //---------------------------------------------------------------------- 
    8282 
    8383//---------------------------------------------------------------------- 
     
    115115 
    116116template <typename TGeneric> 
    117 tInterfaceTypeInfo tTypeInfo<TGeneric>::shared_info(&tTypeInfo<TGeneric>::cTYPE_INFO, &tTypeInfo<TGeneric>::Create, 0); 
     117tInterfaceTypeInfo tTypeInfo<TGeneric>::shared_info(&tTypeInfo<TGeneric>::cTYPE_INFO, &tTypeInfo<TGeneric>::Create, 0, tInterfaceBase::GetPrimaryPortType<TGeneric>() != tInterfaceBase::tPrimaryPortType::ANY, typeid(tTypeInfo<TGeneric>)); 
    118118 
    119119 
  • tInterface.h

    r16 r17  
    108108public: 
    109109 
    110   typedef typename std::conditional<cCONVENIENCE_PORT, structure::tComponent*, core::tPortGroup*>::type tParent; 
    111110  typedef tInterfaceBase tBase; 
    112111 
     
    122121  /*! 
    123122   * \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) 
    125124   * \param name Name of interface (must be unique in parent) 
    126    * \param port_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 
    127126   * \param custom_connect_function Custom connect function for this interface 
    128127   */ 
    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)) 
    131143  { 
    132144  } 
     
    138150   * \param parent Parent port composite interface 
    139151   * \param name Name of interface (must be unique in parent) 
     152   * \param primary_port_type Type of ports with relation id zero 
    140153   * \param custom_connect_function Custom connect function for this interface 
    141154   */ 
    142155  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)) 
    145158  { 
    146159  } 
    147160 
    148161  /*! 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()) : 
    150163    tInterfaceBase() 
    151164  { 
    152165    parent->type = interface_type; 
     166    parent->primary_port_type = primary_port_type; 
    153167  } 
    154168 
     
    162176 
    163177  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) 
    165179  { 
    166180    return &TPrimaryPort<double>::GetParentInterface(static_cast<typename TPrimaryPort<double>::tComponent&>(*parent)); 
    167181  } 
    168182 
    169   static core::tFrameworkElement* GetPrimaryPortTypeParent(core::tPortGroup* parent) 
    170   { 
    171     return parent; 
    172   } 
    173  
    174183  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) 
    176185  { 
    177186    return tInterfaceBase::GetDefaultCreateMissingInterfaceFunction<typename TPrimaryPort<double>::tComponent>(); 
    178187  } 
    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) 
    180190  { 
    181191    return nullptr; 
    182192  } 
    183193 
     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 
    184216}; 
    185217 
  • tInterfaceBase.cpp

    r16 r17  
    115115} 
    116116 
    117 core::tAbstractPortCreationInfo MakeCreationInfo(const rrlib::rtti::tType& interface_type, const std::string& name, core::tFrameworkElement& parent_interface) 
     117core::tAbstractPortCreationInfo MakeCreationInfo(const rrlib::rtti::tType& interface_type, const std::string& name, core::tFrameworkElement& parent_interface, bool partial_interface) 
    118118{ 
    119119  core::tAbstractPortCreationInfo result; 
    120120  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  } 
    121126  result.parent = &parent_interface; 
    122127  result.flags |= tFlag::INTERFACE; 
     
    171176    return; 
    172177  } 
     178 
    173179  creation_info.parent = &Backend()->primary_backend; 
    174180 
     
    181187  creation_info.flags |= core::tFrameworkElementFlags(creation_info.parent->GetAllFlags().Raw() & cRELEVANT_FLAGS); 
    182188 
     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 
    183194  return; 
    184195} 
    185196 
    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)), 
     197core::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 
     216tInterfaceBase::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)), 
    189218  parent_component(parent_component), 
    190219  primary_backend(*this), 
     
    192221  convenience_port_type(convenience_port_type), 
    193222  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()) 
    195226{ 
    196227  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); 
    198240} 
    199241 
     
    203245  convenience_port_type(false), 
    204246  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) 
    206250{ 
    207251} 
     
    253297    } 
    254298  } 
    255   throw std::runtime_error("Unpecified port direction"); 
     299  throw std::runtime_error("Unspecified port direction"); 
    256300} 
    257301 
     
    282326 
    283327  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; 
    284331  if (GetParent() && typeid(*GetParent()).name() == typeid(tBackend).name()) 
    285332  { 
     
    315362    } 
    316363 
     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 
    317373    for (int opcode : relation_list) 
    318374    { 
    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(); 
    320377      core::tFrameworkElementFlags target_set_flags = core::tFrameworkElementFlags(original_flags.Raw() & relevant_flags.Raw()); 
    321378      core::tFrameworkElementFlags target_unset_flags = core::tFrameworkElementFlags((~original_flags.Raw()) & relevant_flags.Raw()); 
     
    406463      } 
    407464 
     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 
    408472      // Not-yet-created component interfaces - until there is a generic way to do this 
    409473      if ((!new_candidate) && create_missing_component_interface_function) 
     
    415479      { 
    416480        component_interface = new_candidate; 
     481        parent_candidate = new_candidate; 
    417482      } 
    418483      else 
     
    425490    } 
    426491 
    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    { 
    435513      relation_backend_mapping.emplace_back(primary_relation_id, backend); 
    436514      return backend; 
     
    439517 
    440518  // Create new backend below this parent 
     519  assert(parent != this->GetParent()); 
    441520  core::tAbstractPortCreationInfo secondary_creation_info; 
    442521  secondary_creation_info.data_type = this->GetDataType(); 
     
    506585      for (auto other_backend : other.primary_backend.primary_backend.relation_backend_mapping) 
    507586      { 
    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)) 
    509588        { 
    510589          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; 
     
    613692} 
    614693 
     694tInterfaceBase::tScopedExtraConstructorParameters tInterfaceBase::tScopedExtraConstructorParameters::Get() 
     695{ 
     696  static tExtraConstructorParameters parameters; 
     697  return tScopedExtraConstructorParameters(core::tRuntimeEnvironment::GetInstance().GetStructureMutex(), &parameters);  // 
     698} 
     699 
    615700 
    616701//---------------------------------------------------------------------- 
  • tInterfaceBase.h

    r16 r17  
    100100public: 
    101101 
     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 
    102113  class tBackend; 
    103114  typedef std::function<std::string(tBackend&, tBackend&)> tConnectFunction;  //!< First backend is data source primary backend, second backend is data destination primary backend 
     
    122133    return static_cast<tBackend*>(this->GetWrapped()); 
    123134  } 
     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()); 
    124145 
    125146  /*! 
     
    132153   */ 
    133154  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  } 
    134166 
    135167  /*! 
     
    172204     * \param custom_connect_function Custom connect function for this interface 
    173205     * \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); 
    176210 
    177211    /*! 
     
    199233 
    200234    /*! 
     235     * \return Whether this interface is a partial interface 
     236     */ 
     237    bool IsPartialInterface() const 
     238    { 
     239      return partial_interface; 
     240    } 
     241 
     242    /*! 
    201243     * \return Whether this is the primary backend 
    202244     */ 
     
    204246    { 
    205247      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; 
    206256    } 
    207257 
     
    272322    tCreateMissingComponentInterfaceFunction create_missing_component_interface_function; 
    273323 
     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 
    274330    /*! 
    275331     * Constructor for secondary instances 
     
    312368  } 
    313369 
     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 
    314424//---------------------------------------------------------------------- 
    315425// Private fields and methods 
     
    319429  template <template <typename> class TPort> 
    320430  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 */ 
    323434  struct tInterfaceTypeData 
    324435  { 
    325436    rrlib::rtti::tType type; 
     437    tPrimaryPortType primary_port_type; 
    326438  }; 
    327439 
Note: See TracChangeset for help on using the changeset viewer.