Skip to content

Commit

Permalink
CELIX-386: Fixes an issues when C++ objects provide mutiple services.…
Browse files Browse the repository at this point in the history
… Also extends the example with a mutiple service providing example.

Fixes issue in TypeName where namespace where not used for the service name and added an service with namespace example.
  • Loading branch information
pnoltes committed Nov 21, 2016
1 parent 5e9db3d commit 261161f
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 85 deletions.
6 changes: 3 additions & 3 deletions dependency_manager_cxx/include/celix/dm/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ namespace celix { namespace dm {

/**
* Adds a C++ interface to provide as service to the Celix framework.
* The interface name will be inferred using the I template.
*
* @param serviceName The service name to use
* @param version The version of the interface (e.g. "1.0.0"), can be an empty string
* @param properties To (meta) properties to provide with the service
* @return the DM Component reference for chaining (fluent API)
*/
template<class I> Component<T>& addInterface(const std::string version, const Properties properties = Properties{});
template<class I> Component<T>& addInterfaceWithName(const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});

/**
* Adds a C++ interface to provide as service to the Celix framework.
Expand All @@ -121,7 +121,7 @@ namespace celix { namespace dm {
* @param properties To (meta) properties to provide with the service
* @return the DM Component reference for chaining (fluent API)
*/
Component<T>& addInterface(const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});
template<class I> Component<T>& addInterface(const std::string version = std::string{}, const Properties properties = Properties{});

/**
* Adds a C interface to provide as service to the Celix framework.
Expand Down
39 changes: 25 additions & 14 deletions dependency_manager_cxx/include/celix/dm/Component_Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <memory>
#include <iostream>
#include <iomanip>

using namespace celix::dm;

Expand All @@ -36,28 +37,38 @@ Component<T>::~Component() {

template<class T>
template<class I>
Component<T>& Component<T>::addInterface(const std::string version, const Properties props) {
std::string name = typeName<I>();
if (name.empty()) {
std::cerr << "Cannot add interface, because type name could not be inferred. function: '" << __PRETTY_FUNCTION__ << "'\n";
Component<T>& Component<T>::addInterfaceWithName(const std::string serviceName, const std::string version, const Properties properties) {
if (!serviceName.empty()) {
//setup c properties
properties_pt cProperties = properties_create();
properties_set(cProperties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE);
for (auto iter = properties.begin(); iter != properties.end(); iter++) {
properties_set(cProperties, (char *) iter->first.c_str(), (char *) iter->second.c_str());
}

T* cmpPtr = &this->getInstance();
I* intfPtr = static_cast<I*>(cmpPtr); //NOTE T should implement I

const char *cVersion = version.empty() ? nullptr : version.c_str();
component_addInterface(this->cComponent(), (char *) serviceName.c_str(), (char *) cVersion,
intfPtr, cProperties);
} else {
this->addInterface(name, version.c_str(), props);
std::cerr << "Cannot add interface with a empty name\n";
}

return *this;
}

template<class T>
Component<T>& Component<T>::addInterface(const std::string serviceName, const std::string version, const Properties properties) {
properties_pt cProperties = properties_create();
properties_set(cProperties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE);
for (auto iter = properties.begin(); iter != properties.end(); iter++) {
properties_set(cProperties, (char*)iter->first.c_str(), (char*)iter->second.c_str());
template<class I>
Component<T>& Component<T>::addInterface(const std::string version, const Properties properties) {
//get name if not provided
std::string serviceName = typeName<I>();
if (serviceName.empty()) {
std::cerr << "Cannot add interface, because type name could not be inferred. function: '" << __PRETTY_FUNCTION__ << "'\n";
}

const char *cVersion = version.empty() ? nullptr : version.c_str();
component_addInterface(this->cComponent(), (char*)serviceName.c_str(), (char*)cVersion, &this->getInstance(), cProperties);

return *this;
return this->addInterfaceWithName<I>(serviceName, version, properties);
};

template<class T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ ServiceDependency<T,I>& ServiceDependency<T,I>::setStrategy(DependencyUpdateStra
template<class T, class I>
int ServiceDependency<T,I>::invokeCallback(void(T::*fp)(I*), const void* service) {
T *cmp = this->componentInstance;
I *svc = (I *) service;
I *svc = (I*)service;
(cmp->*fp)(svc);
return 0;
};
Expand All @@ -364,7 +364,7 @@ int ServiceDependency<T,I>::invokeCallbackWithProperties(void(T::*fp)(I*, Proper
service_registration_pt reg {nullptr};
properties_pt props {nullptr};
T *cmp = this->componentInstance;
I *svc = (I *) service;
I *svc = (I*)service;
serviceReference_getServiceRegistration(ref, &reg);
serviceRegistration_getProperties(reg, &props);

Expand Down
11 changes: 5 additions & 6 deletions dependency_manager_cxx/include/celix/dm/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,21 @@ namespace celix { namespace dm {
free(demangled_name);
}
#else
const char *templateStr = "INTERFACE_TYPENAME =";
const char *templateStr = "INTERFACE_TYPENAME = ";
const size_t templateStrLen = strlen(templateStr);

result = __PRETTY_FUNCTION__; //USING pretty function to retrieve the filled in template argument without using typeid()

size_t bpos = result.find(templateStr) + templateStrLen + 1; //find begin pos after INTERFACE_TYPENAME = entry
size_t bpos = result.find(templateStr) + templateStrLen; //find begin pos after INTERFACE_TYPENAME = entry
size_t epos = bpos;
while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ';') {
while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':') {
epos += 1;
}
size_t len = epos - bpos;
result = result.substr(bpos, len);
#endif

//std::cout << "PRETTY IS '" << __PRETTY_FUNCTION__ << "'\n";
//std::cout << "RESULT IS '" << result << "'\n";
// std::cout << "PRETTY IS '" << __PRETTY_FUNCTION__ << "'\n";
// std::cout << "RESULT IS '" << result << "'\n";

if (result.empty()) {
std::cerr << "Cannot infer type name in function call '" << __PRETTY_FUNCTION__ << "'\n'";
Expand Down
39 changes: 39 additions & 0 deletions examples/dm_example_cxx/api/IName.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#ifndef CELIX_INAME_H
#define CELIX_INAME_H

#define INAME_VERSION "1.0.0"

#include <string>

namespace srv {
namespace info {
class IName {
protected:
IName() = default;
~IName() = default;
public:
virtual std::string getName() = 0;
};
}
}

#endif //CELIX_INAME_H
1 change: 1 addition & 0 deletions examples/dm_example_cxx/api/IPhase1.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
class IPhase1 {
protected:
IPhase1() = default;
~IPhase1() = default;
public:
virtual int getData() = 0;
};
Expand Down
1 change: 1 addition & 0 deletions examples/dm_example_cxx/api/IPhase2.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
class IPhase2 {
protected:
IPhase2() = default;
~IPhase2() = default;
public:
virtual double getData() = 0;
};
Expand Down
6 changes: 4 additions & 2 deletions examples/dm_example_cxx/phase1/include/Phase1Cmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
#define CELIX_PHASE1CMP_H

#include "IPhase1.h"
#include "IName.h"
#include <stdint.h>
#include <stdio.h>

class Phase1Cmp : public IPhase1 {
class Phase1Cmp : public srv::info::IName, public IPhase1 {
uint32_t counter = 0;
public:
Phase1Cmp() = default;
Expand All @@ -35,8 +36,9 @@ class Phase1Cmp : public IPhase1 {
void stop();
void deinit();

virtual int getData(); //implements IPhase1
int getData() override; //implements IPhase1
virtual int infoCmd(char* line, FILE *out, FILE* err); //implements cmd service
std::string getName() override;
};

#endif //CELIX_PHASE1CMP_H
57 changes: 0 additions & 57 deletions examples/dm_example_cxx/phase1/src/BarActivator.cc

This file was deleted.

1 change: 1 addition & 0 deletions examples/dm_example_cxx/phase1/src/Phase1Activator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void Phase1Activator::init() {
createComponent(cmp) //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
.addInterface<IPhase1>(IPHASE1_VERSION)
.addCInterface(&cmd, OSGI_SHELL_COMMAND_SERVICE_NAME, "", cmdProps)
.addInterface<srv::info::IName>(INAME_VERSION)
.setCallbacks(&Phase1Cmp::init, &Phase1Cmp::start, &Phase1Cmp::stop, &Phase1Cmp::deinit);
}

Expand Down
4 changes: 4 additions & 0 deletions examples/dm_example_cxx/phase1/src/Phase1Cmp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ int Phase1Cmp::getData() {
return rand();
};

std::string Phase1Cmp::getName() {
return std::string {"IPhase"};
}

int Phase1Cmp::infoCmd(char * line, FILE *out, FILE *err) {
fprintf(out, "Phase1: number of getData calls: %u\n", counter);
return 0;
Expand Down
4 changes: 3 additions & 1 deletion examples/dm_example_cxx/phase2/include/Phase2Cmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef CELIX_PHASE2CMP_H
#define CELIX_PHASE2CMP_H

#include "IName.h"
#include "IPhase1.h"
#include "IPhase2.h"
#include <stdint.h>
Expand All @@ -39,9 +40,10 @@ class Phase2Cmp : public IPhase2 {
virtual ~Phase2Cmp() { std::cout << "Destroying Phase2\n"; };

void setPhase1(IPhase1* phase); //injector used by dependency manager
void setName(srv::info::IName* name) { std::cout << "Setting IName with name: " << name->getName() << std::endl; }
void setLogService(const log_service_t* logSrv);

virtual double getData(); //implements IPhase2
double getData() override; //implements IPhase2
private:
IPhase1* phase1 {nullptr};
const log_service_t* logSrv {nullptr};
Expand Down
5 changes: 5 additions & 0 deletions examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

#include <IName.h>
#include "Phase2Cmp.h"
#include "Phase2Activator.h"
#include "log_service.h"
Expand All @@ -42,6 +43,10 @@ void Phase2Activator::init() {
.setRequired(true)
.setCallbacks(&Phase2Cmp::setPhase1);

cmp.createServiceDependency<srv::info::IName>()
.setVersionRange("[1.0.0,2)")
.setCallbacks(&Phase2Cmp::setName);

cmp.createCServiceDependency<log_service_t>(OSGI_LOGSERVICE_NAME)
.setRequired(false)
.setCallbacks(&Phase2Cmp::setLogService);
Expand Down

0 comments on commit 261161f

Please sign in to comment.