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

Cpp wrapper: wrap listenable classes as multilistenable class only

parent f5911186
......@@ -94,28 +94,14 @@ namespace linphone {
{{/enums}}
{{#isNotListener}}
{{#isrefcountable}}
{{{className}}}(void *ptr, bool takeRef=true);
{{/isrefcountable}}
{{#isnotrefcountable}}
LINPHONECXX_PUBLIC {{{className}}}();
LINPHONECXX_PUBLIC {{{className}}}(const {{{className}}} &src);
{{{className}}}(const void *src);
LINPHONECXX_PUBLIC ~{{{className}}}();
LINPHONECXX_PUBLIC const void *c_struct() const {return mPrivPtr;}
{{/isnotrefcountable}}
LINPHONECXX_PUBLIC {{{privCClassName}}} *cPtr() {return ({{{privCClassName}}} *)mPrivPtr;}
{{/isNotListener}}
{{#ismonolistenable}}
LINPHONECXX_PUBLIC void setListener(const std::shared_ptr<{{{listenerClassName}}}> &listener);
{{/ismonolistenable}}
{{#ismultilistenable}}
LINPHONECXX_PUBLIC virtual ~{{{className}}}();
{{#islistenable}}
LINPHONECXX_PUBLIC void addListener(const std::shared_ptr<{{{listenerClassName}}}> &listener);
LINPHONECXX_PUBLIC void removeListener(const std::shared_ptr<{{{listenerClassName}}}> &listener);
{{/ismultilistenable}}
{{/islistenable}}
public:
{{#isVcard}}
......@@ -158,21 +144,10 @@ namespace linphone {
{{/staticMethods}}
{{#ismultilistenable}}
private:
static void *createCallbacks(void *userData);
{{/ismultilistenable}}
{{#ismultilistenable}}
private:
void *mCallbacks;
{{/ismultilistenable}}
{{#isnotrefcountable}}
{{#islistenable}}
private:
void *mPrivPtr;
{{/isnotrefcountable}}
void *createCallbacks() override;
{{/islistenable}}
};
{{/_class}}
......
......@@ -32,92 +32,43 @@ using namespace {{{namespace}}};
{{#wrapperCbs}}
static {{{returnType}}} {{{cbName}}}({{{declArgs}}}) {
{{#ismultilistenable}}
{{{cListenerName}}} *cbs = {{{currentCallbacksGetter}}}({{{firstArgName}}});
if (cbs) {
std::list<std::shared_ptr<Listener> > listeners = *(std::list<std::shared_ptr<Listener> > *){{{userDataGetter}}}(cbs);
auto &listeners = *static_cast<std::list<std::shared_ptr<Listener> > *>(belle_sip_object_data_get((::belle_sip_object_t *)cbs, MultiListenableObject::sListenerListName));
for(auto it=listeners.begin(); it!=listeners.end(); it++) {
std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(*it);
{{{cppMethodCallingLine}}};
}
}
{{/ismultilistenable}}
{{#ismonolistenable}}
std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(ListenableObject::getListenerFromObject((::belle_sip_object_t *){{{firstArgName}}}));
{{#hasReturnValue}}return {{/hasReturnValue}}{{{cppMethodCallingLine}}};
{{/ismonolistenable}}
}
{{/wrapperCbs}}
{{#isNotListener}}
{{#isrefcountable}}
{{{namespace}}}::{{{className}}}::{{{className}}}(void *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) {
{{#ismultilistenable}}
mCallbacks = ({{{cListenerName}}} *)createCallbacks(&getListeners());
{{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks);
{{/ismultilistenable}}
}
{{/isrefcountable}}
{{#isnotrefcountable}}
{{{namespace}}}::{{{className}}}::{{{className}}}() {
mPrivPtr = new {{{cClassName}}};
memset(mPrivPtr, 0, sizeof({{{cClassName}}}));
}
{{{namespace}}}::{{{className}}}::{{{className}}}(const {{{className}}} &src) {
mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src.mPrivPtr);
}
{{{namespace}}}::{{{className}}}::{{{className}}}(const void *src) {
mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src);
}
{{{namespace}}}::{{{className}}}::~{{{className}}}() {
delete ({{{cClassName}}} *)mPrivPtr;
}
{{/isnotrefcountable}}
{{/isNotListener}}
{{#ismonolistenable}}
void {{{namespace}}}::{{{className}}}::setListener(const std::shared_ptr<{{{listenerClassName}}}> & listener) {
{{{parentClassName}}}::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}}
{{{className}}}::~{{{className}}}() {
{{{callbacksRemover}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks);
belle_sip_object_unref(mCallbacks);
}
{{#islistenable}}
void {{{className}}}::addListener(const std::shared_ptr<{{{listenerClassName}}}> &listener) {
{{{parentClassName}}}::addListener(std::static_pointer_cast<Listener,{{{listenerClassName}}}>(listener));
MultiListenableObject::addListener(std::static_pointer_cast<Listener,{{{listenerClassName}}}>(listener));
}
void {{{className}}}::removeListener(const std::shared_ptr<{{{listenerClassName}}}> &listener) {
{{{parentClassName}}}::removeListener(std::static_pointer_cast<Listener,{{{listenerClassName}}}>(listener));
MultiListenableObject::removeListener(std::static_pointer_cast<Listener,{{{listenerClassName}}}>(listener));
}
void *{{{className}}}::createCallbacks(void *userData) {
void *{{{className}}}::createCallbacks() {
{{{cListenerName}}} *cbs = {{{listenerCreator}}}(linphone_factory_get());
{{#wrapperCbs}}
{{{callbackSetter}}}(cbs, {{{cbName}}});
{{/wrapperCbs}}
{{{userDataSetter}}}(cbs, userData);
belle_sip_object_data_set((::belle_sip_object_t *)(cbs), MultiListenableObject::sListenerListName, new list<shared_ptr<Listener>>(), (::belle_sip_data_destroy)deleteListenerList);
belle_sip_object_data_set((::belle_sip_object_t *)(mPrivPtr), MultiListenableObject::sCbsPtrName, cbs, nullptr);
{{{callbacksAdder}}}(static_cast<{{{cClassName}}} *>(mPrivPtr), cbs);
belle_sip_object_unref((::belle_sip_object_t *)cbs);
return cbs;
}
{{/ismultilistenable}}
{{/islistenable}}
{{#isVcard}}
std::shared_ptr<belcard::BelCard> &Vcard::getVcard() {
......
......@@ -67,16 +67,10 @@ class CppTranslator(object):
def translate_class(self, _class):
islistenable = _class.listenerInterface is not None
ismonolistenable = (islistenable and _class.singlelistener)
ismultilistenable = (islistenable and _class.multilistener)
classDict = {
'islistenable' : islistenable,
'isnotlistenable' : not islistenable,
'ismonolistenable' : ismonolistenable,
'ismultilistenable' : ismultilistenable,
'isrefcountable' : _class.refcountable,
'isnotrefcountable' : not _class.refcountable,
'isNotListener' : True,
'isListener' : False,
'isVcard' : (_class.name.to_c() == 'LinphoneVcard'),
......@@ -106,15 +100,7 @@ class CppTranslator(object):
classDict['cppListenerName'] = _class.listenerInterface.name.translate(self.nameTranslator)
for method in _class.listenerInterface.instanceMethods:
classDict['wrapperCbs'].append(self._generate_wrapper_callback(_class, method))
if ismonolistenable:
classDict['cCbsGetter'] = _class.name.to_snake_case(fullName=True) + '_get_callbacks'
classDict['parentClassName'] = 'ListenableObject'
if ismultilistenable:
if ismonolistenable:
classDict['parentClassName'] = 'DualListenableObject'
else:
classDict['parentClassName'] = 'MultiListenableObject'
classDict['parentClassName'] = 'MultiListenableObject'
classDict['listenerCreator'] = 'linphone_factory_create_' + _class.listenerInterface.name.to_snake_case()[:-len('_listener')] + '_cbs'
classDict['callbacksAdder'] = _class.name.to_snake_case(fullName=True)+ '_add_callbacks'
classDict['callbacksRemover'] = _class.name.to_snake_case(fullName=True)+ '_remove_callbacks'
......
......@@ -104,68 +104,25 @@ std::shared_ptr<Listener> & ListenableObject::getListenerFromObject(void *object
}
std::string MultiListenableObject::sListenerListName = "cpp_listeners";
MultiListenableObject::MultiListenableObject(void *ptr, bool takeRef): Object(ptr, takeRef) {
if (ptr != NULL) {
if (belle_sip_object_data_get((::belle_sip_object_t *)ptr, sListenerListName.c_str()) == NULL) {
list<shared_ptr<Listener> > *listeners = new list<shared_ptr<Listener> >;
belle_sip_object_data_set((::belle_sip_object_t *)ptr, sListenerListName.c_str(), listeners, (belle_sip_data_destroy)deleteListenerList);
}
}
}
const char *MultiListenableObject::sListenerListName = "cpp_listeners";
const char *MultiListenableObject::sCbsPtrName = "cpp_callbacks";
MultiListenableObject::MultiListenableObject(void *ptr, bool takeRef): Object(ptr, takeRef) {}
std::list<std::shared_ptr<Listener> > &MultiListenableObject::getListeners() const {
return *(std::list<std::shared_ptr<Listener> > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
return *(std::list<std::shared_ptr<Listener> > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName);
}
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((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
listeners.push_back(listener);
auto *cbs = static_cast<::belle_sip_object_t *>(belle_sip_object_data_get(static_cast<::belle_sip_object_t *>(mPrivPtr), sCbsPtrName));
if (cbs == nullptr) cbs = static_cast<::belle_sip_object_t *>(createCallbacks());
auto *listeners = static_cast<list<shared_ptr<Listener>> *>(belle_sip_object_data_get(cbs, sListenerListName));
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((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
listeners.remove(listener);
}
std::string DualListenableObject::sListenerDataName = "cpp_listener";
std::string DualListenableObject::sListenerListName = "cpp_listeners";
DualListenableObject::DualListenableObject(void *ptr, bool takeRef): Object(ptr, takeRef) {
shared_ptr<Listener> *cppListener = (shared_ptr<Listener> *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str());
if (cppListener == NULL) {
cppListener = new shared_ptr<Listener>();
belle_sip_object_data_set((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str(), cppListener, (belle_sip_data_destroy)deleteListenerPtr);
}
if (ptr != NULL) {
if (belle_sip_object_data_get((::belle_sip_object_t *)ptr, sListenerListName.c_str()) == NULL) {
list<shared_ptr<Listener> > *listeners = new list<shared_ptr<Listener> >;
belle_sip_object_data_set((::belle_sip_object_t *)ptr, sListenerListName.c_str(), listeners, (belle_sip_data_destroy)deleteListenerList);
}
}
}
void DualListenableObject::setListener(const std::shared_ptr<Listener> &listener) {
shared_ptr<Listener> &curListener = *(shared_ptr<Listener> *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str());
curListener = listener;
auto *cbs = static_cast<::belle_sip_object_t *>(belle_sip_object_data_get(static_cast<::belle_sip_object_t *>(mPrivPtr), sCbsPtrName));
if (cbs == nullptr) return;
auto *listeners = static_cast<list<shared_ptr<Listener>> *>(belle_sip_object_data_get(cbs, sListenerListName));
listeners->remove(listener);
}
std::shared_ptr<Listener> & DualListenableObject::getListenerFromObject(void *object) {
return *(std::shared_ptr<Listener> *)belle_sip_object_data_get((::belle_sip_object_t *)object, sListenerDataName.c_str());
}
std::list<std::shared_ptr<Listener> > &DualListenableObject::getListeners() const {
return *(std::list<std::shared_ptr<Listener> > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
}
void DualListenableObject::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((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
listeners.push_back(listener);
}
void DualListenableObject::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((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str());
listeners.remove(listener);
}
......@@ -130,48 +130,25 @@ namespace linphone {
};
class MultiListenableObject: public Object {
friend class Factory;
public:
static const char *sListenerListName;
static const char *sCbsPtrName;
protected:
MultiListenableObject(void *ptr, bool takeRef=true);
virtual ~MultiListenableObject() {};
virtual ~MultiListenableObject() = default;
protected:
void addListener(const std::shared_ptr<Listener> &listener);
void removeListener(const std::shared_ptr<Listener> &listener);
std::list<std::shared_ptr<Listener> > &getListeners() const;
private:
static void deleteListenerList(std::list<std::shared_ptr<Listener> > *listeners) {delete listeners;}
private:
static std::string sListenerListName;
};
class DualListenableObject: public Object {
friend class Factory;
virtual void *createCallbacks() = 0;
public:
static std::shared_ptr<Listener> & getListenerFromObject(void *object);
protected:
DualListenableObject(void *ptr, bool takeRef=true);
void setListener(const std::shared_ptr<Listener> &listener);
virtual ~DualListenableObject() {};
protected:
void addListener(const std::shared_ptr<Listener> &listener);
void removeListener(const std::shared_ptr<Listener> &listener);
std::list<std::shared_ptr<Listener> > &getListeners() const;
private:
static void deleteListenerPtr(std::shared_ptr<Listener> *ptr) {delete ptr;}
static void deleteListenerList(std::list<std::shared_ptr<Listener> > *listeners) {delete listeners;}
private:
static std::string sListenerDataName;
static std::string sListenerListName;
friend class Factory;
};
};
#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