diff --git a/Modules/Core/ComponentInterface/ComponentBase.h b/Modules/Core/ComponentInterface/ComponentBase.h index 06857cfde89a01399fc88c6ac14e08aabec1a71c..934d9660478526f346e3ac662d3860b69a4bc55c 100644 --- a/Modules/Core/ComponentInterface/ComponentBase.h +++ b/Modules/Core/ComponentInterface/ComponentBase.h @@ -3,9 +3,11 @@ namespace elx { + enum interfaceStatus { success, noaccepter, noprovider }; + class ComponentBase { public: - virtual int ConnectFrom(const char *, ComponentBase*) { return 0; }; //= 0; + virtual interfaceStatus ConnectFrom(const char *, ComponentBase*) = 0; protected: virtual ~ComponentBase(){}; }; diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx index 87146c75094bb083b60eb4dd26ed57fc06c49fc4..3f0e0db01c83d6a4f24d67490df5a12f0a9a1555 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx @@ -14,36 +14,6 @@ GDOptimizer3rdPartyComponent::~GDOptimizer3rdPartyComponent() } -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); - // static_cast always succeeds since we know via the template arguments of the component what InterfaceAcceptors are base classes. - // connect value interfaces - if (1 == acceptIF->Connect(other)) - { - return 1; //success, assume only one interface listens interfacename - } - else - { - 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 8a8cd8195321acfb8b381c4fca59804a78d88c3d..c584235d0b7311cd6a1db54c57076439c520f028 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h @@ -13,7 +13,6 @@ namespace elx class GDOptimizer3rdPartyComponent : public Implements< Accepting< MetricValueInterface, MetricDerivativeInterface >, - //Accepting< InterfaceAcceptor<MetricValueInterface>, InterfaceAcceptor<MetricDerivativeInterface> >, Providing< OptimizerUpdateInterface> > { @@ -22,7 +21,7 @@ namespace elx ~GDOptimizer3rdPartyComponent(); Example3rdParty::GDOptimizer3rdParty* theImplementation; Metric3rdPartyWrapper* MetricObject; - virtual int ConnectFrom(const char *, ComponentBase*); + //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 16df9f8d380bf162d74216898cc798fad8a6962c..78a496b18df24fead5ff2ba4382341179366ac75 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx +++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.cxx @@ -15,22 +15,6 @@ 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) { diff --git a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h index 2e3a33d8643e1c7c889805560d2dbfe5a3a2b6b2..29f03e9639b0f223992d1aeea24c655995e17875 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h +++ b/Modules/Core/ComponentInterface/GDOptimizer4thPartyComponent.h @@ -9,14 +9,19 @@ namespace elx { // wrapping into components: - class GDOptimizer4thPartyComponent : public ComponentBase, public InterfaceAcceptor<MetricValueInterface>, public OptimizerUpdateInterface + class GDOptimizer4thPartyComponent : + public Implements < + Accepting< MetricValueInterface >, + Providing < OptimizerUpdateInterface > + > + { public: GDOptimizer4thPartyComponent(); ~GDOptimizer4thPartyComponent(); Example4thParty::GDOptimizer4thParty* theImplementation; Metric4thPartyWrapper* MetricObject; - virtual int ConnectFrom(const char *, ComponentBase*); + //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 f5071a0b5ea7eb2842c95fb7f765a8fc31b7a640..b372806dfc0e9124178c985b708204fe57058115 100644 --- a/Modules/Core/ComponentInterface/Interfaces.hxx +++ b/Modules/Core/ComponentInterface/Interfaces.hxx @@ -26,92 +26,53 @@ public: template<class InterfaceT> class InterfaceAcceptor { public: - virtual int Set(InterfaceT*) = 0; + + // Set() is called by a succesfull Connect() + // The implementation of Set() must be provided by component developers. + virtual int Set(InterfaceT*) = 0; + + // Connect tries to connect this accepting interface with all interfaces of the provider component. 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 " << InterfaceName < InterfaceT >::Get() << 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; - } - - -//template<typename... Interfaces> -//class Accepting : public Interfaces... -//{ -//}; - -//template<> -//class Accepting<> -//{ -//}; -//template<typename FirstInterface> -//class Accepting : public InterfaceAcceptor < FirstInterface > -//{ -//}; template<typename ... RestInterfaces> class Accepting { + public: + interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ; }; - -//template<typename FirstInterface, typename ... RestInterfaces> -//class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > -//{ -//}; - template<typename FirstInterface, typename ... RestInterfaces> -class Accepting<FirstInterface, RestInterfaces... > : public Accepting< RestInterfaces ... >, public InterfaceAcceptor<FirstInterface> +class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > { - //FirstInterface firstIF; +public: + interfaceStatus ConnectFromImpl(const char *, ComponentBase*); }; + template<typename... Interfaces> class Providing : public Interfaces... { }; template<typename AcceptingInterfaces, typename ProvidingInterfaces> -class Implements : public ComponentBase, public AcceptingInterfaces, public ProvidingInterfaces +class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase { - typedef typename AcceptingInterfaces AcceptingInterfacesType; - typedef typename ProvidingInterfaces ProvidingInterfacesType; + public: + virtual interfaceStatus ConnectFrom(const char *, ComponentBase*); + //typedef typename AcceptingInterfaces AcceptingInterfacesType; + //typedef typename ProvidingInterfaces ProvidingInterfacesType; }; -/* -// -template <typename First, typename ... Rest> -int ConnectFromBaseQueryInterface(GUID const & id) noexcept -{ - if (id == __uuidof(First) || id == __uuidof(::IUnknown)) - { - return static_cast<First *>(this); - } - if (IsInspectable<Interfaces ...>() && - id == __uuidof(::IInspectable)) - { - return FindInspectable<Interfaces ...>(); - } - return FindInterface<Rest ...>(id); -} -*/ // TEST template<class InterfaceT> class InterfaceProvider { @@ -179,6 +140,56 @@ struct AcceptorInterfaceName } }; +template<class InterfaceT> +int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ + + InterfaceT* providerInterface = dynamic_cast<InterfaceT*> (providerComponent); + if (!providerInterface) + { + std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << 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 at component level + return 1; +} + +//template<template<typename... RestInterfacesT> class AcceptingT, typename ProvidingT> +//interfaceStatus Implements<AcceptingT<RestInterfacesT... >, ProvidingT>::ConnectFrom(const char * interfacename, ComponentBase* other) +//{ +// :ConnectFrom(const char * interfacename, ComponentBase* other) +//} + +template<typename AcceptingInterfaces, typename ProvidingInterfaces> +interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other) +{ + return AcceptingInterfaces::ConnectFromImpl(interfacename, other); +} + + +template<typename FirstInterface, typename ... RestInterfaces> +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)) + { + // static_cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are. + InterfaceAcceptor<FirstInterface>* acceptIF = static_cast<InterfaceAcceptor<FirstInterface>*> (this); + + // See if the other component has the right interface and try to connect them + 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; + } + else + { + // interfacename was found, but other component doesn't match + return interfaceStatus::noprovider; + } + } + return Accepting< RestInterfaces ... >::ConnectFromImpl(interfacename, other); +} } // end namespace elx #endif // #define Interfaces_hxx \ No newline at end of file diff --git a/Modules/Core/ComponentInterface/SSDMetric3rdPartyComponent.h b/Modules/Core/ComponentInterface/SSDMetric3rdPartyComponent.h index 6adfcc19ca8d3d5103f79ebec6ee0e4a8244e053..e789950ac4e3223f4d613a8edbd4e7c110e3a3e2 100644 --- a/Modules/Core/ComponentInterface/SSDMetric3rdPartyComponent.h +++ b/Modules/Core/ComponentInterface/SSDMetric3rdPartyComponent.h @@ -8,7 +8,12 @@ namespace elx { // SSDMetric3rdPartyComponent provides a value and a derivative - class SSDMetric3rdPartyComponent : public ComponentBase, public MetricDerivativeInterface, public MetricValueInterface { + class SSDMetric3rdPartyComponent : + public Implements< + Accepting<>, + Providing< MetricDerivativeInterface, MetricValueInterface> + > + { public: SSDMetric3rdPartyComponent(); ~SSDMetric3rdPartyComponent(); diff --git a/Modules/Core/ComponentInterface/SSDMetric4thPartyComponent.h b/Modules/Core/ComponentInterface/SSDMetric4thPartyComponent.h index 49e17a476accd5da3c6bb18b11cd6c716481d70f..26685c74fd4f941ebc339a78e4471fc6f71ce2b3 100644 --- a/Modules/Core/ComponentInterface/SSDMetric4thPartyComponent.h +++ b/Modules/Core/ComponentInterface/SSDMetric4thPartyComponent.h @@ -8,7 +8,12 @@ namespace elx { // SSDMetric4thPartyComponent provides only a value and not a derivative - class SSDMetric4thPartyComponent : public ComponentBase, public MetricValueInterface { + class SSDMetric4thPartyComponent : + public Implements< + Accepting<>, + Providing< MetricValueInterface> + > + { public: SSDMetric4thPartyComponent(); ~SSDMetric4thPartyComponent(); diff --git a/Modules/Core/ComponentInterface/componenthandshake.cxx b/Modules/Core/ComponentInterface/componenthandshake.cxx index 78149b0c73f0173f779567a1f636c88ffa93a040..fa665ed990a1e2097051e27fc57eab61f94bb9a0 100644 --- a/Modules/Core/ComponentInterface/componenthandshake.cxx +++ b/Modules/Core/ComponentInterface/componenthandshake.cxx @@ -13,8 +13,6 @@ using namespace elx; int main() { { - tuple<double, long long, const char*> t1(12.2, 42, "big"); - std::cout << InterfaceName<MetricValueInterface>::Get() << std::endl; std::cout << AcceptorInterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl; @@ -47,7 +45,7 @@ using namespace elx; GDOptimizer4thPartyComponent* tempOptimizer4p = new GDOptimizer4thPartyComponent(); ComponentBase* optimizer4p = tempOptimizer4p; // type returned by our component factory - int success = optimizer4p->ConnectFrom("MetricValueInterface", metric4p); + interfaceStatus IFstatus = optimizer4p->ConnectFrom("MetricValueInterface", metric4p); InterfaceAcceptor<MetricValueInterface>* opValIF = dynamic_cast<InterfaceAcceptor<MetricValueInterface>*> (optimizer4p); if (!opValIF)