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
#define ComponentBase_h
#include "itkLightObject.h"
#include "itkObjectFactory.h"
//#include "itkComponentBase.h"
#include <list>
#include <iostream>
#include <cstring>
namespace elx
#include <fstream>
#include <string>
#include <map>
namespace selx
{
enum interfaceStatus { success, noaccepter, noprovider };
class ComponentBase {
class ComponentBase : public itk::LightObject
{
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 int ConnectFrom(ComponentBase*) = 0;
//protected:
virtual bool MeetsCriteria(const CriteriaType &criteria) = 0;
protected:
ComponentBase() {};
virtual ~ComponentBase() {};
};
} // end namespace elx
#endif // #define ComponentBase_h
\ No newline at end of file
} // end namespace selx
#endif // ComponentBase_h
......@@ -7,7 +7,7 @@
#include "Metric3rdPartyWrapper.h"
#include <string.h>
namespace elx
namespace selx
{
class GDOptimizer3rdPartyComponent :
......@@ -25,6 +25,9 @@ namespace elx
int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*);
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
\ No newline at end of file
......@@ -6,7 +6,7 @@
#include "Example4thPartyCode.h"
#include "Metric4thPartyWrapper.h"
namespace elx
namespace selx
{
// wrapping into components:
class GDOptimizer4thPartyComponent :
......@@ -28,7 +28,10 @@ namespace elx
//template <class ConflictinUpdateInterface> virtual int Update() { return 5; };
// "error" : member function templates cannot be virtual
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
\ No newline at end of file
......@@ -3,7 +3,7 @@
#include "Interfaces.h"
namespace elx
namespace selx
{
// Traits to get printable interface name
// default implementation
......@@ -12,6 +12,7 @@ struct InterfaceName
{
static const char* Get()
{
static_assert(false, "Please implement a template specialization for the appropriate InterfaceName")
return typeid(T).name();
}
};
......@@ -43,6 +44,16 @@ struct InterfaceName < OptimizerUpdateInterface >
}
};
template <>
struct InterfaceName < TransformedImageInterface >
{
static const char* Get()
{
return "TransformedImageInterface";
}
};
// partial specialization of InterfaceName
template<template<typename> class TT, typename T1>
......@@ -63,7 +74,7 @@ struct AcceptorInterfaceName
}
};
} // end namespace elx
} // end namespace selx
#endif // #define InterfaceTraits_h
\ No newline at end of file
......@@ -2,29 +2,33 @@
#define Interfaces_h
#include "ComponentBase.h"
#include "InterfaceTraits.h"
#include <typeinfo>
namespace elx
namespace selx
{
// Define the providing interfaces abstractly
class MetricDerivativeInterface {
// Define the providing interfaces abstractly
class MetricDerivativeInterface {
public:
virtual int GetDerivative() = 0;
};
};
class MetricValueInterface {
class MetricValueInterface {
public:
virtual int GetValue() = 0;
};
};
class OptimizerUpdateInterface {
public:
class OptimizerUpdateInterface {
public:
virtual int Update() = 0;
};
};
class ConflictinUpdateInterface {
public:
class TransformedImageInterface {
public:
virtual int GetTransformedImage() = 0;
};
class ConflictinUpdateInterface {
public:
// "error" : member function templates cannot be virtual
// template <class ConflictinUpdateInterface> virtual int Update() = 0;
//TODO http://en.cppreference.com/w/cpp/language/member_template
......@@ -32,13 +36,15 @@ public:
//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;
};
};
// Define the accepting interfaces as templated by the providing interface
template<class InterfaceT>
class InterfaceAcceptor {
public:
// 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.
......@@ -47,15 +53,15 @@ public:
// Connect tries to connect this accepting interface with all interfaces of the provider component.
int Connect(ComponentBase*);
private:
private:
bool isSet;
};
};
template<typename ... RestInterfaces>
class Accepting
{
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 ;
};
......@@ -63,7 +69,7 @@ template<typename FirstInterface, typename ... RestInterfaces>
class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... >
{
public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
ComponentBase::interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
int ConnectFromImpl(ComponentBase*);
};
......@@ -80,7 +86,7 @@ class Implements : public AcceptingInterfaces, public ProvidingInterfaces, publi
virtual int ConnectFrom(ComponentBase*);
};
} // end namespace elx
} // end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "Interfaces.hxx"
......
......@@ -2,7 +2,7 @@
#define Interfaces_hxx
#include "InterfaceTraits.h"
namespace elx
namespace selx
{
template<class InterfaceT>
int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
......@@ -19,7 +19,7 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
}
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);
}
......@@ -31,7 +31,7 @@ int Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(ComponentB
}
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?
if (0 ==std::strcmp(InterfaceName<InterfaceAcceptor<FirstInterface>>::Get(), interfacename))
......@@ -43,12 +43,12 @@ interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(c
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
return interfaceStatus::success;
return ComponentBase::interfaceStatus::success;
}
else
{
// interfacename was found, but other component doesn't match
return interfaceStatus::noprovider;
return ComponentBase::interfaceStatus::noprovider;
}
}
return Accepting< RestInterfaces ... >::ConnectFromImpl(interfacename, other);
......@@ -65,7 +65,7 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase
return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other);
}
} // end namespace elx
} // end namespace selx
#endif // #define Interfaces_hxx
\ No newline at end of file
......@@ -3,7 +3,7 @@
#include "Example3rdPartyCode.h"
#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.
class Metric3rdPartyWrapper : public Example3rdParty::Metric3rdPartyBase {
......@@ -16,5 +16,5 @@ private:
MetricValueInterface* metricval;
MetricDerivativeInterface* metricderiv;
};
} // end namespace elx
} // end namespace selx
#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
......@@ -3,7 +3,7 @@
#include "Example4thPartyCode.h"
#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.
class Metric4thPartyWrapper : public Example4thParty::Metric4thPartyBase {
......@@ -13,5 +13,5 @@ public:
private:
MetricValueInterface* metricval;
};
} // end namespace elx
} // end namespace selx
#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
......@@ -5,7 +5,7 @@
#include "Interfaces.hxx"
#include "Example3rdPartyCode.h"
namespace elx
namespace selx
{
// SSDMetric3rdPartyComponent provides a value and a derivative
class SSDMetric3rdPartyComponent :
......@@ -20,6 +20,9 @@ namespace elx
Example3rdParty::SSDMetric3rdParty* theImplementation;
int GetValue();
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
\ No newline at end of file
......@@ -5,7 +5,7 @@
#include "Interfaces.hxx"
#include "Example4thPartyCode.h"
namespace elx
namespace selx
{
// SSDMetric4thPartyComponent provides only a value and not a derivative
class SSDMetric4thPartyComponent :
......@@ -19,6 +19,10 @@ namespace elx
virtual ~SSDMetric4thPartyComponent();
Example4thParty::SSDMetric4thParty* theImplementation;
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
\ No newline at end of file
#include "GDOptimizer3rdPartyComponent.h"
namespace elx
namespace selx
{
GDOptimizer3rdPartyComponent::GDOptimizer3rdPartyComponent()
{
......@@ -29,4 +29,4 @@ int GDOptimizer3rdPartyComponent::Update()
this->theImplementation->SetMetric(this->MetricObject);
return this->theImplementation->Optimize(); // 3rd party specific call
}
} //end namespace elx
\ No newline at end of file
} //end namespace selx
\ No newline at end of file
#include "GDOptimizer4thPartyComponent.h"
namespace elx
namespace selx
{
GDOptimizer4thPartyComponent::GDOptimizer4thPartyComponent()
......@@ -26,4 +26,4 @@ int GDOptimizer4thPartyComponent::Update()
this->theImplementation->SetMetric(this->MetricObject);
return this->theImplementation->DoOptimization(); // 4th party specific call
}
} //end namespace elx
\ No newline at end of file
} //end namespace selx
\ No newline at end of file
#include "Metric3rdPartyWrapper.h"
namespace elx
namespace selx
{
void Metric3rdPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{
......@@ -21,4 +21,4 @@ int Metric3rdPartyWrapper::GetDerivative()
{
return this->metricderiv->GetDerivative();
}
} // end namespace elx
\ No newline at end of file
} // end namespace selx
\ No newline at end of file
#include "Metric4thPartyWrapper.h"
namespace elx
namespace selx
{
void Metric4thPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{
......@@ -12,4 +12,4 @@ int Metric4thPartyWrapper::GetCost()
return this->metricval->GetValue();
}
} // end namespace elx
\ No newline at end of file
} // end namespace selx
\ No newline at end of file
#include "SSDMetric3rdPartyComponent.h"
namespace elx
namespace selx
{
SSDMetric3rdPartyComponent::SSDMetric3rdPartyComponent()
{
......@@ -19,4 +19,4 @@ int SSDMetric3rdPartyComponent::GetValue()
{
return this->theImplementation->GetValue();
};
} //end namespace elx
\ No newline at end of file
} //end namespace selx
\ No newline at end of file
#include "SSDMetric4thPartyComponent.h"
namespace elx
namespace selx
{
SSDMetric4thPartyComponent::SSDMetric4thPartyComponent()
......@@ -15,4 +15,4 @@ int SSDMetric4thPartyComponent::GetValue()
{
return this->theImplementation->GetCost(); // translate method name
};
} //end namespace elx
\ No newline at end of file
} //end namespace selx
\ No newline at end of file
......@@ -15,33 +15,33 @@
* limitations under the License.
*
*=========================================================================*/
#ifndef itkComponentFactory_h
#define itkComponentFactory_h
#ifndef itkComponentSelector_h
#define itkComponentSelector_h
#include "itkObjectFactory.h"
#include "itkComponentBase.h"
#include "ComponentBase.h"
namespace itk
namespace selx
{
/** \class ComponentFactor
* \brief Create instances of MetaImageIO objects using an object factory.
* \ingroup ITKIOMeta
*/
class ComponentFactory:public Object
class ComponentSelector:public itk::Object
{
public:
/** Standard class typedefs. */
typedef ComponentFactory Self;
typedef ComponentSelector Self;
typedef Object Superclass;
typedef SmartPointer< Self > Pointer;
typedef SmartPointer< const Self > ConstPointer;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer< const Self > ConstPointer;
/** Class methods used to interface with the registered factories. */
//virtual const char * GetITKSourceVersion() const { return ITK_SOURCE_VERSION; }
/** Run-time type information (and related methods). */
itkTypeMacro(ComponentFactory, Object);
itkTypeMacro(ComponentSelector, Object);
/** New macro for creation of through the object factory. */
itkNewMacro(Self);
......@@ -60,26 +60,23 @@ public:
void UpdatePossibleComponents(void);
/** Create the appropriate ComponentIO depending on
* the particulars of the file.
*/
ComponentBasePointer GetComponent(void);
protected:
mutable CriteriaType m_Criteria;
mutable ComponentListType m_PossibleComponents;
ComponentFactory();
~ComponentFactory();
ComponentSelector();
~ComponentSelector();
private:
ComponentFactory(const Self &); //purposely not implemented
ComponentSelector(const Self &); //purposely not implemented
void operator=(const Self &); //purposely not implemented
};
} // end namespace itk
} // end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkComponentFactory.hxx"
#include "ComponentSelector.hxx"
#endif
#endif
......@@ -15,28 +15,28 @@
* limitations under the License.
*
*=========================================================================*/
#ifndef itkComponentFactory_hxx
#define itkComponentFactory_hxx
#ifndef itkComponentSelector_hxx
#define itkComponentSelector_hxx
#include "itkComponentFactory.h"
#include "ComponentSelector.h"
namespace itk
namespace selx
{
ComponentFactory::ComponentFactory()
ComponentSelector::ComponentSelector()
{
this->m_PossibleComponents.clear();
}
ComponentFactory::~ComponentFactory()
ComponentSelector::~ComponentSelector()
{
}
void ComponentFactory::Initialize()
void ComponentSelector::Initialize()
{
std::list< LightObject::Pointer > allobjects =
ObjectFactoryBase::CreateAllInstance("itkComponentBase");
std::list< itk::LightObject::Pointer > allobjects =
itk::ObjectFactoryBase::CreateAllInstance("itkComponentBase");
for (std::list< LightObject::Pointer >::iterator i = allobjects.begin();
for (std::list< itk::LightObject::Pointer >::iterator i = allobjects.begin();
i != allobjects.end(); ++i)
{
ComponentBase *io =
......@@ -47,7 +47,7 @@ void ComponentFactory::Initialize()
}
}
}
void ComponentFactory::SetCriteria(const CriteriaType &criteria)
void ComponentSelector::SetCriteria(const CriteriaType &criteria)
{
this->Initialize();
this->m_Criteria = criteria;
......@@ -55,7 +55,7 @@ void ComponentFactory::SetCriteria(const CriteriaType &criteria)
}
void ComponentFactory::AddCriteria(const CriteriaType &criteria)
void ComponentSelector::AddCriteria(const CriteriaType &criteria)
{
this->m_Criteria.insert(criteria.begin(), criteria.end());
this->Modified();
......@@ -66,13 +66,13 @@ void ComponentFactory::AddCriteria(const CriteriaType &criteria)
// bool operator() (const ComponentBasePointer& component) { return !component->MeetsCriteria(this->m_Criteria) }
//};
void ComponentFactory::UpdatePossibleComponents()
void ComponentSelector::UpdatePossibleComponents()
{
// Check each possible component if it meets the criteria
// Using a Lambda function.
this->m_PossibleComponents.remove_if([&](ComponentBasePointer component){ return !component->MeetsCriteria(this->m_Criteria); });
}
ComponentFactory::ComponentBasePointer ComponentFactory::GetComponent()
ComponentSelector::ComponentBasePointer ComponentSelector::GetComponent()
{
//TODO check if Modified
this->UpdatePossibleComponents();
......@@ -86,6 +86,6 @@ ComponentFactory::ComponentBasePointer ComponentFactory::GetComponent()
return ITK_NULLPTR;
}
}
} // end namespace itk
} // end namespace selx
#endif
/*=========================================================================
*
* Copyright Insight Software Consortium
*