Changeset 122:1e156061e98d in finroc_plugins_data_ports


Ignore:
Timestamp:
27.08.2017 18:02:54 (2 years ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Message:

Simplifies generic port implementation - as with revision 118:f7a4f44a0789 type-specific instances have become obsolete. Notably, data type annotations are no longer required for the generic port implementation.

Location:
api
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • api/tGenericPortImplementation.cpp

    r114 r122  
    7070// Implementation 
    7171//---------------------------------------------------------------------- 
    72 namespace internal 
    73 { 
    74  
    75 template <typename T> 
    76 struct tBoundsSetter 
    77 { 
    78   static void SetBounds(core::tAbstractPort& port, const rrlib::rtti::tGenericObject& min, const rrlib::rtti::tGenericObject& max) 
    79   { 
    80     typedef api::tBoundedPort<T, api::tPortImplementationTypeTrait<T>::type> tBoundedPort; 
    81     if (typeid(port) != typeid(tBoundedPort)) 
    82     { 
    83       FINROC_LOG_PRINT_STATIC(ERROR, "Cannot set bounds for port ", rrlib::rtti::tDataType<T>().GetName(), ". It is not a bounded port."); 
    84       return; 
    85     } 
    86     static_cast<tBoundedPort&>(port).SetBounds(tBounds<T>(min.GetData<T>(), max.GetData<T>())); 
    87   } 
    88 }; 
    89  
    90 struct tNoBoundsSetter 
    91 { 
    92   static void SetBounds(core::tAbstractPort& port, const rrlib::rtti::tGenericObject& min, const rrlib::rtti::tGenericObject& max) 
    93   { 
    94     FINROC_LOG_PRINT_STATIC(ERROR, "Cannot set bounds for type ", port.GetDataType().GetName()); 
    95   } 
    96 }; 
    97  
    98  
    99 template <typename T> 
    100 class tGenericPortImplementationTyped : public tGenericPortImplementation 
     72namespace 
     73{ 
     74 
     75class tGenericPortImplementationCheapCopy : public tGenericPortImplementation 
    10176{ 
    10277public: 
    10378 
    104   /*! Should methods dealing with bounds be available? */ 
    105   enum { cBOUNDABLE = IsBoundable<T>::value }; 
    106  
    107   /*! Class that contains actual implementation of most functionality */ 
    108   typedef api::tPortImplementation<T, api::tPortImplementationTypeTrait<T>::type> tImplementation; 
    109  
    110   typedef typename tImplementation::tPortBase tPortBase; 
     79  typedef tCheapCopyPort tPortBase; 
    11180 
    11281  virtual core::tAbstractPort* CreatePort(const common::tAbstractDataPortCreationInfo& creation_info) override 
    11382  { 
    114     tPort<T> port(creation_info); 
    115     return port.GetWrapped(); 
     83    return new tPortBase(creation_info); 
    11684  } 
    11785 
    11886  virtual void Get(core::tAbstractPort& port, rrlib::rtti::tGenericObject& result, rrlib::time::tTimestamp& timestamp) override 
    11987  { 
    120     tImplementation::CopyCurrentPortValue(static_cast<tPortBase&>(port), result.GetData<T>(), timestamp); 
     88    static_cast<tPortBase&>(port).CopyCurrentValueToGenericObject(result, timestamp); 
    12189  } 
    12290 
     
    143111  virtual void Publish(core::tAbstractPort& port, const rrlib::rtti::tGenericObject& data, const rrlib::time::tTimestamp& timestamp) override 
    144112  { 
    145     tImplementation::CopyAndPublish(static_cast<tPortBase&>(port), data.GetData<T>(), timestamp); 
    146   } 
    147  
    148   virtual void SetBounds(core::tAbstractPort& port, const rrlib::rtti::tGenericObject& min, const rrlib::rtti::tGenericObject& max) override 
    149   { 
    150     std::conditional<cBOUNDABLE, tBoundsSetter<T>, tNoBoundsSetter>::type::SetBounds(port, min, max); 
    151   } 
    152 }; 
    153  
    154  
    155 class tGenericPortImplementationCheapCopy : public tGenericPortImplementation 
    156 { 
    157 public: 
    158  
    159   typedef tCheapCopyPort tPortBase; 
    160  
    161   virtual core::tAbstractPort* CreatePort(const common::tAbstractDataPortCreationInfo& creation_info) override 
    162   { 
    163     return new tPortBase(creation_info); 
    164   } 
    165  
    166   virtual void Get(core::tAbstractPort& port, rrlib::rtti::tGenericObject& result, rrlib::time::tTimestamp& timestamp) override 
    167   { 
    168     static_cast<tPortBase&>(port).CopyCurrentValueToGenericObject(result, timestamp); 
    169   } 
    170  
    171   virtual tPortDataPointer<const rrlib::rtti::tGenericObject> GetPointer(core::tAbstractPort& abstract_port, tStrategy strategy) override 
    172   { 
    173     tPortBase& port = static_cast<tPortBase&>(abstract_port); 
    174     if ((strategy == tStrategy::DEFAULT && port.PushStrategy()) || strategy == tStrategy::NEVER_PULL || definitions::cSINGLE_THREADED) 
    175     { 
    176       tPortDataPointer<rrlib::rtti::tGenericObject> buffer = this->GetUnusedBuffer(port); 
    177       rrlib::time::tTimestamp timestamp; 
    178       port.CopyCurrentValueToGenericObject(*buffer.Get(), timestamp, strategy); 
    179       buffer.SetTimestamp(timestamp); 
    180       return std::move(buffer); 
    181     } 
    182 #ifndef RRLIB_SINGLE_THREADED 
    183     else 
    184     { 
    185       auto buffer_pointer = port.GetPullRaw(strategy == tStrategy::PULL_IGNORING_HANDLER_ON_THIS_PORT); 
    186       return tPortDataPointerImplementation<rrlib::rtti::tGenericObject, false>(buffer_pointer.release(), false); 
    187     } 
    188 #endif 
    189   } 
    190  
    191   virtual void Publish(core::tAbstractPort& port, const rrlib::rtti::tGenericObject& data, const rrlib::time::tTimestamp& timestamp) override 
    192   { 
    193113#ifndef RRLIB_SINGLE_THREADED 
    194114    assert(data.GetType() == port.GetDataType()); 
     
    260180}; 
    261181 
    262 template <typename T> 
    263 static void CheckCreateImplementationForType(rrlib::rtti::tType type) 
    264 { 
    265   if (type.GetRttiName() == typeid(T).name()) 
    266   { 
    267     static internal::tGenericPortImplementationTyped<T> cINSTANCE; 
    268     type.AddAnnotation<tGenericPortImplementation*>(&cINSTANCE); 
    269   } 
    270 } 
    271182 
    272183tGenericPortImplementationCheapCopy cINSTANCE_CHEAP_COPY; 
    273184tGenericPortImplementationStandard cINSTANCE_STANDARD; 
    274185 
    275 } // namespace internal 
    276  
    277 void tGenericPortImplementation::CreateImplementations() 
    278 { 
    279   static rrlib::thread::tMutex mutex; 
    280   static size_t initialized_types = 0; 
    281   rrlib::thread::tLock lock(mutex); 
    282  
    283   for (; initialized_types < rrlib::rtti::tType::GetTypeCount(); initialized_types++) 
    284   { 
    285     rrlib::rtti::tType type = rrlib::rtti::tType::GetType(initialized_types); 
    286     if (IsDataFlowType(type)) 
    287     { 
    288       // typed implementations for certain types 
    289       internal::CheckCreateImplementationForType<int8_t>(type); 
    290       internal::CheckCreateImplementationForType<int16_t>(type); 
    291       internal::CheckCreateImplementationForType<int>(type); 
    292       internal::CheckCreateImplementationForType<long long int>(type); 
    293       internal::CheckCreateImplementationForType<uint8_t>(type); 
    294       internal::CheckCreateImplementationForType<uint16_t>(type); 
    295       internal::CheckCreateImplementationForType<unsigned int>(type); 
    296       internal::CheckCreateImplementationForType<unsigned long long int>(type); 
    297       internal::CheckCreateImplementationForType<double>(type); 
    298       internal::CheckCreateImplementationForType<float>(type); 
    299       internal::CheckCreateImplementationForType<char>(type);  // is neither int8_t nor uint8_t 
    300       internal::CheckCreateImplementationForType<numeric::tNumber>(type); 
    301  
    302       if (!type.GetAnnotation<tGenericPortImplementation*>()) 
    303       { 
    304         assert((type.GetTypeTraits() & rrlib::rtti::trait_flags::cIS_INTEGRAL) == 0 || type.GetRttiName() == typeid(bool).name()); 
    305         if (IsCheaplyCopiedType(type)) 
    306         { 
    307           type.AddAnnotation<tGenericPortImplementation*>(&internal::cINSTANCE_CHEAP_COPY); 
    308         } 
    309         else 
    310         { 
    311           type.AddAnnotation<tGenericPortImplementation*>(&internal::cINSTANCE_STANDARD); 
    312         } 
    313       } 
    314     } 
    315   } 
    316 } 
     186} // anonymous namespace 
     187 
     188tGenericPortImplementation* tGenericPortImplementation::cIMPLEMENTATION_STANDARD = &cINSTANCE_STANDARD; 
     189tGenericPortImplementation* tGenericPortImplementation::cIMPLEMENTATION_CHEAP_COPY = &cINSTANCE_CHEAP_COPY; 
     190 
    317191 
    318192void tGenericPortImplementation::SetPullRequestHandler(core::tAbstractPort& port, tPullRequestHandler<rrlib::rtti::tGenericObject>* pull_request_handler) 
  • api/tGenericPortImplementation.h

    r119 r122  
    125125  static tGenericPortImplementation* GetImplementation(const rrlib::rtti::tType& type) 
    126126  { 
    127     tGenericPortImplementation* annotation = type.GetAnnotation<tGenericPortImplementation*>(); 
    128     if (!annotation) 
    129     { 
    130       CreateImplementations(); 
    131       annotation = type.GetAnnotation<tGenericPortImplementation*>(); 
    132     } 
    133     return annotation; 
     127    return IsCheaplyCopiedType(type) ? cIMPLEMENTATION_CHEAP_COPY : cIMPLEMENTATION_STANDARD; 
    134128  } 
    135129 
     
    229223private: 
    230224 
    231   /*! Creates implementation for data types that weren't annotated yet */ 
    232   static void CreateImplementations(); 
     225  /*! The two available implementations */ 
     226  static tGenericPortImplementation* cIMPLEMENTATION_STANDARD, *cIMPLEMENTATION_CHEAP_COPY; 
    233227 
    234228}; 
Note: See TracChangeset for help on using the changeset viewer.