Commit f8f072fb authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Handle C back pointer in C++ objects.

parent 81277983
......@@ -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 ();
......
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