selxSuperElastixComponent.hxx 7.65 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

Floris Berendsen's avatar
Floris Berendsen committed
42

43
44
template< class InterfaceT >
bool
Floris Berendsen's avatar
Floris Berendsen committed
45
InterfaceAcceptor< InterfaceT >::CanAcceptConnectionFrom( ComponentBase * providerComponent )
46
{
Floris Berendsen's avatar
Floris Berendsen committed
47
  InterfaceT * providerInterface = dynamic_cast< InterfaceT * >( providerComponent );
48
49
  return bool(providerInterface);
}
50

Floris Berendsen's avatar
Floris Berendsen committed
51

52
//////////////////////////////////////////////////////////////////////////
53
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
54
int
Floris Berendsen's avatar
Floris Berendsen committed
55
56
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom( ComponentBase * other,
  const InterfaceCriteriaType interfaceCriteria )
57
{
Floris Berendsen's avatar
Floris Berendsen committed
58
  return AcceptingInterfaces::ConnectFromImpl( other, interfaceCriteria );
59
60
}

61
62
63
64

template< typename AcceptingInterfaces, typename ProvidingInterfaces >
int
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom( ComponentBase * other )
65
{
66
  return AcceptingInterfaces::ConnectFromImpl( other );
67
}
68

Floris Berendsen's avatar
Floris Berendsen committed
69

70
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
71
InterfaceStatus
72
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >
Floris Berendsen's avatar
Floris Berendsen committed
73
::CanAcceptConnectionFrom( ComponentBase * other, const InterfaceCriteriaType interfaceCriteria )
74
{
Floris Berendsen's avatar
Floris Berendsen committed
75
  return AcceptingInterfaces::CanAcceptConnectionFrom( other, interfaceCriteria );
76
}
77

Floris Berendsen's avatar
Floris Berendsen committed
78

79
//////////////////////////////////////////////////////////////////////////
80
template< typename FirstInterface, typename ... RestInterfaces >
81
int
Floris Berendsen's avatar
Floris Berendsen committed
82
83
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( ComponentBase * other,
  const ComponentBase::InterfaceCriteriaType interfaceCriteria )
84
{
85
  // Does our component have an accepting interface sufficing the right criteria (e.g interfaceName)?
Floris Berendsen's avatar
Floris Berendsen committed
86
  if( Count< FirstInterface >::MeetsCriteria( interfaceCriteria ) == 1 )   // We use the FirstInterface only (of each recursion level), thus the count can be 0 or 1
87
  {
88
    // cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
89
    InterfaceAcceptor< FirstInterface > * acceptIF = this;
90
    // Make the connection to the other component by this interface and add the number of successes.
Floris Berendsen's avatar
Floris Berendsen committed
91
    return acceptIF->Connect( other ) + Accepting< RestInterfaces ... >::ConnectFromImpl( other, interfaceCriteria );
92
93
94
  }
  else
  {
Floris Berendsen's avatar
Floris Berendsen committed
95
    return Accepting< RestInterfaces ... >::ConnectFromImpl( other, interfaceCriteria );
96
97
  }
}
98

99
100
101
102

template< typename FirstInterface, typename ... RestInterfaces >
int
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( ComponentBase * other )
103
{
104
  // cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
105
  InterfaceAcceptor< FirstInterface > * acceptIF = ( this );
106
107
108

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

112

113
template< typename FirstInterface, typename ... RestInterfaces >
114
InterfaceStatus
Floris Berendsen's avatar
Floris Berendsen committed
115
116
Accepting< FirstInterface, RestInterfaces ... >::CanAcceptConnectionFrom( ComponentBase * other,
  const ComponentBase::InterfaceCriteriaType interfaceCriteria )
117
{
Floris Berendsen's avatar
Floris Berendsen committed
118
  InterfaceStatus restInterfacesStatus = Accepting< RestInterfaces ... >::CanAcceptConnectionFrom( other, interfaceCriteria );
119
  // if multiple interfaces were a success we do not have to check any further interfaces.
Floris Berendsen's avatar
Floris Berendsen committed
120
  if( restInterfacesStatus == InterfaceStatus::multiple )
121
  {
122
    return InterfaceStatus::multiple;
123
  }
124
  // We use the FirstInterface only (of each recursion level), thus the count can be 0 or 1
Floris Berendsen's avatar
Floris Berendsen committed
125
126
  unsigned int interfaceMeetsCriteria = Count< FirstInterface >::MeetsCriteria( interfaceCriteria );
  if( interfaceMeetsCriteria == 0 ) // InterfaceStatus::noaccepter;
127
  {
128
129
    // no new success, keep the status of previous recursion
    return restInterfacesStatus;
130
  }
131
  else // This "FirstInterface" of the component is an acceptor interface that fulfills the criteria
132
  {
Floris Berendsen's avatar
Floris Berendsen committed
133
134
    InterfaceAcceptor< FirstInterface > * acceptIF = ( this );
    if( acceptIF->CanAcceptConnectionFrom( other ) )
135
    {
136
      // if a previous interface was a success, we can have either success or multiple (successes)
Floris Berendsen's avatar
Floris Berendsen committed
137
138
      if( restInterfacesStatus == InterfaceStatus::success )
      {
139
        return InterfaceStatus::multiple;
Floris Berendsen's avatar
Floris Berendsen committed
140
      }
141
      return InterfaceStatus::success;
142
    }
143
    else // InterfaceStatus::noprovider
144
    {
145
      // The found acceptor interface is not identical to a providing interface of the other component
Floris Berendsen's avatar
Floris Berendsen committed
146
147
      if( restInterfacesStatus == InterfaceStatus::noaccepter )
      {
148
        return InterfaceStatus::noprovider;
Floris Berendsen's avatar
Floris Berendsen committed
149
      }
150
      return restInterfacesStatus;
151
152
    }
  }
153
  // never reached
154
  return InterfaceStatus::noaccepter;
155
156
}

157
158
159

template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Floris Berendsen's avatar
Floris Berendsen committed
160
Accepting< FirstInterface, RestInterfaces ... >::CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
161
{
Floris Berendsen's avatar
Floris Berendsen committed
162
  return Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
163
164
}

Floris Berendsen's avatar
Floris Berendsen committed
165

166
167
template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Floris Berendsen's avatar
Floris Berendsen committed
168
Providing< FirstInterface, RestInterfaces ... >::CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
169
{
Floris Berendsen's avatar
Floris Berendsen committed
170
  return Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
171
172
173
}


Floris Berendsen's avatar
Floris Berendsen committed
174
175
176
template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
Floris Berendsen's avatar
Floris Berendsen committed
177
178
{
  auto interfaceProperies = Properties< FirstInterface >::Get();
Floris Berendsen's avatar
Floris Berendsen committed
179
  for( const auto keyAndValue : interfaceCriteria )
Floris Berendsen's avatar
Floris Berendsen committed
180
  {
Floris Berendsen's avatar
Floris Berendsen committed
181
    auto && key   = keyAndValue.first;
Floris Berendsen's avatar
Floris Berendsen committed
182
    auto && value = keyAndValue.second;
Floris Berendsen's avatar
Floris Berendsen committed
183
    if( interfaceProperies.count( key ) != 1 || interfaceProperies[ key ].compare( value ) != 0 )
Floris Berendsen's avatar
Floris Berendsen committed
184
185
    {
      // as soon as any of the criteria fails we break the loop and test the RestInterfaces
Floris Berendsen's avatar
Floris Berendsen committed
186
      return Count< RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
Floris Berendsen's avatar
Floris Berendsen committed
187
188
189
    }
  }
  // if all criteria are met for this Interface we add 1 to the count and continue with the RestInterfaces
Floris Berendsen's avatar
Floris Berendsen committed
190
191
  return 1 + Count< RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
}
Floris Berendsen's avatar
Floris Berendsen committed
192
} // end namespace selx
193

194
#endif // #define selxSuperElastixComponent_hxx