Commit 0a5449b8 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

COMP: Split into headers and sources

parent 882e0853
PROJECT(componenthandshake) PROJECT(componenthandshake)
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.8)
cmake_policy(VERSION 2.6) cmake_policy(VERSION 2.8)
file(GLOB componenthandshake_SRC
ADD_EXECUTABLE(componenthandshake componenthandshake.cxx) "*.h"
"*.cxx"
"*.hxx"
)
ADD_EXECUTABLE(componenthandshake ${componenthandshake_SRC})
\ No newline at end of file
#ifndef ComponentBase_h
#define ComponentBase_h
namespace elx
{
class ComponentBase {
public:
virtual ~ComponentBase(){};
};
} // end namespace elx
#endif // #define ComponentBase_h
\ No newline at end of file
#include "Example3rdPartyCode.h"
namespace Example3rdParty
{
GDOptimizer3rdParty::GDOptimizer3rdParty()
{
this->theMetric = nullptr;
}
GDOptimizer3rdParty::~GDOptimizer3rdParty()
{
}
int GDOptimizer3rdParty::SetMetric(Metric3rdPartyBase* metric)
{
this->theMetric = metric;
return 0;
}
int GDOptimizer3rdParty::Optimize()
{
if (this->theMetric != nullptr)
{
std::cout << "GDOptimizer3rdParty->Optimize():" << std::endl;
std::cout << " theMetric->GetValue():" << theMetric->GetValue() << std::endl;
std::cout << " theMetric->GetDerivative():" << theMetric->GetDerivative() << std::endl;
}
return 0;
}
} // end namespace Example3rdParty
\ No newline at end of file
#ifndef Example3rdPartyCode_h
#define Example3rdPartyCode_h
#include <iostream>
namespace Example3rdParty
{
// test case: there are two (slightly) incompatible codebases (i.e. 3rd party and 4th party!), each with an optimizer object and a metric object.
// goal: make elastix components of all objects and define a handshake that checks if connections can be made.
/*************** below: example implementations of 3rd and 4th party code base (assume we cannot change that) *********************/
class Metric3rdPartyBase{
public:
virtual int GetValue() = 0;
virtual int GetDerivative() = 0;
};
class Optimizer3rdPartyBase{
public:
virtual int SetMetric(Metric3rdPartyBase*) = 0;
virtual int Optimize() = 0;
protected:
Metric3rdPartyBase* theMetric;
};
class SSDMetric3rdParty : public Metric3rdPartyBase {
public:
virtual int GetValue() { return 1; };
virtual int GetDerivative() { return 2; };
};
class GDOptimizer3rdParty : public Optimizer3rdPartyBase {
public:
GDOptimizer3rdParty();
~GDOptimizer3rdParty();
virtual int SetMetric(Metric3rdPartyBase*);
virtual int Optimize();
};
} // end namespave Example3rdParty
#endif // #define Example3rdPartyCode_h
\ No newline at end of file
#include "Example4thPartyCode.h"
namespace Example4thParty
{
GDOptimizer4thParty::GDOptimizer4thParty()
{
this->theMetric = nullptr;
}
GDOptimizer4thParty::~GDOptimizer4thParty()
{
}
int GDOptimizer4thParty::SetMetric(Metric4thPartyBase* metric)
{
this->theMetric = metric;
return 0;
}
int GDOptimizer4thParty::DoOptimization()
{
if (this->theMetric != nullptr)
{
std::cout << "GDOptimizer4thParty->DoOptimization():" << std::endl;
std::cout << " theMetric->GetCost():" << theMetric->GetCost() << std::endl;
}
return 0;
}
} // end namespace Example4thParty
\ No newline at end of file
#ifndef Example4thPartyCode_h
#define Example4thPartyCode_h
#include <iostream>
namespace Example4thParty
{
// test case: there are two (slightly) incompatible codebases (i.e. 3rd party and 4th party!), each with an optimizer object and a metric object.
// goal: make elastix components of all objects and define a handshake that checks if connections can be made.
/*************** below: example implementations of 3rd and 4th party code base (assume we cannot change that) *********************/
class Metric4thPartyBase{
public:
virtual int GetCost() = 0; // with different naming convention than 3rd party
};
class Optimizer4thPartyBase{
public:
virtual int SetMetric(Metric4thPartyBase*) = 0;
virtual int DoOptimization() = 0; // with different naming convention than 3rd party
protected:
Metric4thPartyBase* theMetric;
};
class SSDMetric4thParty : public Metric4thPartyBase {
public:
virtual int GetCost() { return 3; };
};
class GDOptimizer4thParty : public Optimizer4thPartyBase {
public:
GDOptimizer4thParty();
~GDOptimizer4thParty();
virtual int SetMetric(Metric4thPartyBase*);
virtual int DoOptimization();
};
} // end namespave Example4thParty
#endif // #define Example4thPartyCode_h
\ No newline at end of file
#include "GDOptimizer3rdPartyComponent.h"
namespace elx
{
GDOptimizer3rdPartyComponent::GDOptimizer3rdPartyComponent()
{
this->theImplementation = new Example3rdParty::GDOptimizer3rdParty();
this->MetricObject = new Metric3rdPartyWrapper();
}
GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent()
{
delete this->theImplementation;
delete this->MetricObject;
}
int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component)
{
this->MetricObject->SetMetricValueComponent(component);
return 0;
}
int GDOptimizer3rdPartyComponent::Set(MetricDerivativeInterface* component)
{
this->MetricObject->SetMetricDerivativeComponent(component);
return 0;
}
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
#ifndef GDOptimizer3rdPartyComponent_h
#define GDOptimizer3rdPartyComponent_h
#include "ComponentBase.h"
#include "Interfaces.hxx"
#include "Example3rdPartyCode.h"
#include "Metric3rdPartyWrapper.h"
namespace elx
{
class GDOptimizer3rdPartyComponent : public ComponentBase, public InterfaceAcceptor<MetricValueInterface>, public InterfaceAcceptor<MetricDerivativeInterface>, public OptimizerUpdateInterface
{
public:
GDOptimizer3rdPartyComponent();
~GDOptimizer3rdPartyComponent();
Example3rdParty::GDOptimizer3rdParty* theImplementation;
Metric3rdPartyWrapper* MetricObject;
int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*);
int Update();
};
} //end namespace elx
#endif // #define GDOptimizer3rdPartyComponent_h
\ No newline at end of file
#include "GDOptimizer4thPartyComponent.h"
namespace elx
{
GDOptimizer4thPartyComponent::GDOptimizer4thPartyComponent()
{
this->theImplementation = new Example4thParty::GDOptimizer4thParty();
this->MetricObject = new Metric4thPartyWrapper();
}
GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent()
{
delete this->theImplementation;
delete this->MetricObject;
}
int GDOptimizer4thPartyComponent::Set(MetricValueInterface* component)
{
this->MetricObject->SetMetricValueComponent(component);
return 0;
}
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
#ifndef GDOptimizer4thPartyComponent_h
#define GDOptimizer4thPartyComponent_h
#include "ComponentBase.h"
#include "Interfaces.hxx"
#include "Example4thPartyCode.h"
#include "Metric4thPartyWrapper.h"
namespace elx
{
// wrapping into components:
class GDOptimizer4thPartyComponent : public ComponentBase, public InterfaceAcceptor<MetricValueInterface>, public OptimizerUpdateInterface
{
public:
GDOptimizer4thPartyComponent();
~GDOptimizer4thPartyComponent();
Example4thParty::GDOptimizer4thParty* theImplementation;
Metric4thPartyWrapper* MetricObject;
int Set(MetricValueInterface*);
int Update();
};
} //end namespace elx
#endif // #define GDOptimizer4thPartyComponent_h
\ No newline at end of file
#ifndef Interfaces_hxx
#define Interfaces_hxx
#include "ComponentBase.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:
virtual int Set(InterfaceT*) = 0;
int Connect(ComponentBase*);
private:
bool isSet;
};
template<class InterfaceT>
int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
InterfaceT* providerInterface = dynamic_cast<InterfaceT*> (providerComponent);
if (!providerInterface)
{
std::cout << "providerComponent does not have required interface" << 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
return 1;
}
} // end namespace elx
#endif // #define Interfaces_hxx
\ No newline at end of file
#include "Metric3rdPartyWrapper.h"
namespace elx
{
void Metric3rdPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{
this->metricval = metricValueComponent;
}
int Metric3rdPartyWrapper::GetValue()
{
return this->metricval->GetValue();
}
void Metric3rdPartyWrapper::SetMetricDerivativeComponent(MetricDerivativeInterface* metricDerivativeComponent)
{
this->metricderiv = metricDerivativeComponent;
}
int Metric3rdPartyWrapper::GetDerivative()
{
return this->metricderiv->GetDerivative();
}
} // end namespace elx
\ No newline at end of file
#ifndef Metric3rdPartyWrapper_h
#define Metric3rdPartyWrapper_h
#include "Example3rdPartyCode.h"
#include "Interfaces.hxx"
namespace elx
{
// 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 {
public:
void SetMetricValueComponent(MetricValueInterface*);
void SetMetricDerivativeComponent(MetricDerivativeInterface*);
virtual int GetValue();
virtual int GetDerivative();
private:
MetricValueInterface* metricval;
MetricDerivativeInterface* metricderiv;
};
} // end namespace elx
#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
#include "Metric4thPartyWrapper.h"
namespace elx
{
void Metric4thPartyWrapper::SetMetricValueComponent(MetricValueInterface* metricValueComponent)
{
this->metricval = metricValueComponent;
}
int Metric4thPartyWrapper::GetCost()
{
return this->metricval->GetValue();
}
} // end namespace elx
\ No newline at end of file
#ifndef Metric4thPartyWrapper_h
#define Metric4thPartyWrapper_h
#include "Example4thPartyCode.h"
#include "Interfaces.hxx"
namespace elx
{
// 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 {
public:
void SetMetricValueComponent(MetricValueInterface*);
virtual int GetCost();
private:
MetricValueInterface* metricval;
};
} // end namespace elx
#endif // #define Metric3rdPartyWrapper_h
\ No newline at end of file
#include "SSDMetric3rdPartyComponent.h"
namespace elx
{
SSDMetric3rdPartyComponent::SSDMetric3rdPartyComponent()
{
this->theImplementation = new Example3rdParty::SSDMetric3rdParty();
}
SSDMetric3rdPartyComponent::~SSDMetric3rdPartyComponent()
{
delete this->theImplementation;
}
int SSDMetric3rdPartyComponent::GetDerivative()
{
return this->theImplementation->GetDerivative();
};
int SSDMetric3rdPartyComponent::GetValue()
{
return this->theImplementation->GetValue();
};
} //end namespace elx
\ No newline at end of file
#ifndef SSDMetric3rdPartyComponent_h
#define SSDMetric3rdPartyComponent_h
#include "ComponentBase.h"
#include "Interfaces.hxx"
#include "Example3rdPartyCode.h"
namespace elx
{
// SSDMetric3rdPartyComponent provides a value and a derivative
class SSDMetric3rdPartyComponent : public ComponentBase, public MetricDerivativeInterface, public MetricValueInterface {
public:
SSDMetric3rdPartyComponent();
~SSDMetric3rdPartyComponent();
Example3rdParty::SSDMetric3rdParty* theImplementation;
int GetValue();
int GetDerivative();
};
} //end namespace elx
#endif // #define SSDMetric3rdPartyComponent_h
\ No newline at end of file
#include "SSDMetric4thPartyComponent.h"
namespace elx
{
SSDMetric4thPartyComponent::SSDMetric4thPartyComponent()
{
this->theImplementation = new Example4thParty::SSDMetric4thParty();
}
SSDMetric4thPartyComponent::~SSDMetric4thPartyComponent()
{
delete this->theImplementation;
}
int SSDMetric4thPartyComponent::GetValue()
{
return this->theImplementation->GetCost(); // translate method name
};
} //end namespace elx
\ No newline at end of file
#ifndef SSDMetric4thPartyComponent_h
#define SSDMetric4thPartyComponent_h
#include "ComponentBase.h"
#include "Interfaces.hxx"
#include "Example4thPartyCode.h"
namespace elx
{
// SSDMetric4thPartyComponent provides only a value and not a derivative
class SSDMetric4thPartyComponent : public ComponentBase, public MetricValueInterface {
public:
SSDMetric4thPartyComponent();
~SSDMetric4thPartyComponent();
Example4thParty::SSDMetric4thParty* theImplementation;
int GetValue();
};
} //end namespace elx
#endif // #define SSDMetric4thPartyComponent_h
\ No newline at end of file
// multiple inheritance
#include <iostream> #include <iostream>
// test case: there are two (slightly) incompatible codebases (i.e. 3rd party and 4th party!), each with an optimizer object and a metric object. // test case: Assume there are two (slightly) incompatible codebases (i.e. 3rd party and 4th! party), each with an optimizer object and a metric object. The example classes of 3rd and 4th party code bases cannot be changed, but the wrapping is in our control.
// goal: make elastix components of all objects and define a handshake that checks if connections can be made. // goal: make elastix components of all objects and define a handshake that checks if connections can be made.
/*************** below: example implementations of 3rd and 4th party code base (assume we cannot change that) *********************/ #include "SSDMetric3rdPartyComponent.h"
class Metric3rdPartyBase{ #include "GDOptimizer3rdPartyComponent.h"
public: #include "SSDMetric4thPartyComponent.h"
virtual int GetValue() = 0; #include "GDOptimizer4thPartyComponent.h"
virtual int GetDerivative() = 0;
};
class Optimizer3rdPartyBase{ using namespace elx;
public: int main() {
virtual int SetMetric(Metric3rdPartyBase*) = 0;
virtual int Optimize() = 0;
protected:
Metric3rdPartyBase* theMetric;
};
class Metric4rdPartyBase{
public:
virtual int GetCost() = 0; // with different naming convention than 3rd party
};
class Optimizer4rdPartyBase{
public:
virtual int SetMetric(Metric4rdPartyBase*) = 0;
virtual int DoOptimization() = 0; // with different naming convention than 3rd party
protected:
Metric4rdPartyBase* theMetric;
};
class SSDMetric3rdParty : public Metric3rdPartyBase {
public:
virtual int GetValue() { return 1; };
virtual int GetDerivative() { return 2; };
};
class GDOptimizer3rdParty : public Optimizer3rdPartyBase {
public:
GDOptimizer3rdParty();
~GDOptimizer3rdParty();
virtual int SetMetric(Metric3rdPartyBase*);
virtual int Optimize();
};
GDOptimizer3rdParty::GDOptimizer3rdParty()
{
this->theMetric = nullptr;
}
GDOptimizer3rdParty::~GDOptimizer3rdParty()
{
}
int GDOptimizer3rdParty::SetMetric(Metric3rdPartyBase* metric)
{
this->theMetric = metric;
return 0;
}
int GDOptimizer3rdParty::Optimize()
{
if (this->theMetric != nullptr)
{
std::cout << "GDOptimizer3rdParty->Optimize():" << std::endl;
std::cout << " theMetric->GetValue():" << theMetric->GetValue() << std::endl;
std::cout << " theMetric->GetDerivative():" << theMetric->GetDerivative() << std::endl;
}
return 0;
}
class SSDMetric4rdParty : public Metric4rdPartyBase {
public:
virtual int GetCost() { return 3; };
};
class GDOptimizer4rdParty : public Optimizer4rdPartyBase {
public:
GDOptimizer4rdParty();
~GDOptimizer4rdParty();
virtual int SetMetric(Metric4rdPartyBase*);
virtual int DoOptimization();
};
GDOptimizer4rdParty::GDOptimizer4rdParty()
{
this->theMetric = nullptr;
}
GDOptimizer4rdParty::~GDOptimizer4rdParty()
{
}
int GDOptimizer4rdParty::SetMetric(Metric4rdPartyBase* metric)
{
this->theMetric = metric;
return 0;