Commit 7e6b33d4 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH: added InterfaceName Type Traits and ConnectFrom

parent 0a5449b8
......@@ -5,7 +5,10 @@ namespace elx
{
class ComponentBase {
public:
virtual int ConnectFrom(const char *, ComponentBase*) { return 0; }; //= 0;
protected:
virtual ~ComponentBase(){};
};
} // end namespace elx
#endif // #define ComponentBase_h
\ No newline at end of file
......@@ -13,6 +13,35 @@ GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent()
delete this->MetricObject;
}
int GDOptimizer3rdPartyComponent::ConnectFrom(const char * interfacename, ComponentBase* other)
{
//TODO write out as templated functionality:
if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get(), interfacename) == 0)
{
InterfaceAcceptor<MetricValueInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricValueInterface>*> (this);
if (!acceptIF)
{
std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
}
// connect value interfaces
acceptIF->Connect(other);
return 1; //success, assume only one interface listens interfacename
}
if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get(), interfacename) == 0)
{
InterfaceAcceptor<MetricDerivativeInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (this);
if (!acceptIF)
{
std::cout << InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
}
// connect value interfaces
acceptIF->Connect(other);
return 1; //success, assume only one interface listens interfacename
}
return 0;
}
int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component)
{
this->MetricObject->SetMetricValueComponent(component);
......
......@@ -5,6 +5,7 @@
#include "Interfaces.hxx"
#include "Example3rdPartyCode.h"
#include "Metric3rdPartyWrapper.h"
#include <string.h>
namespace elx
{
......@@ -15,6 +16,7 @@ namespace elx
~GDOptimizer3rdPartyComponent();
Example3rdParty::GDOptimizer3rdParty* theImplementation;
Metric3rdPartyWrapper* MetricObject;
virtual int ConnectFrom(const char *, ComponentBase*);
int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*);
int Update();
......
......@@ -15,6 +15,23 @@ GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent()
delete this->MetricObject;
}
int GDOptimizer4thPartyComponent::ConnectFrom(const char * interfacename, ComponentBase* other)
{
//TODO write out as templated functionality:
if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get(), interfacename) == 0)
{
InterfaceAcceptor<MetricValueInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricValueInterface>*> (this);
if (!acceptIF)
{
std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl;
}
// connect value interfaces
acceptIF->Connect(other);
return 1; //success, assume only one interface listens interfacename
}
return 0;
}
int GDOptimizer4thPartyComponent::Set(MetricValueInterface* component)
{
this->MetricObject->SetMetricValueComponent(component);
......
......@@ -16,6 +16,7 @@ namespace elx
~GDOptimizer4thPartyComponent();
Example4thParty::GDOptimizer4thParty* theImplementation;
Metric4thPartyWrapper* MetricObject;
virtual int ConnectFrom(const char *, ComponentBase*);
int Set(MetricValueInterface*);
int Update();
};
......
......@@ -46,5 +46,74 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
return 1;
}
// 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();
}
};
} // end namespace elx
#endif // #define Interfaces_hxx
\ No newline at end of file
......@@ -8,8 +8,20 @@
#include "SSDMetric4thPartyComponent.h"
#include "GDOptimizer4thPartyComponent.h"
using namespace elx;
int main() {
{
std::cout << InterfaceName<MetricValueInterface>::Get() << std::endl;
std::cout << AcceptorInterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl;
std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl;
std::cout << InterfaceName<InterfaceProvider<MetricValueInterface>>::Get() << std::endl;
}
{
/************ testing interface casts ***********
* expected: ok
......@@ -33,6 +45,8 @@ using namespace elx;
GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent();
ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory
int success = optimizer4p->ConnectFrom("MetricValueInterface", metric4p);
InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p);
if (!opValIF)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment