celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject celix git commit: CELIX-370: Adds callbacks support for C++ dep man for C service dependencies
Date Thu, 21 Jul 2016 15:10:36 GMT
Repository: celix
Updated Branches:
  refs/heads/develop f453a4676 -> 84bdb0c0b


CELIX-370: Adds callbacks support for C++ dep man for C service dependencies


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/84bdb0c0
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/84bdb0c0
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/84bdb0c0

Branch: refs/heads/develop
Commit: 84bdb0c0b6ca1f72532be54d73d10ef5cb767a71
Parents: f453a46
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Thu Jul 21 17:10:06 2016 +0200
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Thu Jul 21 17:10:06 2016 +0200

----------------------------------------------------------------------
 .../include/celix/dm/ServiceDependency.h        |  48 ++++++-
 .../include/celix/dm/ServiceDependency_Impl.h   | 125 +++++++++++++++++++
 documents/best_practices/README.md              |   1 +
 .../dm_example_cxx/phase2/include/Phase2Cmp.h   |   6 +
 .../phase2a/src/Phase2aActivator.cc             |   3 +-
 .../dm_example_cxx/phase2a/src/Phase2aCmp.cc    |   5 +
 .../phase2b/src/Phase2bActivator.cc             |   3 +-
 .../dm_example_cxx/phase2b/src/Phase2bCmp.cc    |   5 +
 8 files changed, 192 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/ServiceDependency.h b/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
index 7b635c3..df3f432 100644
--- a/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
+++ b/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
@@ -70,6 +70,19 @@ namespace celix { namespace dm {
 
     template<class T>
     class CServiceDependency : public TypedServiceDependency<T> {
+    private:
+        void (T::*setFp)(const void* service) {nullptr};
+        void (T::*setFpWithProperties)(const void* service, Properties&& properties)
{nullptr};
+
+        void (T::*addFp)(const void* service) {nullptr};
+        void (T::*addFpWithProperties)(const void* service, Properties&& properties)
{nullptr};
+
+        void (T::*removeFp)(const void* service) {nullptr};
+        void (T::*removeFpWithProperties)(const void* service, Properties&& properties)
{nullptr};
+
+        void setupCallbacks();
+        int invokeCallback(void(T::*fp)(const void*), const void* service);
+        int invokeCallbackWithProperties(void(T::*fp)(const void*, Properties&&),
service_reference_pt  ref, const void* service);
     public:
         CServiceDependency() : TypedServiceDependency<T>() {};
         virtual ~CServiceDependency() = default;
@@ -97,11 +110,42 @@ namespace celix { namespace dm {
          * @return the C service dependency reference for chaining (fluent API)
          */
         CServiceDependency<T>& setStrategy(DependencyUpdateStrategy strategy);
+
+        /**
+         * Set the set callback for when the service dependency becomes available
+         *
+         * @return the C++ service dependency reference for chaining (fluent API)
+         */
+        CServiceDependency<T>& setCallbacks(void (T::*set)(const void* service));
+
+        /**
+         * Set the set callback for when the service dependency becomes available
+         *
+         * @return the C++ service dependency reference for chaining (fluent API)
+         */
+        CServiceDependency<T>& setCallbacks(void (T::*set)(const void* service,
Properties&& properties));
+
+        /**
+         * Set the add and remove callback for when the services of service dependency are
added or removed.
+         *
+         * @return the C++ service dependency reference for chaining (fluent API)
+         */
+        CServiceDependency<T>& setCallbacks( void (T::*add)(const void* service),
 void (T::*remove)(const void* service));
+
+        /**
+         * Set the add and remove callback for when the services of service dependency are
added or removed.
+         *
+         * @return the C++ service dependency reference for chaining (fluent API)
+         */
+        CServiceDependency<T>& setCallbacks(
+                void (T::*add)(const void* service, Properties&& properties),
+                void (T::*remove)(const void* service, Properties&& properties)
+        );
     };
 
     template<class T, class I>
     class ServiceDependency : public TypedServiceDependency<T> {
-    protected:
+    private:
         std::string name {};
         std::string filter {};
         std::string versionRange {};
@@ -115,7 +159,7 @@ namespace celix { namespace dm {
 
         void (T::*removeFp)(I* service) {nullptr};
         void (T::*removeFpWithProperties)(I* service, Properties&& properties) {nullptr};
-    private:
+
         void setupService();
         void setupCallbacks();
         int invokeCallback(void(T::*fp)(I*), const void* service);

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h b/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
index 4f23b61..9300253 100644
--- a/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
+++ b/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
@@ -42,6 +42,131 @@ CServiceDependency<T>& CServiceDependency<T>::setStrategy(DependencyUpdateStrate
     return *this;
 }
 
+//set callbacks
+template<class T>
+CServiceDependency<T>& CServiceDependency<T>::setCallbacks(void (T::*set)(const
void* service)) {
+    this->setFp = set;
+    this->setupCallbacks();
+    return *this;
+}
+
+template<class T>
+CServiceDependency<T>& CServiceDependency<T>::setCallbacks(void (T::*set)(const
void* service, Properties&& properties)) {
+    this->setFpWithProperties = set;
+    this->setupCallbacks();
+    return *this;
+}
+
+//add remove callbacks
+template<class T>
+CServiceDependency<T>& CServiceDependency<T>::setCallbacks(
+        void (T::*add)(const void* service),
+        void (T::*remove)(const void* service)) {
+    this->addFp = add;
+    this->removeFp = remove;
+    this->setupCallbacks();
+    return *this;
+}
+
+template<class T>
+CServiceDependency<T>& CServiceDependency<T>::setCallbacks(
+        void (T::*add)(const void* service, Properties&& properties),
+        void (T::*remove)(const void* service, Properties&& properties)
+) {
+    this->addFpWithProperties = add;
+    this->removeFpWithProperties = remove;
+    this->setupCallbacks();
+    return *this;
+}
+
+
+template<class T>
+void CServiceDependency<T>::setupCallbacks() {
+
+    int(*cset)(void*,const void*) {nullptr};
+    int(*cadd)(void*, const void*) {nullptr};
+    int(*cremove)(void*, const void*) {nullptr};
+
+
+    if (setFp != nullptr) {
+        cset = [](void* handle, const void*service) -> int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallback(dep->setFp, service);
+        };
+    }
+    if (addFp != nullptr) {
+        cadd = [](void* handle, const void*service) -> int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallback(dep->addFp, service);
+        };
+    }
+    if (removeFp != nullptr) {
+        cremove = [](void* handle, const void*service) -> int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallback(dep->removeFp, service);
+        };
+    }
+
+    int(*csetWithRef)(void*, service_reference_pt, const void*) {nullptr};
+    int(*caddWithRef)(void*, service_reference_pt, const void*) {nullptr};
+    int(*cremoveWithRef)(void*, service_reference_pt, const void*) {nullptr};
+
+    if (setFpWithProperties != nullptr) {
+        csetWithRef = [](void* handle, service_reference_pt ref, const void* service) ->
int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallbackWithProperties(dep->setFpWithProperties, ref,
service);
+        };
+    }
+    if (addFpWithProperties != nullptr) {
+        caddWithRef = [](void* handle, service_reference_pt ref, const void* service) ->
int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallbackWithProperties(dep->addFpWithProperties, ref,
service);
+        };
+    }
+    if (removeFpWithProperties != nullptr) {
+        cremoveWithRef = [](void* handle, service_reference_pt ref, const void* service)
-> int {
+            auto dep = (CServiceDependency<T>*) handle;
+            return dep->invokeCallbackWithProperties(dep->removeFpWithProperties, ref,
service);
+        };
+    }
+
+    serviceDependency_setCallbackHandle(this->cServiceDependency(), this);
+    serviceDependency_setCallbacks(this->cServiceDependency(), cset, cadd, nullptr, cremove,
nullptr);
+    serviceDependency_setCallbacksWithServiceReference(this->cServiceDependency(), csetWithRef,
caddWithRef, nullptr, cremoveWithRef, nullptr);
+};
+
+template<class T>
+int CServiceDependency<T>::invokeCallback(void(T::*fp)(const void* service), const
void* service) {
+    T *cmp = this->componentInstance;
+    (cmp->*fp)(service);
+    return 0;
+};
+
+template<class T>
+int CServiceDependency<T>::invokeCallbackWithProperties(void(T::*fp)(const void*, Properties&&),
service_reference_pt  ref, const void* service) {
+    service_registration_pt reg {nullptr};
+    properties_pt props {nullptr};
+    T *cmp = this->componentInstance;
+    serviceReference_getServiceRegistration(ref, &reg);
+    serviceRegistration_getProperties(reg, &props);
+
+    Properties properties {};
+    const char* key {nullptr};
+    const char* value {nullptr};
+
+    hash_map_iterator_t iter = hashMapIterator_construct((hash_map_pt)props);
+    while(hashMapIterator_hasNext(&iter)) {
+        key = (const char*) hashMapIterator_nextKey(&iter);
+        value = properties_get(props, key);
+        //std::cout << "got property " << key << "=" << value <<
"\n";
+        properties[key] = value;
+    }
+
+    (cmp->*fp)(service, static_cast<Properties&&>(properties)); //explicit
move of lvalue properties.
+    return 0;
+}
+
+
 template<class T, class I>
 ServiceDependency<T,I>::ServiceDependency() : TypedServiceDependency<T>() {
     setupService();

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/documents/best_practices/README.md
----------------------------------------------------------------------
diff --git a/documents/best_practices/README.md b/documents/best_practices/README.md
index 9671b2d..1e5ab76 100644
--- a/documents/best_practices/README.md
+++ b/documents/best_practices/README.md
@@ -94,6 +94,7 @@ The error checking is very minimal in these example to keep the focus on
how to
 
 
 ### Bar example
+
 The bar example is a simple component providing the `example` service. 
  
 ```C

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/examples/dm_example_cxx/phase2/include/Phase2Cmp.h
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2/include/Phase2Cmp.h b/examples/dm_example_cxx/phase2/include/Phase2Cmp.h
index 4288e3e..ca85cc4 100644
--- a/examples/dm_example_cxx/phase2/include/Phase2Cmp.h
+++ b/examples/dm_example_cxx/phase2/include/Phase2Cmp.h
@@ -27,13 +27,19 @@
 #include <thread>
 #include <iostream>
 
+extern "C" {
+#include "log_service.h"
+};
+
 class Phase2Cmp : public IPhase2 {
     IPhase1* phase1 {nullptr};
+    log_service_pt logSrv {nullptr};
 public:
     Phase2Cmp() = default;
     virtual ~Phase2Cmp() { std::cout << "Destroying Phase2\n"; };
 
     void setPhase1(IPhase1* phase); //injector used by dependency manager
+    void setLogService(log_service_pt logSrv);
 
     virtual double getData(); //implements IPhase2
 private:

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc b/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
index fc6269a..d90b5d0 100644
--- a/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
+++ b/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
@@ -43,7 +43,8 @@ void Phase2Activator::init(DependencyManager& manager) {
         )
         .add(createCServiceDependency<Phase2Cmp>()
             .setRequired(false)
-            .setCService(OSGI_LOGSERVICE_NAME, {}, {})
+            .setCService(OSGI_LOGSERVICE_NAME, "", "")
+            .setCallbacks((void (Phase2Cmp::*)(const void*)) &Phase2Cmp::setLogService)
         )
     );
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/examples/dm_example_cxx/phase2a/src/Phase2aCmp.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2a/src/Phase2aCmp.cc b/examples/dm_example_cxx/phase2a/src/Phase2aCmp.cc
index 088c218..e72a36c 100644
--- a/examples/dm_example_cxx/phase2a/src/Phase2aCmp.cc
+++ b/examples/dm_example_cxx/phase2a/src/Phase2aCmp.cc
@@ -27,6 +27,11 @@ void Phase2Cmp::setPhase1(IPhase1* phase1) {
     this->phase1 = phase1;
 }
 
+void Phase2Cmp::setLogService(log_service_pt logSrv) {
+    this->logSrv = logSrv;
+}
+
 double Phase2Cmp::getData() {
+    logSrv->log(logSrv->logger, OSGI_LOGSERVICE_DEBUG, (char*)"getting data from phase2cmp
A\n");
     return phase1->getData() * 42.0;
 };

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc b/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
index f518581..c026203 100644
--- a/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
+++ b/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
@@ -42,7 +42,8 @@ void Phase2Activator::init(DependencyManager& manager) {
         )
         .add(createCServiceDependency<Phase2Cmp>()
             .setRequired(false)
-            .setCService(OSGI_LOGSERVICE_NAME, {}, {})
+            .setCService(OSGI_LOGSERVICE_NAME, "", "")
+            .setCallbacks((void (Phase2Cmp::*)(const void*)) &Phase2Cmp::setLogService)
         )
     );
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/84bdb0c0/examples/dm_example_cxx/phase2b/src/Phase2bCmp.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2b/src/Phase2bCmp.cc b/examples/dm_example_cxx/phase2b/src/Phase2bCmp.cc
index fac2867..cd6df23 100644
--- a/examples/dm_example_cxx/phase2b/src/Phase2bCmp.cc
+++ b/examples/dm_example_cxx/phase2b/src/Phase2bCmp.cc
@@ -27,6 +27,11 @@ void Phase2Cmp::setPhase1(IPhase1* phase1) {
     this->phase1 = phase1;
 }
 
+void Phase2Cmp::setLogService(log_service_pt logSrv) {
+    this->logSrv = logSrv;
+}
+
 double Phase2Cmp::getData() {
+    logSrv->log(logSrv->logger, OSGI_LOGSERVICE_DEBUG, (char*)"getting data from phase2cmp
B\n");
     return phase1->getData() * 24.0;
 };


Mime
View raw message