source: finroc_plugins_composite_ports/internal/tGenericPortType.h @ 28:0d9e9fd957de

Last change on this file since 28:0d9e9fd957de was 23:3c9cac2a0cc1, checked in by Max Reichardt <mreichardt@…>, 23 months ago

Adds 'interface modifiers' for customization of port composite interface creation (as there are diverse use cases). Refactors and tidies partial interface creation with this new feature.

File size: 8.1 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/composite_ports/internal/tGenericPortType.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2020-02-07
27 *
28 * \brief   Contains tGenericPortType
29 *
30 * \b tGenericPortType
31 *
32 * Helper port class to realize generic instantiation of port composite interfaces
33 *
34 */
35//----------------------------------------------------------------------
36#ifndef __plugins__structure__internal__tGenericPortType_h__
37#define __plugins__structure__internal__tGenericPortType_h__
38
39//----------------------------------------------------------------------
40// External includes (system with <>, local with "")
41//----------------------------------------------------------------------
42#include "core/port/tPortFactory.h"
43#include "plugins/data_ports/tGenericPort.h"
44
45//----------------------------------------------------------------------
46// Internal includes with ""
47//----------------------------------------------------------------------
48#include "plugins/composite_ports/tInterfaceBase.h"
49#include "plugins/composite_ports/internal/type_traits.h"
50
51//----------------------------------------------------------------------
52// Namespace declaration
53//----------------------------------------------------------------------
54namespace finroc
55{
56namespace composite_ports
57{
58namespace internal
59{
60
61//----------------------------------------------------------------------
62// Forward declarations / typedefs / enums
63//----------------------------------------------------------------------
64
65
66//----------------------------------------------------------------------
67// Class declaration
68//----------------------------------------------------------------------
69//! Generic port class for port composite interfaces
70/*!
71 * Helper port class to realize generic instantiation of port composite interfaces
72 */
73template < int Tprimary_interface_relations, template <typename> class TPortType, typename T, bool Trpc = IsRPCPort<TPortType>::value, bool Tdirection_specified = IsInputPort<TPortType>::value || IsOutputPort<TPortType>::value >
74class tGenericPortType : public TPortType<T>
75{
76
77//----------------------------------------------------------------------
78// Public methods and typedefs
79//----------------------------------------------------------------------
80public:
81
82  template <typename TParent, typename ... TRest>
83  tGenericPortType(const std::string& name, TParent* parent, const TRest&... rest)
84  {
85    if (!parent->Backend())  // When used for type id extraction
86    {
87      return;
88    }
89
90    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations);
91    if (!parent_backend)
92    {
93      return;
94    }
95    static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), rest...);
96  }
97
98//----------------------------------------------------------------------
99// Private fields and methods
100//----------------------------------------------------------------------
101private:
102
103};
104
105template <int Tprimary_interface_relations, template <typename> class TPortType, typename T>
106class tGenericPortType<Tprimary_interface_relations, TPortType, T, false, false> : public TPortType<T>
107{
108
109//----------------------------------------------------------------------
110// Public methods and typedefs
111//----------------------------------------------------------------------
112public:
113
114  template <typename TParent, typename ... TRest>
115  tGenericPortType(const std::string& name, TParent* parent, const TRest&... rest)
116  {
117    if (!parent->Backend())  // When used for type id extraction
118    {
119      return;
120    }
121
122    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations);
123    if (!parent_backend)
124    {
125      return;
126    }
127    core::tPortWrapperBase::tConstructorArguments<data_ports::tPortCreationInfo<T>> creation_info(name, parent_backend, rrlib::rtti::tDataType<T>(), parent_backend->GetDefaultPortFlags(true), rest...);
128    assert(creation_info.data_type);
129
130    this->SetWrapped(parent_backend->CreatePort(creation_info, Tprimary_interface_relations));
131  }
132
133//----------------------------------------------------------------------
134// Private fields and methods
135//----------------------------------------------------------------------
136private:
137
138};
139
140template <int Tprimary_interface_relations, template <typename> class TPortType, typename T>
141class tGenericPortType<Tprimary_interface_relations, TPortType, T, true, false> : public TPortType<T>
142{
143
144//----------------------------------------------------------------------
145// Public methods and typedefs
146//----------------------------------------------------------------------
147public:
148
149  static_assert(std::is_base_of<rpc_ports::tRPCInterface, T>::value, "Invalid");
150
151  template <typename TParent, typename ... TRest>
152  tGenericPortType(const std::string& name, TParent* parent, const TRest&... rest)
153  {
154    if (!parent->Backend())  // When used for type id extraction
155    {
156      return;
157    }
158
159    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations);
160    if (!parent_backend)
161    {
162      return;
163    }
164
165    // Create port instance via factory
166    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);
167    core::tAbstractPortCreationInfo creation_info;
168    creation_info.name = name;
169    creation_info.parent = parent_backend;
170    creation_info.data_type = rrlib::rtti::tType::FindTypeByRtti(typeid(T).name());
171    creation_info.flags = parent_backend->GetDefaultPortFlags(true) | extra_flags;
172    this->SetWrapped(parent_backend->CreatePort(creation_info, Tprimary_interface_relations));
173  }
174
175//----------------------------------------------------------------------
176// Private fields and methods
177//----------------------------------------------------------------------
178private:
179
180};
181
182
183template <int Tprimary_interface_relations, template <typename> class TPortType, typename T>
184class tGenericPortType<Tprimary_interface_relations, TPortType, T, true, true> : public TPortType<T>
185{
186
187  static_assert(std::is_base_of<rpc_ports::tRPCInterface, T>::value, "Invalid");
188
189//----------------------------------------------------------------------
190// Public methods and typedefs
191//----------------------------------------------------------------------
192public:
193
194  template <typename TParent, typename ... TRest>
195  tGenericPortType(const std::string& name, TParent* parent, TRest&&... rest)
196  {
197    if (!parent->Backend())  // When used for type id extraction
198    {
199      return;
200    }
201
202    tInterfaceBase::tBackend* parent_backend = parent->Backend()->GetBackend(Tprimary_interface_relations);
203    if (!parent_backend)
204    {
205      return;
206    }
207
208    static_cast<TPortType<T>&>(*this) = TPortType<T>(name, parent_backend, parent_backend->GetDefaultPortFlags(false), std::forward<TRest>(rest)...);
209  }
210
211//----------------------------------------------------------------------
212// Private fields and methods
213//----------------------------------------------------------------------
214private:
215
216};
217
218//----------------------------------------------------------------------
219// End of namespace declaration
220//----------------------------------------------------------------------
221}
222}
223}
224
225
226#endif
Note: See TracBrowser for help on using the repository browser.