From 7e6b33d4b48ee1eddf9d256ef4812dc5af344100 Mon Sep 17 00:00:00 2001 From: Floris Berendsen <floris.berendsen@gmail.com> Date: Mon, 16 Nov 2015 11:54:24 +0100 Subject: [PATCH] ENH: added InterfaceName Type Traits and ConnectFrom --- .../Core/ComponentInterface/ComponentBase.h | 3 + .../GDOptimizer3rdPartyComponent.cxx | 29 ++++++++ .../GDOptimizer3rdPartyComponent.h | 2 + .../GDOptimizer4thPartyComponent.cxx | 17 +++++ .../GDOptimizer4thPartyComponent.h | 1 + .../Core/ComponentInterface/Interfaces.hxx | 69 +++++++++++++++++++ .../ComponentInterface/componenthandshake.cxx | 14 ++++ 7 files changed, 135 insertions(+) diff --git a/Modules/Core/ComponentInterface/ComponentBase.h b/Modules/Core/ComponentInterface/ComponentBase.h index 3249b12a..78da4c6a 100644 --- a/Modules/Core/ComponentInterface/ComponentBase.h +++ b/Modules/Core/ComponentInterface/ComponentBase.h @@ -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 diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx index b2118b13..0b8fac5c 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx @@ -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); diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h index 8ff19a2f..7addba7b 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h @@ -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(); diff --git a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx index cd797a94..16df9f8d 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx +++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx @@ -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); diff --git a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h index f6598949..2e3a33d8 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h +++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h @@ -16,6 +16,7 @@ namespace elx ~GDOptimizer4thPartyComponent(); Example4thParty::GDOptimizer4thParty* theImplementation; Metric4thPartyWrapper* MetricObject; + virtual int ConnectFrom(const char *, ComponentBase*); int Set(MetricValueInterface*); int Update(); }; diff --git a/Modules/Core/ComponentInterface/Interfaces.hxx b/Modules/Core/ComponentInterface/Interfaces.hxx index ee85ebeb..c74468bb 100644 --- a/Modules/Core/ComponentInterface/Interfaces.hxx +++ b/Modules/Core/ComponentInterface/Interfaces.hxx @@ -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 diff --git a/Modules/Core/ComponentInterface/componenthandshake.cxx b/Modules/Core/ComponentInterface/componenthandshake.cxx index b7cb8fed..930b2028 100644 --- a/Modules/Core/ComponentInterface/componenthandshake.cxx +++ b/Modules/Core/ComponentInterface/componenthandshake.cxx @@ -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) { -- GitLab