Commit 4ef334b0 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

WIP: Several:

- Changed to namespace selx
- Combined componentbase classes and based it on itkLightObject
- Initial combination of example components
- Made templated ComponentFactory to replace all specific factories
parent aa6f864e
#ifndef ComponentBase_h #ifndef ComponentBase_h
#define ComponentBase_h #define ComponentBase_h
#include "itkLightObject.h"
#include "itkObjectFactory.h"
//#include "itkComponentBase.h"
#include <list>
#include <iostream> #include <iostream>
#include <cstring> #include <fstream>
namespace elx #include <string>
#include <map>
namespace selx
{ {
enum interfaceStatus { success, noaccepter, noprovider };
class ComponentBase { class ComponentBase : public itk::LightObject
{
public: public:
/** Standard class typedefs */
typedef ComponentBase Self;
typedef itk::LightObject Superclass;
typedef itk::SmartPointer< Self > Pointer;
/** Run-time type information (and related methods). */
itkTypeMacro(ComponentBase, Superclass);
typedef std::map<std::string, std::string> CriteriaType;
typedef std::pair<std::string, std::string> CriteriumType;
enum interfaceStatus { success, noaccepter, noprovider };
virtual interfaceStatus ConnectFrom(const char *, ComponentBase*) = 0; virtual interfaceStatus ConnectFrom(const char *, ComponentBase*) = 0;
virtual int ConnectFrom(ComponentBase*) = 0; virtual int ConnectFrom(ComponentBase*) = 0;
//protected: virtual bool MeetsCriteria(const CriteriaType &criteria) = 0;
protected:
ComponentBase() {};
virtual ~ComponentBase() {}; virtual ~ComponentBase() {};
}; };
} // end namespace elx
#endif // #define ComponentBase_h } // end namespace selx
\ No newline at end of file
#endif // ComponentBase_h
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "Metric3rdPartyWrapper.h" #include "Metric3rdPartyWrapper.h"
#include <string.h> #include <string.h>
namespace elx namespace selx
{ {
class GDOptimizer3rdPartyComponent : class GDOptimizer3rdPartyComponent :
...@@ -25,6 +25,9 @@ namespace elx ...@@ -25,6 +25,9 @@ namespace elx
int Set(MetricValueInterface*); int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*); int Set(MetricDerivativeInterface*);
int Update(); int Update();
virtual bool MeetsCriteria(const CriteriaType &criteria) { return false; };
static const char * GetName() { return "GDOptimizer3rdPartyComponent"; } ;
static const char * GetDescription() { return "GD Optimizer 3rd Party Component"; };
}; };
} //end namespace elx } //end namespace selx
#endif // #define GDOptimizer3rdPartyComponent_h #endif // #define GDOptimizer3rdPartyComponent_h
\ No newline at end of file
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include "Example4thPartyCode.h" #include "Example4thPartyCode.h"
#include "Metric4thPartyWrapper.h" #include "Metric4thPartyWrapper.h"
namespace elx namespace selx
{ {
// wrapping into components: // wrapping into components:
class GDOptimizer4thPartyComponent : class GDOptimizer4thPartyComponent :
...@@ -28,7 +28,10 @@ namespace elx ...@@ -28,7 +28,10 @@ namespace elx
//template <class ConflictinUpdateInterface> virtual int Update() { return 5; }; //template <class ConflictinUpdateInterface> virtual int Update() { return 5; };
// "error" : member function templates cannot be virtual // "error" : member function templates cannot be virtual
int Update(ConflictinUpdateInterface*) { return 5; }; int Update(ConflictinUpdateInterface*) { return 5; };
virtual bool MeetsCriteria(const CriteriaType &criteria) { return false; };
static const char * GetName(){ return "GDOptimizer4thPartyComponent"; };
static const char * GetDescription(){ return "GD Optimizer 4th Party Component"; };
}; };
} //end namespace elx } //end namespace selx
#endif // #define GDOptimizer4thPartyComponent_h #endif // #define GDOptimizer4thPartyComponent_h
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "Interfaces.h" #include "Interfaces.h"
namespace elx namespace selx
{ {
// Traits to get printable interface name // Traits to get printable interface name
// default implementation // default implementation
...@@ -12,6 +12,7 @@ struct InterfaceName ...@@ -12,6 +12,7 @@ struct InterfaceName
{ {
static const char* Get() static const char* Get()
{ {
static_assert(false, "Please implement a template specialization for the appropriate InterfaceName")
return typeid(T).name(); return typeid(T).name();
} }
}; };
...@@ -43,6 +44,16 @@ struct InterfaceName < OptimizerUpdateInterface > ...@@ -43,6 +44,16 @@ struct InterfaceName < OptimizerUpdateInterface >
} }
}; };
template <>
struct InterfaceName < TransformedImageInterface >
{
static const char* Get()
{
return "TransformedImageInterface";
}
};
// partial specialization of InterfaceName // partial specialization of InterfaceName
template<template<typename> class TT, typename T1> template<template<typename> class TT, typename T1>
...@@ -63,7 +74,7 @@ struct AcceptorInterfaceName ...@@ -63,7 +74,7 @@ struct AcceptorInterfaceName
} }
}; };
} // end namespace elx } // end namespace selx
#endif // #define InterfaceTraits_h #endif // #define InterfaceTraits_h
\ No newline at end of file
...@@ -2,60 +2,66 @@ ...@@ -2,60 +2,66 @@
#define Interfaces_h #define Interfaces_h
#include "ComponentBase.h" #include "ComponentBase.h"
#include "InterfaceTraits.h"
#include <typeinfo> #include <typeinfo>
namespace elx namespace selx
{ {
// Define the providing interfaces abstractly // Define the providing interfaces abstractly
class MetricDerivativeInterface { class MetricDerivativeInterface {
public: public:
virtual int GetDerivative() = 0; virtual int GetDerivative() = 0;
}; };
class MetricValueInterface { class MetricValueInterface {
public: public:
virtual int GetValue() = 0; virtual int GetValue() = 0;
}; };
class OptimizerUpdateInterface { class OptimizerUpdateInterface {
public: public:
virtual int Update() = 0; virtual int Update() = 0;
}; };
class ConflictinUpdateInterface { class TransformedImageInterface {
public: public:
// "error" : member function templates cannot be virtual virtual int GetTransformedImage() = 0;
// template <class ConflictinUpdateInterface> virtual int Update() = 0; };
//TODO http://en.cppreference.com/w/cpp/language/member_template
//TODO solution: http://stackoverflow.com/questions/2004820/inherit-interfaces-which-share-a-method-name class ConflictinUpdateInterface {
//TODO better?: http://stackoverflow.com/questions/18398409/c-inherit-from-multiple-base-classes-with-the-same-virtual-function-name public:
virtual int Update(ConflictinUpdateInterface*) = 0; // "error" : member function templates cannot be virtual
}; // template <class ConflictinUpdateInterface> virtual int Update() = 0;
//TODO http://en.cppreference.com/w/cpp/language/member_template
// Define the accepting interfaces as templated by the providing interface //TODO solution: http://stackoverflow.com/questions/2004820/inherit-interfaces-which-share-a-method-name
//TODO better?: http://stackoverflow.com/questions/18398409/c-inherit-from-multiple-base-classes-with-the-same-virtual-function-name
virtual int Update(ConflictinUpdateInterface*) = 0;
};
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. // Define the accepting interfaces as templated by the providing interface
int Connect(ComponentBase*);
private: template<class InterfaceT>
bool isSet; 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> template<typename ... RestInterfaces>
class Accepting class Accepting
{ {
public: public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ; ComponentBase::interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return ComponentBase::interfaceStatus::noaccepter; }; //no interface called interfacename ;
int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ; int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ;
}; };
...@@ -63,7 +69,7 @@ template<typename FirstInterface, typename ... RestInterfaces> ...@@ -63,7 +69,7 @@ template<typename FirstInterface, typename ... RestInterfaces>
class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... >
{ {
public: public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*); ComponentBase::interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
int ConnectFromImpl(ComponentBase*); int ConnectFromImpl(ComponentBase*);
}; };
...@@ -80,7 +86,7 @@ class Implements : public AcceptingInterfaces, public ProvidingInterfaces, publi ...@@ -80,7 +86,7 @@ class Implements : public AcceptingInterfaces, public ProvidingInterfaces, publi
virtual int ConnectFrom(ComponentBase*); virtual int ConnectFrom(ComponentBase*);
}; };
} // end namespace elx } // end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION #ifndef ITK_MANUAL_INSTANTIATION
#include "Interfaces.hxx" #include "Interfaces.hxx"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define Interfaces_hxx #define Interfaces_hxx
#include "InterfaceTraits.h" #include "InterfaceTraits.h"
namespace elx namespace selx
{ {
template<class InterfaceT> template<class InterfaceT>
int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
...@@ -19,7 +19,7 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ ...@@ -19,7 +19,7 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
} }
template<typename AcceptingInterfaces, typename ProvidingInterfaces> template<typename AcceptingInterfaces, typename ProvidingInterfaces>
interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other) ComponentBase::interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other)
{ {
return AcceptingInterfaces::ConnectFromImpl(interfacename, other); return AcceptingInterfaces::ConnectFromImpl(interfacename, other);
} }
...@@ -31,7 +31,7 @@ int Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(ComponentB ...@@ -31,7 +31,7 @@ int Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(ComponentB
} }
template<typename FirstInterface, typename ... RestInterfaces> template<typename FirstInterface, typename ... RestInterfaces>
interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(const char * interfacename, ComponentBase* other) ComponentBase::interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(const char * interfacename, ComponentBase* other)
{ {
// does our component have an accepting interface called interfacename? // does our component have an accepting interface called interfacename?
if (0 ==std::strcmp(InterfaceName<InterfaceAcceptor<FirstInterface>>::Get(), interfacename)) if (0 ==std::strcmp(InterfaceName<InterfaceAcceptor<FirstInterface>>::Get(), interfacename))
...@@ -43,12 +43,12 @@ interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(c ...@@ -43,12 +43,12 @@ interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(c
if (1 == acceptIF->Connect(other)) if (1 == acceptIF->Connect(other))
{ {
//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 //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
return interfaceStatus::success; return ComponentBase::interfaceStatus::success;
} }
else else
{ {
// interfacename was found, but other component doesn't match // interfacename was found, but other component doesn't match
return interfaceStatus::noprovider; return ComponentBase::interfaceStatus::noprovider;
} }
} }
return Accepting< RestInterfaces ... >::ConnectFromImpl(interfacename, other); return Accepting< RestInterfaces ... >::ConnectFromImpl(interfacename, other);
...@@ -65,7 +65,7 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase ...@@ -65,7 +65,7 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase
return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other); return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other);
} }
} // end namespace elx } // end namespace selx
#endif // #define Interfaces_hxx #endif // #define Interfaces_hxx
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "Example3rdPartyCode.h" #include "Example3rdPartyCode.h"
#include "Interfaces.hxx" #include "Interfaces.hxx"
namespace elx namespace selx
{ {
// An Optimizer3rdParty expects that Metric3rdParty will be set as input. All accepted interfaces by the Optimizer3rdPartyCompoment will be delegated to the Metric3rdPartyWrapper object. // An Optimizer3rdParty expects that Metric3rdParty will be set as input. All accepted interfaces by the Optimizer3rdPartyCompoment will be delegated to the Metric3rdPartyWrapper object.
class Metric3rdPartyWrapper : public Example3rdParty::Metric3rdPartyBase { class Metric3rdPartyWrapper : public Example3rdParty::Metric3rdPartyBase {
...@@ -16,5 +16,5 @@ private: ...@@ -16,5 +16,5 @@ private:
MetricValueInterface* metricval; MetricValueInterface* metricval;
MetricDerivativeInterface* metricderiv; MetricDerivativeInterface* metricderiv;
}; };
} // end namespace elx } // end namespace selx
#endif // #define Metric3rdPartyWrapper_h #endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "Example4thPartyCode.h" #include "Example4thPartyCode.h"
#include "Interfaces.hxx" #include "Interfaces.hxx"
namespace elx namespace selx
{ {
// An Optimizer4thParty expects that Metric4thParty will be set as input. All accepted interfaces by the Optimizer4thPartyCompoment will be delegated to the Metric4thPartyWrapper object. // An Optimizer4thParty expects that Metric4thParty will be set as input. All accepted interfaces by the Optimizer4thPartyCompoment will be delegated to the Metric4thPartyWrapper object.
class Metric4thPartyWrapper : public Example4thParty::Metric4thPartyBase { class Metric4thPartyWrapper : public Example4thParty::Metric4thPartyBase {
...@@ -13,5 +13,5 @@ public: ...@@ -13,5 +13,5 @@ public:
private: private:
MetricValueInterface* metricval; MetricValueInterface* metricval;
}; };
} // end namespace elx } // end namespace selx
#endif // #define Metric3rdPartyWrapper_h #endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "Interfaces.hxx" #include "Interfaces.hxx"
#include "Example3rdPartyCode.h" #include "Example3rdPartyCode.h"
namespace elx namespace selx
{ {
// SSDMetric3rdPartyComponent provides a value and a derivative // SSDMetric3rdPartyComponent provides a value and a derivative
class SSDMetric3rdPartyComponent : class SSDMetric3rdPartyComponent :
...@@ -20,6 +20,9 @@ namespace elx ...@@ -20,6 +20,9 @@ namespace elx
Example3rdParty::SSDMetric3rdParty* theImplementation; Example3rdParty::SSDMetric3rdParty* theImplementation;
int GetValue(); int GetValue();
int GetDerivative(); int GetDerivative();
virtual bool MeetsCriteria(const CriteriaType &criteria) { return false; };
static const char * GetName(){ return "SSDMetric3rdPartyComponent"; }
static const char * GetDescription(){ return "SSD Metric 3rd Party Component"; };
}; };
} //end namespace elx } //end namespace selx
#endif // #define SSDMetric3rdPartyComponent_h #endif // #define SSDMetric3rdPartyComponent_h
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "Interfaces.hxx" #include "Interfaces.hxx"
#include "Example4thPartyCode.h" #include "Example4thPartyCode.h"
namespace elx namespace selx
{ {
// SSDMetric4thPartyComponent provides only a value and not a derivative // SSDMetric4thPartyComponent provides only a value and not a derivative
class SSDMetric4thPartyComponent : class SSDMetric4thPartyComponent :
...@@ -19,6 +19,10 @@ namespace elx ...@@ -19,6 +19,10 @@ namespace elx
virtual ~SSDMetric4thPartyComponent(); virtual ~SSDMetric4thPartyComponent();
Example4thParty::SSDMetric4thParty* theImplementation; Example4thParty::SSDMetric4thParty* theImplementation;
int GetValue(); int GetValue();
virtual bool MeetsCriteria(const CriteriaType &criteria) { return false; };
static const char * GetName(){ return "SSDMetric4thPartyComponent"; };
static const char * GetDescription(){ return "SSD Metric 4th Party Component"; };
}; };
} //end namespace elx } //end namespace selx
#endif // #define SSDMetric4thPartyComponent_h #endif // #define SSDMetric4thPartyComponent_h
\ No newline at end of file
#include "GDOptimizer3rdPartyComponent.h" #include "GDOptimizer3rdPartyComponent.h"
namespace elx namespace selx
{ {
GDOptimizer3rdPartyComponent::GDOptimizer3rdPartyComponent() GDOptimizer3rdPartyComponent::GDOptimizer3rdPartyComponent()
{ {
...@@ -29,4 +29,4 @@ int GDOptimizer3rdPartyComponent::Update() ...@@ -29,4 +29,4 @@ int GDOptimizer3rdPartyComponent::Update()
this->theImplementation->SetMetric(this->MetricObject); this->theImplementation->SetMetric(this->MetricObject);
return this->theImplementation->Optimize(); // 3rd party specific call return this->theImplementation->Optimize(); // 3rd party specific call
} }
} //end namespace elx } //end namespace selx
\ No newline at end of file \ No newline at end of file
#include "GDOptimizer4thPartyComponent.h" #include "GDOptimizer4thPartyComponent.h"
namespace elx namespace selx
{ {
GDOptimizer4thPartyComponent::GDOptimizer4thPartyComponent() GDOptimizer4thPartyComponent::GDOptimizer4thPartyComponent()
...@@ -26,4 +26,4 @@ int GDOptimizer4thPartyComponent::Update() ...@@ -26,4 +26,4 @@ int GDOptimizer4thPartyComponent::Update()
this->theImplementation->SetMetric(this->MetricObject); this->theImplementation->SetMetric(this->MetricObject);
return this->theImplementation->DoOptimization(); // 4th party specific call return this->theImplementation->DoOptimization(); // 4th party specific call
} }
} //end namespace elx } //end namespace selx
\ No newline at end of file \ No newline at end of file
#include "Metric3rdPartyWrapper.h" #include "Metric3rdPartyWrapper.h"
namespace elx namespace selx
{ {
void Metric3rdPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent) void Metric3rdPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{ {
...@@ -21,4 +21,4 @@ int Metric3rdPartyWrapper::GetDerivative() ...@@ -21,4 +21,4 @@ int Metric3rdPartyWrapper::GetDerivative()
{ {
return this->metricderiv->GetDerivative(); return this->metricderiv->GetDerivative();
} }
} // end namespace elx } // end namespace selx
\ No newline at end of file \ No newline at end of file
#include "Metric4thPartyWrapper.h" #include "Metric4thPartyWrapper.h"
namespace elx namespace selx
{ {
void Metric4thPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent) void Metric4thPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{ {
...@@ -12,4 +12,4 @@ int Metric4thPartyWrapper::GetCost() ...@@ -12,4 +12,4 @@ int Metric4thPartyWrapper::GetCost()
return this->metricval->GetValue(); return this->metricval->GetValue();
} }
} // end namespace elx } // end namespace selx
\ No newline at end of file \ No newline at end of file
#include "SSDMetric3rdPartyComponent.h" #include "SSDMetric3rdPartyComponent.h"
namespace elx namespace selx
{ {
SSDMetric3rdPartyComponent::SSDMetric3rdPartyComponent() SSDMetric3rdPartyComponent::SSDMetric3rdPartyComponent()
{ {
...@@ -19,4 +19,4 @@ int SSDMetric3rd