diff --git a/Modules/Core/ComponentInterface/include/InterfaceTraits.h b/Modules/Core/ComponentInterface/include/InterfaceTraits.h new file mode 100644 index 0000000000000000000000000000000000000000..5dd03ec37bccab68b6be2b1450cb6d588532d0e5 --- /dev/null +++ b/Modules/Core/ComponentInterface/include/InterfaceTraits.h @@ -0,0 +1,69 @@ +#ifndef InterfaceTraits_h +#define InterfaceTraits_h + +#include "Interfaces.h" + +namespace elx +{ +// Traits to get printable interface name +// default implementation +template <typename T> +struct InterfaceName +{ + static const char* Get() + { + return typeid(T).name(); + } +}; + +// a specialization for each type of those you want to support +// and don't like the string returned by typeid +template <> +struct InterfaceName < MetricValueInterface > +{ + static const char* Get() + { + return "MetricValueInterface"; + } +}; +template <> +struct InterfaceName < MetricDerivativeInterface > +{ + static const char* Get() + { + return "MetricDerivativeInterface"; + } +}; +template <> +struct InterfaceName < OptimizerUpdateInterface > +{ + static const char* Get() + { + return "OptimizerUpdateInterface"; + } +}; + + +// partial specialization of InterfaceName +template<template<typename> class TT, typename T1> +struct InterfaceName < TT<T1> > { + static const char* Get() + { + return InterfaceName<T1>::Get(); + } +}; + + +template <typename T> +struct AcceptorInterfaceName +{ + static const char* Get() + { + return InterfaceName<T>::Get(); + } +}; + +} // end namespace elx + + +#endif // #define InterfaceTraits_h \ No newline at end of file diff --git a/Modules/Core/ComponentInterface/include/Interfaces.h b/Modules/Core/ComponentInterface/include/Interfaces.h new file mode 100644 index 0000000000000000000000000000000000000000..281d763d3ebbaf8608afb70fd02bdf98b0b9ce57 --- /dev/null +++ b/Modules/Core/ComponentInterface/include/Interfaces.h @@ -0,0 +1,78 @@ +#ifndef Interfaces_h +#define Interfaces_h + +#include "ComponentBase.h" +#include "InterfaceTraits.h" +#include <typeinfo> + +namespace elx +{ +// Define the providing interfaces abstractly +class MetricDerivativeInterface { + public: + virtual int GetDerivative() = 0; +}; + +class MetricValueInterface { + public: + virtual int GetValue() = 0; +}; + +class OptimizerUpdateInterface { +public: + virtual int Update() = 0; +}; + +// Define the accepting interfaces as templated by the providing interface + +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*); + +private: + bool isSet; +}; + +template<typename ... RestInterfaces> +class Accepting +{ + public: + interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ; + int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ; +}; + +template<typename FirstInterface, typename ... RestInterfaces> +class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > +{ +public: + interfaceStatus ConnectFromImpl(const char *, ComponentBase*); + int ConnectFromImpl(ComponentBase*); +}; + +template<typename... Interfaces> +class Providing : public Interfaces... +{ +}; + +template<typename AcceptingInterfaces, typename ProvidingInterfaces> +class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase +{ + public: + virtual interfaceStatus ConnectFrom(const char *, ComponentBase*); + virtual int ConnectFrom(ComponentBase*); +}; + +} // end namespace elx + +#ifndef ITK_MANUAL_INSTANTIATION +#include "Interfaces.hxx" +#endif + +#endif // #define Interfaces_h \ No newline at end of file diff --git a/Modules/Core/ComponentInterface/include/Interfaces.hxx b/Modules/Core/ComponentInterface/include/Interfaces.hxx index 7b309ca0366759873cdc120024747b17faaaa702..cade1ce157abcb8b48165d0993ff80785a50d2dd 100644 --- a/Modules/Core/ComponentInterface/include/Interfaces.hxx +++ b/Modules/Core/ComponentInterface/include/Interfaces.hxx @@ -1,141 +1,9 @@ #ifndef Interfaces_hxx #define Interfaces_hxx -#include "ComponentBase.h" -#include <typeinfo> - +#include "InterfaceTraits.h" namespace elx { -// Define the providing interfaces abstractly -class MetricDerivativeInterface { - public: - virtual int GetDerivative() = 0; -}; - -class MetricValueInterface { - public: - virtual int GetValue() = 0; -}; - -class OptimizerUpdateInterface { -public: - virtual int Update() = 0; -}; - -// Define the accepting interfaces as templated by the providing interface - -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*); - -private: - bool isSet; -}; - -template<typename ... RestInterfaces> -class Accepting -{ - public: - interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ; - int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ; -}; - -template<typename FirstInterface, typename ... RestInterfaces> -class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > -{ -public: - interfaceStatus ConnectFromImpl(const char *, ComponentBase*); - int ConnectFromImpl(ComponentBase*); -}; - -template<typename... Interfaces> -class Providing : public Interfaces... -{ -}; - -template<typename AcceptingInterfaces, typename ProvidingInterfaces> -class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase -{ - public: - virtual interfaceStatus ConnectFrom(const char *, ComponentBase*); - virtual int ConnectFrom(ComponentBase*); -}; - - -// TEST -template<class InterfaceT> -class InterfaceProvider { -public: - virtual int Set(InterfaceT*) {}; -private: -}; - - -// Traits to get printable interface name -// default implementation -template <typename T> -struct InterfaceName -{ - static const char* Get() - { - return typeid(T).name(); - } -}; - -// a specialization for each type of those you want to support -// and don't like the string returned by typeid -template <> -struct InterfaceName < MetricValueInterface > -{ - static const char* Get() - { - return "MetricValueInterface"; - } -}; -template <> -struct InterfaceName < MetricDerivativeInterface > -{ - static const char* Get() - { - return "MetricDerivativeInterface"; - } -}; -template <> -struct InterfaceName < OptimizerUpdateInterface > -{ - static const char* Get() - { - return "OptimizerUpdateInterface"; - } -}; - - -// partial specialization of InterfaceName -template<template<typename> class TT, typename T1> -struct InterfaceName < TT<T1> > { - static const char* Get() - { - return InterfaceName<T1>::Get(); - } -}; - - -template <typename T> -struct AcceptorInterfaceName -{ - static const char* Get() - { - return InterfaceName<T>::Get(); - } -}; - template<class InterfaceT> int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ @@ -150,12 +18,6 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ return 1; } -//template<template<typename... RestInterfacesT> class AcceptingT, typename ProvidingT> -//interfaceStatus Implements<AcceptingT<RestInterfacesT... >, ProvidingT>::ConnectFrom(const char * interfacename, ComponentBase* other) -//{ -// :ConnectFrom(const char * interfacename, ComponentBase* other) -//} - template<typename AcceptingInterfaces, typename ProvidingInterfaces> interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other) { @@ -204,4 +66,6 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase } } // end namespace elx + + #endif // #define Interfaces_hxx \ No newline at end of file