Commit d6d0cbf5 authored by François Grisez's avatar François Grisez

C++ wrapper generator - intitial commit

parent 19d47a64
......@@ -105,3 +105,5 @@ git-clang-format.diff
.bc_tester_utils.tmp
tools/lp-test-ecc
tools/lp-sendmsg
*.pyc
......@@ -60,6 +60,7 @@ cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENAB
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
option(ENABLE_NLS "Build with internationalisation support" YES)
option(ENABLE_VCARD "Turn on compilation of vcard4 support." YES)
option(CXX_WRAPPER "Build the C++ wrapper for Liblinphone." OFF)
macro(apply_compile_flags SOURCE_FILES)
......@@ -180,6 +181,10 @@ endif()
if(ENABLE_LIME)
set(HAVE_LIME 1)
endif()
if (CXX_WRAPPER)
set(Python_ADDITIONAL_VERSIONS 2)
find_package(PythonInterp REQUIRED)
endif()
if(UNIX AND NOT APPLE)
include(CheckIncludeFiles)
......@@ -326,6 +331,9 @@ endif()
if(ENABLE_UNIT_TESTS AND BCTOOLBOX_TESTER_FOUND)
add_subdirectory(tester)
endif()
if(CXX_WRAPPER)
add_subdirectory(wrappers/cpp)
endif()
include(CMakePackageConfigHelpers)
......
set(GENERATED_SOURCES
src/account_creator.cc
src/address.cc
src/auth_info.cc
src/buffer.cc
src/call.cc
src/call_log.cc
src/call_params.cc
src/call_stats.cc
src/chat_message.cc
src/chat_room.cc
src/conference.cc
src/conference_params.cc
src/config.cc
src/content.cc
src/core.cc
src/core_v_table.cc
src/error_info.cc
src/event.cc
src/factory.cc
src/friend.cc
src/friend_list.cc
src/nat_policy.cc
src/payload_type.cc
src/player.cc
src/presence_activity.cc
src/presence_model.cc
src/presence_note.cc
src/presence_person.cc
src/presence_service.cc
src/proxy_config.cc
src/sip_transports.cc
src/tunnel.cc
src/tunnel_config.cc
src/vcard.cc
src/video_policy.cc
src/xml_rpc_request.cc
src/xml_rpc_session.cc
)
set(SOURCES
${GENERATED_SOURCES}
object.cc
)
set(GENERATED_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/include/account_creator.hh
${CMAKE_CURRENT_BINARY_DIR}/include/account_creator_listener.hh
${CMAKE_CURRENT_BINARY_DIR}/include/address.hh
${CMAKE_CURRENT_BINARY_DIR}/include/auth_info.hh
${CMAKE_CURRENT_BINARY_DIR}/include/buffer.hh
${CMAKE_CURRENT_BINARY_DIR}/include/call.hh
${CMAKE_CURRENT_BINARY_DIR}/include/call_log.hh
${CMAKE_CURRENT_BINARY_DIR}/include/call_params.hh
${CMAKE_CURRENT_BINARY_DIR}/include/call_stats.hh
${CMAKE_CURRENT_BINARY_DIR}/include/chat_message.hh
${CMAKE_CURRENT_BINARY_DIR}/include/chat_message_listener.hh
${CMAKE_CURRENT_BINARY_DIR}/include/chat_room.hh
${CMAKE_CURRENT_BINARY_DIR}/include/conference.hh
${CMAKE_CURRENT_BINARY_DIR}/include/conference_params.hh
${CMAKE_CURRENT_BINARY_DIR}/include/config.hh
${CMAKE_CURRENT_BINARY_DIR}/include/content.hh
${CMAKE_CURRENT_BINARY_DIR}/include/core.hh
${CMAKE_CURRENT_BINARY_DIR}/include/core_listener.hh
${CMAKE_CURRENT_BINARY_DIR}/include/core_v_table.hh
${CMAKE_CURRENT_BINARY_DIR}/include/enums.hh
${CMAKE_CURRENT_BINARY_DIR}/include/error_info.hh
${CMAKE_CURRENT_BINARY_DIR}/include/event.hh
${CMAKE_CURRENT_BINARY_DIR}/include/factory.hh
${CMAKE_CURRENT_BINARY_DIR}/include/friend.hh
${CMAKE_CURRENT_BINARY_DIR}/include/friend_list.hh
${CMAKE_CURRENT_BINARY_DIR}/include/friend_list_listener.hh
${CMAKE_CURRENT_BINARY_DIR}/include/linphone.hh
${CMAKE_CURRENT_BINARY_DIR}/include/nat_policy.hh
${CMAKE_CURRENT_BINARY_DIR}/include/payload_type.hh
${CMAKE_CURRENT_BINARY_DIR}/include/player.hh
${CMAKE_CURRENT_BINARY_DIR}/include/presence_activity.hh
${CMAKE_CURRENT_BINARY_DIR}/include/presence_model.hh
${CMAKE_CURRENT_BINARY_DIR}/include/presence_note.hh
${CMAKE_CURRENT_BINARY_DIR}/include/presence_person.hh
${CMAKE_CURRENT_BINARY_DIR}/include/presence_service.hh
${CMAKE_CURRENT_BINARY_DIR}/include/proxy_config.hh
${CMAKE_CURRENT_BINARY_DIR}/include/sip_transports.hh
${CMAKE_CURRENT_BINARY_DIR}/include/tunnel_config.hh
${CMAKE_CURRENT_BINARY_DIR}/include/tunnel.hh
${CMAKE_CURRENT_BINARY_DIR}/include/vcard.hh
${CMAKE_CURRENT_BINARY_DIR}/include/video_policy.hh
${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_request.hh
${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_request_listener.hh
${CMAKE_CURRENT_BINARY_DIR}/include/xml_rpc_session.hh
)
set(HEADERS
${GENERATED_HEADERS}
object.hh
)
add_custom_command(OUTPUT ${GENERATED_SOURCES} ${GENERATED_HEADERS}
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genheaders.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml"
DEPENDS *.py *.mustache linphone-doc "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml/index.xml"
)
add_compile_options(-Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Werror --std=c++11)
add_definitions(-DWRAPPER_BUILD)
add_library(linphone++ SHARED ${SOURCES})
target_link_libraries(linphone++ PRIVATE linphone)
target_include_directories(linphone++
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${PROJECT_SOURCE_DIR}
)
set_target_properties(linphone++
PROPERTIES SOVERSION ${LINPHONE_SO_VERSION}
)
install(TARGETS linphone++
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES ${HEADERS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++
)
This diff is collapsed.
This diff is collapsed.
#ifndef {{define}}
#define {{define}}
{{#includes}}
{{#external}}
#include <{{name}}>
{{/external}}
{{#internal}}
#include "{{name}}.hh"
{{/internal}}
{{/includes}}
{{#_class}}{{#isfactory}}
#include "config.hh"
{{/isfactory}}{{/_class}}
#include "linphone/linphonecore.h"
#include "linphone/linphone_tunnel.h"
#include "linphone/linphonecore_utils.h"
namespace linphone {
{{#priorDeclarations}}
class {{{name}}};
{{/priorDeclarations}}
{{#_class}}
class {{className}}: public {{{parentClassName}}} {
{{#friendClasses}}
friend class {{name}};
{{/friendClasses}}
public:
{{#isNotListener}}
{{{className}}}(::belle_sip_object_t *ptr, bool takeRef=true);
{{/isNotListener}}
{{#ismonolistenable}}
void setListener(const std::shared_ptr<{{{listenerClassName}}}> &listener);
{{/ismonolistenable}}
{{#ismultilistenable}}
void addListener(std::shared_ptr<{{{listenerClassName}}}> &listener);
void removeListener(std::shared_ptr<{{{listenerClassName}}}> &listener);
{{/ismultilistenable}}
public:
{{#isfactory}}
std::shared_ptr<Core> createCore(const std::shared_ptr<CoreListener> & cbs, const std::string & configPath, const std::string & factoryConfigPath) const;
std::shared_ptr<Core> createCoreWithConfig(const std::shared_ptr<CoreListener> & cbs, const std::shared_ptr<Config> & config) const;
{{/isfactory}}
{{#methods}}
{{{prototype}}}
{{/methods}}
{{#staticMethods}}
{{{prototype}}}
{{/staticMethods}}
{{#ismultilistenable}}
private:
static {{{cListenerName}}} *createCallbacks(const std::shared_ptr<{{{listenerClassName}}}> &listener);
{{/ismultilistenable}}
{{#islistenable}}
private:
{{#wrapperCbs}}
{{decl}}
{{/wrapperCbs}}
{{/islistenable}}
};
{{/_class}}
};
#endif // {{define}}
#include "linphone.hh"
using namespace {{{namespace}}};
{{#_class}}
{{#isNotListener}}
{{{namespace}}}::{{{className}}}::{{{className}}}(::belle_sip_object_t *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) {}
{{/isNotListener}}
{{#ismonolistenable}}
void {{{namespace}}}::{{{className}}}::setListener(const std::shared_ptr<{{{listenerClassName}}}> & listener) {
ListenableObject::setListener(std::static_pointer_cast<Listener>(listener));
{{{cListenerName}}} *cbs = {{{cCbsGetter}}}(({{{cClassName}}} *)mPrivPtr);
if (listener == nullptr) {
{{#wrapperCbs}}
{{{callbackSetter}}}(cbs, NULL);
{{/wrapperCbs}}
} else {
{{#wrapperCbs}}
{{{callbackSetter}}}(cbs, {{{cbName}}});
{{/wrapperCbs}}
}
}
{{/ismonolistenable}}
{{#ismultilistenable}}
{{{cListenerName}}} *{{{className}}}::createCallbacks(const std::shared_ptr<{{{listenerClassName}}}> &listener) {
{{{cListenerName}}} *cbs = {{{listenerCreator}}}(linphone_factory_get());
{{{userDataSetter}}}(cbs, listener.get());
{{#wrapperCbs}}
{{{callbackSetter}}}(cbs, {{{cbName}}});
{{/wrapperCbs}}
return cbs;
}
void {{{className}}}::addListener(std::shared_ptr<{{{listenerClassName}}}> &listener) {
MultiListenableObject::addListener(std::static_pointer_cast<Listener,{{{listenerClassName}}}>(listener));
{{{cListenerName}}} *cbs = createCallbacks(listener);
{{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, cbs);
listener->setCallbacks((::belle_sip_object_t *)cbs);
belle_sip_object_unref(cbs);
}
void {{{className}}}::removeListener(std::shared_ptr<{{{listenerClassName}}}> &listener) {
::belle_sip_object_t *cbs = belle_sip_object_ref(listener->getCallbacks());
{{{callbacksRemover}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)cbs);
listener->setCallbacks(NULL);
belle_sip_object_unref(cbs);
MultiListenableObject::removeListener(listener);
}
{{/ismultilistenable}}
{{#isfactory}}
std::shared_ptr<Core> Factory::createCore(const std::shared_ptr<CoreListener> & cbs, const std::string & configPath, const std::string & factoryConfigPath) const {
::LinphoneFactory *factory = linphone_factory_get();
::LinphoneCoreCbs *c_cbs = cbs != nullptr ? Core::createCallbacks(cbs) : NULL;
::LinphoneCore *core_ptr = linphone_factory_create_core(factory, c_cbs, configPath.c_str(), factoryConfigPath.c_str());
std::shared_ptr<Core> core = cPtrToSharedPtr<Core>((belle_sip_object_t *)core_ptr, false);
if (core != nullptr && cbs != nullptr) {
std::static_pointer_cast<MultiListenableObject,Core>(core)->addListener(cbs);
cbs->setCallbacks((belle_sip_object_t *)c_cbs);
}
if (c_cbs) linphone_core_cbs_unref(c_cbs);
return core;
}
std::shared_ptr<Core> Factory::createCoreWithConfig(const std::shared_ptr<CoreListener> & cbs, const std::shared_ptr<Config> & config) const {
::LinphoneFactory *factory = linphone_factory_get();
::LinphoneCoreCbs *c_cbs = cbs != nullptr ? Core::createCallbacks(cbs) : NULL;
::LinphoneCore *core_ptr = linphone_factory_create_core_with_config(factory, c_cbs, (::LinphoneConfig *)sharedPtrToCPtr(config));
std::shared_ptr<Core> core = cPtrToSharedPtr<Core>((belle_sip_object_t *)core_ptr, false);
if (core != nullptr && cbs != nullptr) {
std::static_pointer_cast<MultiListenableObject,Core>(core)->addListener(cbs);
cbs->setCallbacks((belle_sip_object_t *)c_cbs);
}
if (c_cbs) linphone_core_cbs_unref(c_cbs);
return core;
}
{{/isfactory}}
{{#methods}}
{{{implPrototype}}} {
{{{sourceCode}}}
}
{{/methods}}
{{#staticMethods}}
{{{implPrototype}}} {
{{{sourceCode}}}
}
{{/staticMethods}}
{{#wrapperCbs}}
{{{returnType}}} {{{className}}}::{{{cbName}}}({{{declArgs}}}) {
{{#ismonolistenable}}std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(getListenerFromObject((::belle_sip_object_t *){{{firstArgName}}}));{{/ismonolistenable}}
{{#ismultilistenable}}
LinphoneCoreCbs *cbs = linphone_core_get_current_callbacks(lc);
CoreListener *listener = (CoreListener *)linphone_core_cbs_get_user_data(cbs);
{{/ismultilistenable}}
{{#hasReturnValue}}return {{/hasReturnValue}}{{{cppMethodCallingLine}}}
}
{{/wrapperCbs}}
{{/_class}}
#ifndef _ENUMS_HH
#define _ENUMS_HH
namespace linphone {
{{#enums}}
enum {{name}} {
{{#values}}
{{name}}{{#notLast}},{{/notLast}}
{{/values}}
};
{{/enums}}
};
#endif //_ENUMS_HH
../../tools/genapixml.py
\ No newline at end of file
This diff is collapsed.
#ifndef {{{define}}}
#define {{{define}}}
{{#includes}}
#include "{{{name}}}"
{{/includes}}
#endif // {{{define}}}
#include "object.hh"
#include <bctoolbox/port.h>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace linphone;
using namespace std;
template <class T>
ObjectBctbxListWrapper<T>::ObjectBctbxListWrapper(const std::list<std::shared_ptr<T> > &cppList): AbstractBctbxListWrapper() {
for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) {
::belle_sip_object_t *cPtr = Object::sharedPtrToCPtr(static_pointer_cast<Object,T>(*it));
if (cPtr != NULL) belle_sip_object_ref(cPtr);
mCList = bctbx_list_append(mCList, cPtr);
}
}
static void unrefData(void *data) {
if (data != NULL) belle_sip_object_unref(data);
}
template <class T>
ObjectBctbxListWrapper<T>::~ObjectBctbxListWrapper() {
mCList = bctbx_list_free_with_data(mCList, unrefData);
}
StringBctbxListWrapper::StringBctbxListWrapper(const std::list<std::string> &cppList): AbstractBctbxListWrapper() {
for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) {
char *buffer = (char *)malloc(it->length()+1);
strcpy(buffer, it->c_str());
mCList = bctbx_list_append(mCList, buffer);
}
}
StringBctbxListWrapper::~StringBctbxListWrapper() {
mCList = bctbx_list_free_with_data(mCList, free);
}
const std::string Object::sUserDataKey = "cppUserData";
Object::Object(::belle_sip_object_t *ptr, bool takeRef):
enable_shared_from_this<Object>(), mPrivPtr(ptr) {
if(takeRef) belle_sip_object_ref(mPrivPtr);
belle_sip_object_data_set(ptr, "cpp_object", this, NULL);
}
Object::~Object() {
if(mPrivPtr != NULL) {
belle_sip_object_data_set(mPrivPtr, "cpp_object", NULL, NULL);
belle_sip_object_unref(mPrivPtr);
}
}
void Object::unsetData(const std::string &key) {
map<string,void *> userData = getUserData();
map<string,void *>::iterator it = userData.find(key);
if (it != userData.end()) userData.erase(it);
}
bool Object::dataExists(const std::string &key) {
map<string,void *> userData = getUserData();
return userData.find(key) != userData.end();
}
::belle_sip_object_t *Object::sharedPtrToCPtr(const std::shared_ptr<const Object> &sharedPtr) {
if (sharedPtr == nullptr) return NULL;
else return sharedPtr->mPrivPtr;
}
std::string Object::cStringToCpp(const char *cstr) {
if (cstr == NULL) {
return std::string();
} else {
return std::string(cstr);
}
}
std::string Object::cStringToCpp(char *cstr) {
if (cstr == NULL) {
return std::string();
} else {
std::string cppStr = cstr;
bctbx_free(cstr);
return cppStr;
}
}
const char *Object::cppStringToC(const std::string &cppstr) {
if (cppstr.empty()) {
return NULL;
} else {
return cppstr.c_str();
}
}
list<string> Object::bctbxStringListToCppList(const ::bctbx_list_t *bctbxList) {
list<string> cppList;
for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) {
cppList.push_back(string((char *)it->data));
}
return cppList;
}
std::list<std::string> Object::cStringArrayToCppList(const char **cArray) {
list<string> cppList;
int i;
for(i=0; cArray[i]!=NULL; i++) {
cppList.push_back(cArray[i]);
}
return cppList;
}
static void deleteCppUserDataMap(std::map<std::string,void *> *userDataMap) {
delete userDataMap;
}
std::map<std::string,void *> &Object::getUserData() const {
map<string,void *> *userData = (map<string,void *> *)belle_sip_object_data_get(mPrivPtr, sUserDataKey.c_str());
if (userData == NULL) {
userData = new map<string,void *>();
belle_sip_object_data_set(mPrivPtr, sUserDataKey.c_str(), userData, (belle_sip_data_destroy)deleteCppUserDataMap);
}
return *userData;
}
std::string ListenableObject::sListenerDataName = "cpp_listener";
ListenableObject::ListenableObject(::belle_sip_object_t *ptr, bool takeRef): Object(ptr, takeRef) {
shared_ptr<Listener> *cppListener = (shared_ptr<Listener> *)belle_sip_object_data_get(mPrivPtr, sListenerDataName.c_str());
if (cppListener == NULL) {
cppListener = new shared_ptr<Listener>();
belle_sip_object_data_set(mPrivPtr, sListenerDataName.c_str(), cppListener, (belle_sip_data_destroy)deleteListenerPtr);
}
}
void ListenableObject::setListener(const std::shared_ptr<Listener> &listener) {
shared_ptr<Listener> &curListener = *(shared_ptr<Listener> *)belle_sip_object_data_get(mPrivPtr, sListenerDataName.c_str());
curListener = listener;
}
std::shared_ptr<Listener> & ListenableObject::getListenerFromObject(::belle_sip_object_t *object) {
return *(std::shared_ptr<Listener> *)belle_sip_object_data_get(object, sListenerDataName.c_str());
}
std::string MultiListenableObject::sListenerListName = "cpp_listeners";
MultiListenableObject::MultiListenableObject(::belle_sip_object_t *ptr, bool takeRef): Object(ptr, takeRef) {
if (ptr != NULL) {
list<shared_ptr<Listener> > *listeners = new list<shared_ptr<Listener> >;
belle_sip_object_data_set(ptr, sListenerListName.c_str(), listeners, (belle_sip_data_destroy)deleteListenerList);
}
}
MultiListenableObject::~MultiListenableObject() {
if (mPrivPtr != NULL) {
belle_sip_object_data_set(mPrivPtr, sListenerListName.c_str(), NULL, NULL);
}
}
void MultiListenableObject::addListener(const std::shared_ptr<Listener> &listener) {
std::list<std::shared_ptr<Listener> > &listeners = *(std::list<std::shared_ptr<Listener> > *)belle_sip_object_data_get(mPrivPtr, sListenerListName.c_str());
listeners.push_back(listener);
}
void MultiListenableObject::removeListener(const std::shared_ptr<Listener> &listener) {
std::list<std::shared_ptr<Listener> > &listeners = *(std::list<std::shared_ptr<Listener> > *)belle_sip_object_data_get(mPrivPtr, sListenerListName.c_str());
listeners.remove(listener);
}
#ifndef _LINPHONE_OBJECT_HH
#define _LINPHONE_OBJECT_HH
#include <memory>
#include <list>
#include <map>
#include <belle-sip/object.h>
#include <bctoolbox/list.h>
namespace linphone {
class Object;
class Listener;
class AbstractBctbxListWrapper {
public:
AbstractBctbxListWrapper(): mCList(NULL) {}
virtual ~AbstractBctbxListWrapper() {}
::bctbx_list_t *c_list() {return mCList;}
protected:
::bctbx_list_t *mCList;
};
template <class T>
class ObjectBctbxListWrapper: public AbstractBctbxListWrapper {
public:
ObjectBctbxListWrapper(const std::list<std::shared_ptr<T> > &cppList);
virtual ~ObjectBctbxListWrapper();
};
class StringBctbxListWrapper: public AbstractBctbxListWrapper {
public:
StringBctbxListWrapper(const std::list<std::string> &cppList);
virtual ~StringBctbxListWrapper();
};
class Object: public std::enable_shared_from_this<Object> {
public:
Object(::belle_sip_object_t *ptr, bool takeRef=true);
virtual ~Object();
public:
template <class T>
void setData(const std::string &key, T &data) {
std::map<std::string,void *> &userData = getUserData();
userData[key] = &data;
}
template <class T>
T &getData(const std::string &key) {
std::map<std::string,void *> &userData = getUserData();
void *ptr = userData[key];
if (ptr == NULL) {
throw std::out_of_range("unknown data key [" + key + "]");
} else {
return *(T *)ptr;
}
}
void unsetData(const std::string &key);
bool dataExists(const std::string &key);
public:
template <class T>
static std::shared_ptr<T> cPtrToSharedPtr(::belle_sip_object_t *ptr, bool takeRef=true) {
if (ptr == NULL) {
return nullptr;
} else {
T *cppPtr = (T *)belle_sip_object_data_get(ptr, "cpp_object");
if (cppPtr == NULL) {
return std::make_shared<T>(ptr, takeRef);
} else {
return std::static_pointer_cast<T,Object>(cppPtr->shared_from_this());
}
}
}
static ::belle_sip_object_t *sharedPtrToCPtr(const std::shared_ptr<const Object> &sharedPtr);
protected:
static std::string cStringToCpp(const char *cstr);
static std::string cStringToCpp(char *cstr);
static const char *cppStringToC(const std::string &cppstr);
template <class T>
static std::list<std::shared_ptr<T> > bctbxObjectListToCppList(const ::bctbx_list_t *bctbxList) {
std::list<std::shared_ptr<T> > cppList;
for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) {
std::shared_ptr<T> newObj = Object::cPtrToSharedPtr<T>((::belle_sip_object_t *)it->data);
cppList.push_back(newObj);
}
return cppList;
}
static std::list<std::string> bctbxStringListToCppList(const ::bctbx_list_t *bctbxList);
static std::list<std::string> cStringArrayToCppList(const char **cArray);
private:
std::map<std::string,void *> &getUserData() const;
template <class T> static void deleteSharedPtr(std::shared_ptr<T> *ptr) {if (ptr != NULL) delete ptr;}
static void deleteString(std::string *str) {if (str != NULL) delete str;}
protected:
::belle_sip_object_t *mPrivPtr;
private:
static const std::string sUserDataKey;
};
class Listener {
public:
Listener(): mCbs(NULL) {}
virtual ~Listener() {setCallbacks(NULL);}
public:
void setCallbacks(::belle_sip_object_t *cbs) {
if (mCbs != NULL) belle_sip_object_unref(mCbs);
if (cbs == NULL) mCbs = NULL;
else mCbs = belle_sip_object_ref(cbs);
}
belle_sip_object_t *getCallbacks() {return mCbs;}
private:
::belle_sip_object_t *mCbs;
};
class ListenableObject: public Object {
protected:
ListenableObject(::belle_sip_object_t *ptr, bool takeRef=true);
void setListener(const std::shared_ptr<Listener> &listener);
protected:
static std::shared_ptr<Listener> & getListenerFromObject(::belle_sip_object_t *object);
private:
static void deleteListenerPtr(std::shared_ptr<Listener> *ptr) {delete ptr;}
private:
static std::string sListenerDataName;
};
class MultiListenableObject: public Object {
friend class Factory;
protected:
MultiListenableObject(::belle_sip_object_t *ptr, bool takeRef=true);
virtual ~MultiListenableObject();
protected:
void addListener(const std::shared_ptr<Listener> &listener);
void removeListener(const std::shared_ptr<Listener> &listener);
private:
static void deleteListenerList(std::list<std::shared_ptr<Listener> > *listeners) {delete listeners;}
private:
static std::string sListenerListName;
};
};
#endif // _LINPHONE_OBJECT_HH
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment