Commit 41ebbe6c authored by Floris Berendsen's avatar Floris Berendsen
Browse files

WIP: put each class in its own h and hxx file

parent 4b395dc1
......@@ -20,7 +20,7 @@
#ifndef selxExamplesInterfaces_h
#define selxExamplesInterfaces_h
#include selxInterfaces.h
#include "selxInterfaces.h"
namespace selx
{
......
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Accepting_hxx
#define Accepting_hxx
namespace selx
{
template< typename FirstInterface, typename ... RestInterfaces >
int
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( ComponentBase * other,
const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
// Does our component have an accepting interface sufficing the right criteria (e.g interfaceName)?
if( Count< FirstInterface >::MeetsCriteria( interfaceCriteria ) == 1 ) // We use the FirstInterface only (of each recursion level), thus the count can be 0 or 1
{
// cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
InterfaceAcceptor< FirstInterface > * acceptIF = this;
// Make the connection to the other component by this interface and add the number of successes.
return acceptIF->Connect( other ) + Accepting< RestInterfaces ... >::ConnectFromImpl( other, interfaceCriteria );
}
else
{
return Accepting< RestInterfaces ... >::ConnectFromImpl( other, interfaceCriteria );
}
}
template< typename FirstInterface, typename ... RestInterfaces >
int
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( ComponentBase * other )
{
// cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
InterfaceAcceptor< FirstInterface > * acceptIF = ( this );
// See if the other component has the right interface and try to connect them
// count the number of successes
return acceptIF->Connect( other ) + Accepting< RestInterfaces ... >::ConnectFromImpl( other );
}
template< typename FirstInterface, typename ... RestInterfaces >
InterfaceStatus
Accepting< FirstInterface, RestInterfaces ... >::CanAcceptConnectionFrom( ComponentBase * other,
const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
InterfaceStatus restInterfacesStatus = Accepting< RestInterfaces ... >::CanAcceptConnectionFrom( other, interfaceCriteria );
// if multiple interfaces were a success we do not have to check any further interfaces.
if( restInterfacesStatus == InterfaceStatus::multiple )
{
return InterfaceStatus::multiple;
}
// We use the FirstInterface only (of each recursion level), thus the count can be 0 or 1
unsigned int interfaceMeetsCriteria = Count< FirstInterface >::MeetsCriteria( interfaceCriteria );
if( interfaceMeetsCriteria == 0 ) // InterfaceStatus::noaccepter;
{
// no new success, keep the status of previous recursion
return restInterfacesStatus;
}
else // This "FirstInterface" of the component is an acceptor interface that fulfills the criteria
{
InterfaceAcceptor< FirstInterface > * acceptIF = ( this );
if( acceptIF->CanAcceptConnectionFrom( other ) )
{
// if a previous interface was a success, we can have either success or multiple (successes)
if( restInterfacesStatus == InterfaceStatus::success )
{
return InterfaceStatus::multiple;
}
return InterfaceStatus::success;
}
else // InterfaceStatus::noprovider
{
// The found acceptor interface is not identical to a providing interface of the other component
if( restInterfacesStatus == InterfaceStatus::noaccepter )
{
return InterfaceStatus::noprovider;
}
return restInterfacesStatus;
}
}
// never reached
return InterfaceStatus::noaccepter;
}
template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Accepting< FirstInterface, RestInterfaces ... >::CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
return Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
}
} //end namespace selx
#endif // Accepting_hxx
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Accepting_h
#define Accepting_h
namespace selx
{
template< typename ... Interfaces >
class Accepting;
template< >
class Accepting< >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
int ConnectFromImpl( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria ) { return 0; } //no interface called interfacename ;
InterfaceStatus CanAcceptConnectionFrom( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
return InterfaceStatus::noaccepter;
}
int ConnectFromImpl( ComponentBase * ) { return 0; } //Empty RestInterfaces does 0 successful connects ;
protected:
};
template< typename FirstInterface, typename ... RestInterfaces >
class Accepting< FirstInterface, RestInterfaces ... > : public InterfaceAcceptor< FirstInterface >, public Accepting< RestInterfaces ... >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType );
int ConnectFromImpl( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria );
InterfaceStatus CanAcceptConnectionFrom( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria );
int ConnectFromImpl( ComponentBase * );
protected:
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxAccepting.hxx"
#endif
#endif // Accepting_h
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Count_h
#define Count_h
namespace selx
{
// helper class for SuperElastixComponent::CountAcceptingInterfaces and SuperElastixComponent::CountProvidingInterfaces to loop over a set of interfaces
template< typename ... Interfaces >
struct Count;
template< >
struct Count< >
{
static unsigned int MeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
};
template< typename FirstInterface, typename ... RestInterfaces >
struct Count< FirstInterface, RestInterfaces ... >
{
static unsigned int MeetsCriteria( const ComponentBase::InterfaceCriteriaType );
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxCount.hxx"
#endif
#endif // Count_h
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Count_hxx
#define Count_hxx
namespace selx
{
template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
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
return Count< RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
}
}
// if all criteria are met for this Interface we add 1 to the count and continue with the RestInterfaces
return 1 + Count< RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
}
} //end namespace selx
#endif // Count_hxx
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef InterfaceAcceptor_h
#define InterfaceAcceptor_h
namespace selx
{
// All SuperElastix Components inherit from their interfaces classes. The interface classes as defined in
// "selxInterfaces.h" are by default Providing. The InterfaceAcceptor class turns a Providing interface
// into an Accepting interface. For a SuperElastixComponent this differentiation is done by grouping the
// interfaces either in Providing<Interfaces...> or in Accepting<Interfaces...>
template< class InterfaceT >
class InterfaceAcceptor
{
public:
// Set() is called by a succesfull Connect()
// The implementation of Set() must be provided by component developers.
virtual int Set( InterfaceT * ) = 0;
// Connect tries to connect this accepting interface with all interfaces of the provider component.
int Connect( ComponentBase * );
bool CanAcceptConnectionFrom( ComponentBase * );
private:
bool isSet;
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxInterfaceAcceptor.hxx"
#endif
#endif // InterfaceAcceptor_h
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef InterfaceAcceptor_hxx
#define InterfaceAcceptor_hxx
namespace selx
{
template< class InterfaceT >
int
InterfaceAcceptor< InterfaceT >::Connect( ComponentBase * providerComponent )
{
InterfaceT * providerInterface = dynamic_cast< InterfaceT * >( providerComponent );
if( !providerInterface )
{
//TODO log message?
//std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl;
return 0;
}
// connect value interfaces
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
return 1;
}
template< class InterfaceT >
bool
InterfaceAcceptor< InterfaceT >::CanAcceptConnectionFrom( ComponentBase * providerComponent )
{
InterfaceT * providerInterface = dynamic_cast< InterfaceT * >( providerComponent );
return bool(providerInterface);
}
} //end namespace selx
#endif // InterfaceAcceptor_hxx
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Providing_h
#define Providing_h
namespace selx
{
template< typename ... Interfaces >
class Providing;
template< >
class Providing< >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
protected:
};
template< typename FirstInterface, typename ... RestInterfaces >
class Providing< FirstInterface, RestInterfaces ... > : public FirstInterface, public Providing< RestInterfaces ... >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType );
protected:
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxProviding.hxx"
#endif
#endif // Providing_h
\ No newline at end of file
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* 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.
*
*=========================================================================*/
#ifndef Providing_hxx
#define Providing_hxx
namespace selx
{
template< typename FirstInterface, typename ... RestInterfaces >
unsigned int
Providing< FirstInterface, RestInterfaces ... >::CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
return Count< FirstInterface, RestInterfaces ... >::MeetsCriteria( interfaceCriteria );
}
} //end namespace selx
#endif // Providing_hxx
\ No newline at end of file
......@@ -24,113 +24,14 @@
#include "selxComponentBase.h"
#include <typeinfo>
#include <string>
#include "selxInterfaceAcceptor.h"
#include "selxAccepting.h"
#include "selxProviding.h"
#include "selxCount.h"
#include "selxInterfaceTraits.h"
#include "selxInterfaces.h"
namespace selx
{
// All SuperElastix Components inherit from their interfaces classes. The interface classes as defined in
// "selxInterfaces.h" are by default Providing. The InterfaceAcceptor class turns a Providing interface
// into an Accepting interface. For a SuperElastixComponent this differentiation is done by grouping the
// interfaces either in Providing<Interfaces...> or in Accepting<Interfaces...>
template< class InterfaceT >
class InterfaceAcceptor
{
public:
// Set() is called by a succesfull Connect()
// The implementation of Set() must be provided by component developers.
virtual int Set( InterfaceT * ) = 0;
// Connect tries to connect this accepting interface with all interfaces of the provider component.
int Connect( ComponentBase * );
bool CanAcceptConnectionFrom( ComponentBase * );
private:
bool isSet;
};
template< typename ... Interfaces >
class Accepting;
template< >
class Accepting< >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
int ConnectFromImpl( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria ) { return 0; } //no interface called interfacename ;
InterfaceStatus CanAcceptConnectionFrom( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria )
{
return InterfaceStatus::noaccepter;
}
int ConnectFromImpl( ComponentBase * ) { return 0; } //Empty RestInterfaces does 0 successful connects ;
protected:
};
template< typename FirstInterface, typename ... RestInterfaces >
class Accepting< FirstInterface, RestInterfaces ... > : public InterfaceAcceptor< FirstInterface >, public Accepting< RestInterfaces ... >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType );
int ConnectFromImpl( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria );
InterfaceStatus CanAcceptConnectionFrom( ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria );
int ConnectFromImpl( ComponentBase * );
protected:
};
template< typename ... Interfaces >
class Providing;
template< >
class Providing< >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
protected:
};
template< typename FirstInterface, typename ... RestInterfaces >
class Providing< FirstInterface, RestInterfaces ... > : public FirstInterface, public Providing< RestInterfaces ... >
{
public:
static unsigned int CountMeetsCriteria( const ComponentBase::InterfaceCriteriaType );
protected:
};
//template<typename... Interfaces>
//class Providing : public Interfaces...
//{
//};
// helper class for SuperElastixComponent::CountAcceptingInterfaces and SuperElastixComponent::CountProvidingInterfaces to loop over a set of interfaces
template< typename ... Interfaces >
struct Count;
template< >
struct Count< >
{
static unsigned int MeetsCriteria( const ComponentBase::InterfaceCriteriaType ) { return 0; }
};
template< typename FirstInterface, typename ... RestInterfaces >
struct Count< FirstInterface, RestInterfaces ... >
{
static unsigned int MeetsCriteria( const ComponentBase::InterfaceCriteriaType );
};
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
class SuperElastixComponent :