selxSuperElastixComponent.hxx 10.4 KB
Newer Older
Floris Berendsen's avatar
Floris Berendsen committed
1
2
/*=========================================================================
 *
3
 *  Copyright Leiden University Medical Center, Erasmus University Medical
Floris Berendsen's avatar
Floris Berendsen committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

20
21
#ifndef selxSuperElastixComponent_hxx
#define selxSuperElastixComponent_hxx
22

23
#include "selxInterfaceTraits.h"
Floris Berendsen's avatar
Floris Berendsen committed
24
namespace selx
25
{
26
27
28
29
30
31
template< class InterfaceT >
int
InterfaceAcceptor< InterfaceT >::Connect( ComponentBase * providerComponent )
{
  InterfaceT * providerInterface = dynamic_cast< InterfaceT * >( providerComponent );
  if( !providerInterface )
32
  {
33
34
    //TODO log message?
    //std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl;
35
36
37
    return 0;
  }
  // connect value interfaces
38
  this->Set( providerInterface ); // due to the input argument being uniquely defined in the multiple inheritance tree, all versions of Set() are accessible at component level
39
40
  return 1;
}
41

42
43
44
45
46
47
48
template< class InterfaceT >
bool
InterfaceAcceptor< InterfaceT >::CanAcceptConnectionFrom(ComponentBase * providerComponent)
{
  InterfaceT * providerInterface = dynamic_cast< InterfaceT * >(providerComponent);
  return bool(providerInterface);
}
49

50
//////////////////////////////////////////////////////////////////////////
51
52
53
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
ComponentBase::interfaceStatus
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom( const char * interfacename, ComponentBase * other )
54
{
55
  return AcceptingInterfaces::ConnectFromImpl( interfacename, other );
56
57
}

58
59
60
61

template< typename AcceptingInterfaces, typename ProvidingInterfaces >
int
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom( ComponentBase * other )
62
{
63
  return AcceptingInterfaces::ConnectFromImpl( other );
64
}
65

66
67
68
69

template< typename AcceptingInterfaces, typename ProvidingInterfaces >
bool
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::HasAcceptingInterface( const char * interfacename )
70
{
71
  return AcceptingInterfaces::HasInterface( interfacename );
72
73
}

74
75
76
77

template< typename AcceptingInterfaces, typename ProvidingInterfaces >
bool
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::HasProvidingInterface( const char * interfacename )
78
{
79
  return ProvidingInterfaces::HasInterface( interfacename );
80
81
}

82
83
84
85
86
87
88
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
ComponentBase::interfaceStatus
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >
::CanAcceptConnectionFrom(ComponentBase* other, const InterfaceCriteriaType interfaceCriteria)
{
  return AcceptingInterfaces::CanAcceptConnectionFrom(other, interfaceCriteria);
}
89

90
//////////////////////////////////////////////////////////////////////////
91
92
93
template< typename FirstInterface, typename ... RestInterfaces >
ComponentBase::interfaceStatus
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( const char * interfacename, ComponentBase * other )
94
{
95
96
  // does our component have an accepting interface called interfacename?
  if( InterfaceName< InterfaceAcceptor< FirstInterface >>::Get() == std::string( interfacename ) )
97
  {
98
    // cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
99
    InterfaceAcceptor< FirstInterface > * acceptIF = this;
100
101

    // See if the other component has the right interface and try to connect them
102
    if( 1 == acceptIF->Connect( other ) )
103
104
    {
      //success. By terminating this function, we assume only one interface listens to interfacename and that one connection with the other component can be made by this name
Floris Berendsen's avatar
Floris Berendsen committed
105
      return ComponentBase::interfaceStatus::success;
106
107
108
109
    }
    else
    {
      // interfacename was found, but other component doesn't match
Floris Berendsen's avatar
Floris Berendsen committed
110
      return ComponentBase::interfaceStatus::noprovider;
111
112
    }
  }
113
  return Accepting< RestInterfaces ... >::ConnectFromImpl( interfacename, other );
114
}
115

116
117
118
119

template< typename FirstInterface, typename ... RestInterfaces >
int
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( ComponentBase * other )
120
{
121
  // cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
122
  InterfaceAcceptor< FirstInterface > * acceptIF = ( this );
123
124
125

  // See if the other component has the right interface and try to connect them
  // count the number of successes
126
  return acceptIF->Connect( other ) + Accepting< RestInterfaces ... >::ConnectFromImpl( other );
127
128
}

129
130
131
132

template< typename FirstInterface, typename ... RestInterfaces >
bool
Accepting< FirstInterface, RestInterfaces ... >::HasInterface( const char * interfacename )
133
{
134
  //TODO: check on interface template arguments as well
Floris Berendsen's avatar
Floris Berendsen committed
135
136
137
  auto interfaceProperies = Properties< FirstInterface >::Get();

  if (interfaceProperies["Name"] == std::string(interfacename))
138
139
140
  {
    return true;
  }
141
  return Accepting< RestInterfaces ... >::HasInterface( interfacename );
142
143
}

144
145
146
147
148
149
template< typename FirstInterface, typename ... RestInterfaces >
ComponentBase::interfaceStatus
Accepting< FirstInterface, RestInterfaces ... >::CanAcceptConnectionFrom(ComponentBase* other, const ComponentBase::InterfaceCriteriaType interfaceCriteria)
{

  ComponentBase::interfaceStatus restInterfacesStatus = Accepting< RestInterfaces ... >::CanAcceptConnectionFrom(other, interfaceCriteria);
150
  // if multiple interfaces were a success we do not have to check any further interfaces.
151
152
153
154
  if (restInterfacesStatus == ComponentBase::interfaceStatus::multiple)
  {
    return ComponentBase::interfaceStatus::multiple;
  }
155
  // if a previous interface was a success, we can have either success or multiple (successes)
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  else if (restInterfacesStatus == ComponentBase::interfaceStatus::success)
  {
    unsigned int interfaceMeetsCriteria = Count<FirstInterface>::MeetsCriteria(interfaceCriteria);
    if (interfaceMeetsCriteria == 0) // ComponentBase::interfaceStatus::noacceptor;
    {
      return ComponentBase::interfaceStatus::success;
    }
    else
    {
      InterfaceAcceptor< FirstInterface > * acceptIF = (this);
      if (acceptIF->CanAcceptConnectionFrom(other))
      {
        return ComponentBase::interfaceStatus::multiple;
      }
      else // ComponentBase::interfaceStatus::noprovider
      {
        return ComponentBase::interfaceStatus::success;
      }
    }
  }
176
  // if a previous interface was noprovider, we can have either success or noprovider (we know that there was at least 1 acceptor)
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  else if (restInterfacesStatus == ComponentBase::interfaceStatus::noprovider)
  {
    unsigned int interfaceMeetsCriteria = Count<FirstInterface>::MeetsCriteria(interfaceCriteria);
    if (interfaceMeetsCriteria == 0) // ComponentBase::interfaceStatus::noacceptor;
    {
      return ComponentBase::interfaceStatus::noprovider;
    }
    else
    {
      InterfaceAcceptor< FirstInterface > * acceptIF = (this);
      if (acceptIF->CanAcceptConnectionFrom(other))
      {
        return ComponentBase::interfaceStatus::success;
      }
      else // ComponentBase::interfaceStatus::noprovider
      {
        return ComponentBase::interfaceStatus::noprovider;
      }
    }
  }
197
  // if a previous interface was noaccepter, we can have noaccepter, success or noprovider
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  else if (restInterfacesStatus == ComponentBase::interfaceStatus::noaccepter)
  {
    unsigned int interfaceMeetsCriteria = Count<FirstInterface>::MeetsCriteria(interfaceCriteria);
    if (interfaceMeetsCriteria == 0) // ComponentBase::interfaceStatus::noacceptor;
    {
      return ComponentBase::interfaceStatus::noaccepter;
    }
    else
    {
      InterfaceAcceptor< FirstInterface > * acceptIF = (this);
      if (acceptIF->CanAcceptConnectionFrom(other))
      {
        return ComponentBase::interfaceStatus::success;
      }
      else // ComponentBase::interfaceStatus::noprovider
      {
        return ComponentBase::interfaceStatus::noprovider;
      }
    }
  }
218
219
  // never reached
  return ComponentBase::interfaceStatus::noaccepter;
220
221
222
223
224
225
}


  


226
227
228
229

template< typename FirstInterface, typename ... RestInterfaces >
bool
Providing< FirstInterface, RestInterfaces ... >::HasInterface( const char * interfacename )
230
{
231
  //TODO: check on interface template arguments as well
Floris Berendsen's avatar
Floris Berendsen committed
232
233
234
  auto interfaceProperies = Properties< FirstInterface >::Get();

  if (interfaceProperies["Name"] == std::string(interfacename))
235
236
237
  {
    return true;
  }
238
  return Providing< RestInterfaces ... >::HasInterface( interfacename );
239
}
Floris Berendsen's avatar
Floris Berendsen committed
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257


template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Accepting< FirstInterface, RestInterfaces ... >::CountMeetsCriteria(const ComponentBase::InterfaceCriteriaType interfaceCriteria)
{
  return Count<FirstInterface, RestInterfaces ... >::MeetsCriteria(interfaceCriteria);
}

template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Providing< FirstInterface, RestInterfaces ... >::CountMeetsCriteria(const ComponentBase::InterfaceCriteriaType interfaceCriteria)
{
  return Count<FirstInterface, RestInterfaces ... >::MeetsCriteria(interfaceCriteria);
}


Floris Berendsen's avatar
Floris Berendsen committed
258
template <typename FirstInterface, typename ... RestInterfaces>
259
unsigned int Count<FirstInterface, RestInterfaces ...>::MeetsCriteria(const ComponentBase::InterfaceCriteriaType interfaceCriteria)
Floris Berendsen's avatar
Floris Berendsen committed
260
261
262
263
264
265
266
267
268
{
  auto interfaceProperies = Properties< FirstInterface >::Get();
  for (const auto keyAndValue : interfaceCriteria)
  {
    auto && key = keyAndValue.first;
    auto && value = keyAndValue.second;
    if (interfaceProperies.count(key) != 1 || interfaceProperies[key].compare(value)!=0 )
    {
      // as soon as any of the criteria fails we break the loop and test the RestInterfaces
269
      return Count< RestInterfaces ... >::MeetsCriteria(interfaceCriteria);
Floris Berendsen's avatar
Floris Berendsen committed
270
271
272
    }
  }
  // if all criteria are met for this Interface we add 1 to the count and continue with the RestInterfaces
273
  return 1 + Count< RestInterfaces ... >::MeetsCriteria(interfaceCriteria);
Floris Berendsen's avatar
Floris Berendsen committed
274
275
};

Floris Berendsen's avatar
Floris Berendsen committed
276
} // end namespace selx
277

278
#endif // #define selxSuperElastixComponent_hxx