Skip to content
Snippets Groups Projects
Commit 7e6b33d4 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH: added InterfaceName Type Traits and ConnectFrom

parent 0a5449b8
No related branches found
No related tags found
No related merge requests found
...@@ -5,7 +5,10 @@ namespace elx ...@@ -5,7 +5,10 @@ namespace elx
{ {
class ComponentBase { class ComponentBase {
public: public:
virtual int ConnectFrom(const char *, ComponentBase*) { return 0; }; //= 0;
protected:
virtual ~ComponentBase(){}; virtual ~ComponentBase(){};
}; };
} // end namespace elx } // end namespace elx
#endif // #define ComponentBase_h #endif // #define ComponentBase_h
\ No newline at end of file
...@@ -13,6 +13,35 @@ GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent() ...@@ -13,6 +13,35 @@ GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent()
delete this->MetricObject; 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) int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component)
{ {
this->MetricObject->SetMetricValueComponent(component); this->MetricObject->SetMetricValueComponent(component);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "Interfaces.hxx" #include "Interfaces.hxx"
#include "Example3rdPartyCode.h" #include "Example3rdPartyCode.h"
#include "Metric3rdPartyWrapper.h" #include "Metric3rdPartyWrapper.h"
#include <string.h>
namespace elx namespace elx
{ {
...@@ -15,6 +16,7 @@ namespace elx ...@@ -15,6 +16,7 @@ namespace elx
~GDOptimizer3rdPartyComponent(); ~GDOptimizer3rdPartyComponent();
Example3rdParty::GDOptimizer3rdParty* theImplementation; Example3rdParty::GDOptimizer3rdParty* theImplementation;
Metric3rdPartyWrapper* MetricObject; Metric3rdPartyWrapper* MetricObject;
virtual int ConnectFrom(const char *, ComponentBase*);
int Set(MetricValueInterface*); int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*); int Set(MetricDerivativeInterface*);
int Update(); int Update();
......
...@@ -15,6 +15,23 @@ GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent() ...@@ -15,6 +15,23 @@ GDOptimizer4thPartyComponent::~GDOptimizer4thPartyComponent()
delete this->MetricObject; 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) int GDOptimizer4thPartyComponent::Set(MetricValueInterface* component)
{ {
this->MetricObject->SetMetricValueComponent(component); this->MetricObject->SetMetricValueComponent(component);
......
...@@ -16,6 +16,7 @@ namespace elx ...@@ -16,6 +16,7 @@ namespace elx
~GDOptimizer4thPartyComponent(); ~GDOptimizer4thPartyComponent();
Example4thParty::GDOptimizer4thParty* theImplementation; Example4thParty::GDOptimizer4thParty* theImplementation;
Metric4thPartyWrapper* MetricObject; Metric4thPartyWrapper* MetricObject;
virtual int ConnectFrom(const char *, ComponentBase*);
int Set(MetricValueInterface*); int Set(MetricValueInterface*);
int Update(); int Update();
}; };
......
...@@ -46,5 +46,74 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ ...@@ -46,5 +46,74 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
return 1; 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 } // end namespace elx
#endif // #define Interfaces_hxx #endif // #define Interfaces_hxx
\ No newline at end of file
...@@ -8,8 +8,20 @@ ...@@ -8,8 +8,20 @@
#include "SSDMetric4thPartyComponent.h" #include "SSDMetric4thPartyComponent.h"
#include "GDOptimizer4thPartyComponent.h" #include "GDOptimizer4thPartyComponent.h"
using namespace elx; using namespace elx;
int main() { 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 *********** /************ testing interface casts ***********
* expected: ok * expected: ok
...@@ -33,6 +45,8 @@ using namespace elx; ...@@ -33,6 +45,8 @@ using namespace elx;
GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent(); GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent();
ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory
int success = optimizer4p->ConnectFrom("MetricValueInterface", metric4p);
InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p); InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p);
if (!opValIF) if (!opValIF)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment