mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Handle C back pointer in C++ objects.
This commit is contained in:
parent
8127798358
commit
f8f072fb3d
5 changed files with 65 additions and 7 deletions
|
|
@ -22,6 +22,8 @@
|
|||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "variant/variant.h"
|
||||
|
||||
// From coreapi.
|
||||
#include "private.h"
|
||||
|
||||
|
|
@ -97,18 +99,21 @@ public:
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void setCppPtrFromC (void *object, std::shared_ptr<T> &cppPtr) {
|
||||
static inline void setCppPtrFromC (void *object, const std::shared_ptr<T> &cppPtr) {
|
||||
L_ASSERT(object);
|
||||
static_cast<WrappedObject<T> *>(object)->cppPtr = cppPtr;
|
||||
cppPtr->setProperty("LinphonePrivate::Wrapper::cBackPtr", object);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void setCppPtrFromC (void *object, T *cppPtr) {
|
||||
static inline void setCppPtrFromC (void *object, const T *cppPtr) {
|
||||
L_ASSERT(object);
|
||||
T *tPtr = reinterpret_cast<T *>(static_cast<WrappedClonableObject<T> *>(object)->cppPtr);
|
||||
if (tPtr != cppPtr) {
|
||||
delete tPtr;
|
||||
static_cast<WrappedClonableObject<T> *>(object)->cppPtr = new T(*cppPtr);
|
||||
T *oldPtr = reinterpret_cast<T *>(static_cast<WrappedClonableObject<T> *>(object)->cppPtr);
|
||||
if (oldPtr != cppPtr) {
|
||||
delete oldPtr;
|
||||
T *cppObject = static_cast<WrappedClonableObject<T> *>(object)->cppPtr;
|
||||
cppObject = new T(*cppPtr);
|
||||
cppObject->setProperty("LinphonePrivate::Wrapper::cBackPtr", object);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +127,28 @@ public:
|
|||
return cppPtr;
|
||||
}
|
||||
|
||||
template<typename CType, typename CppType>
|
||||
static inline CType * getCBackPtr (const std::shared_ptr<CppType> &object, CType *(*cTypeAllocator)()) {
|
||||
Variant v = object->getProperty("LinphonePrivate::Wrapper::cBackPtr");
|
||||
void *value = v.getValue<void *>();
|
||||
if (!value) {
|
||||
CType *cObject = cTypeAllocator();
|
||||
setCppPtrFromC(cObject, object);
|
||||
}
|
||||
return reinterpret_cast<CType *>(value);
|
||||
}
|
||||
|
||||
template<typename CType, typename CppType>
|
||||
static inline CType * getCBackPtr (const CppType *object, CType *(*cTypeAllocator)()) {
|
||||
Variant v = object->getProperty("LinphonePrivate::Wrapper::cBackPtr");
|
||||
void *value = v.getValue<void *>();
|
||||
if (!value) {
|
||||
CType *cObject = cTypeAllocator();
|
||||
setCppPtrFromC(cObject, object);
|
||||
}
|
||||
return reinterpret_cast<CType *>(value);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -235,6 +262,9 @@ LINPHONE_END_NAMESPACE
|
|||
L_GET_CPP_PTR_FROM_C_STRUCT(OBJECT, CPP_TYPE, C_TYPE) \
|
||||
))
|
||||
|
||||
#define L_GET_C_BACK_PTR(OBJECT, C_TYPE, C_NAME) \
|
||||
LINPHONE_NAMESPACE::Wrapper::getCBackPtr<Linphone ## C_TYPE>(OBJECT, _linphone_ ## C_NAME ## _init)
|
||||
|
||||
#define L_GET_C_LIST_FROM_CPP_LIST(LIST, TYPE) \
|
||||
LINPHONE_NAMESPACE::Wrapper::getCListFromCppList<TYPE *>(LIST)
|
||||
#define L_GET_CPP_LIST_FROM_C_LIST(LIST, TYPE) \
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "linphone/utils/general.h"
|
||||
|
||||
#include "variant/variant.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
|
@ -41,6 +43,8 @@ private:
|
|||
|
||||
int nRefs = 0;
|
||||
|
||||
std::unordered_map<std::string, Variant> properties;
|
||||
|
||||
L_DECLARE_PUBLIC(ClonableObject);
|
||||
|
||||
// It's forbidden to copy directly one Clonable object private.
|
||||
|
|
|
|||
|
|
@ -82,4 +82,20 @@ void ClonableObject::setRef (const ClonableObjectPrivate &p) {
|
|||
mPrivate->ref();
|
||||
}
|
||||
|
||||
Variant ClonableObject::getProperty (const string &name) const {
|
||||
L_D(const ClonableObject);
|
||||
auto it = d->properties.find(name);
|
||||
return it == d->properties.cend() ? Variant() : it->second;
|
||||
}
|
||||
|
||||
void ClonableObject::setProperty (const string &name, const Variant &value) {
|
||||
L_D(ClonableObject);
|
||||
d->properties[name] = value;
|
||||
}
|
||||
|
||||
void ClonableObject::setProperty (const string &name, Variant &&value) {
|
||||
L_D(ClonableObject);
|
||||
d->properties[name] = move(value);
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -19,16 +19,24 @@
|
|||
#ifndef _CLONABLE_OBJECT_H_
|
||||
#define _CLONABLE_OBJECT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "linphone/utils/general.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class Variant;
|
||||
|
||||
class LINPHONE_PUBLIC ClonableObject {
|
||||
public:
|
||||
virtual ~ClonableObject ();
|
||||
|
||||
Variant getProperty (const std::string &name) const;
|
||||
void setProperty (const std::string &name, const Variant &value);
|
||||
void setProperty (const std::string &name, Variant &&value);
|
||||
|
||||
protected:
|
||||
// Use a new ClonableObjectPrivate without owner.
|
||||
explicit ClonableObject (ClonableObjectPrivate &p);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public:
|
|||
|
||||
template<typename T, typename = typename std::enable_if<std::is_same<T, void *>::value> >
|
||||
// void* constructor. Must be explicitly called.
|
||||
Variant (T value);
|
||||
Variant (T value) {}
|
||||
|
||||
~Variant ();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue