Commit ef62012c authored by Ronan's avatar Ronan

feat(Object): avoid usage of share_from_this

parent 2ff88e79
......@@ -103,7 +103,7 @@ class ObjectPrivate;
#endif
template<typename T>
inline ClonableObject *getPublicHelper (T *object, ClonableObjectPrivate *context) {
inline ClonableObject *getPublicHelper (T *object, const ClonableObjectPrivate *context) {
auto it = object->find(context);
L_ASSERT(it != object->end());
return it->second;
......@@ -117,7 +117,7 @@ inline const ClonableObject *getPublicHelper (const T *object, const ClonableObj
}
template<typename T>
inline Object *getPublicHelper (T *object, ObjectPrivate *) {
inline Object *getPublicHelper (T *object, const ObjectPrivate *) {
return object;
}
......@@ -127,7 +127,7 @@ inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) {
}
#define L_DECLARE_PUBLIC(CLASS) \
inline CLASS * getPublic () { \
inline CLASS *getPublic () { \
return static_cast<CLASS *>(getPublicHelper(mPublic, this)); \
} \
inline const CLASS *getPublic () const { \
......@@ -142,6 +142,14 @@ inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) {
#define L_D() decltype(std::declval<decltype(*this)>().getPrivate()) const d = getPrivate();
#define L_Q() decltype(std::declval<decltype(*this)>().getPublic()) const q = getPublic();
#define L_OVERRIDE_SHARED_FROM_THIS(CLASS) \
inline std::shared_ptr<CLASS> getSharedFromThis () { \
return std::static_pointer_cast<CLASS>(Object::getSharedFromThis()); \
} \
inline std::shared_ptr<const CLASS> getSharedFromThis () const { \
return std::static_pointer_cast<const CLASS>(Object::getSharedFromThis()); \
}
#define L_USE_DEFAULT_SHARE_IMPL(CLASS, PARENT_CLASS) \
CLASS::CLASS (const CLASS &src) : PARENT_CLASS(*src.getPrivate()) {} \
CLASS &CLASS::operator= (const CLASS &src) { \
......
......@@ -1139,7 +1139,7 @@ void linphone_call_set_user_data (LinphoneCall *call, void *ud) {
LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg) {
LinphoneCall *call = L_INIT(Call);
L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared<LinphonePrivate::Call>(call, lc, LinphoneCallOutgoing,
L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create<LinphonePrivate::Call>(call, lc, LinphoneCallOutgoing,
*L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to),
cfg, nullptr, L_GET_CPP_PTR_FROM_C_OBJECT(params)));
call->currentParamsCache = linphone_call_params_new_for_wrapper();
......@@ -1151,7 +1151,7 @@ LinphoneCall *linphone_call_new_outgoing (LinphoneCore *lc, const LinphoneAddres
LinphoneCall *linphone_call_new_incoming (LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op) {
LinphoneCall *call = L_INIT(Call);
L_SET_CPP_PTR_FROM_C_OBJECT(call, make_shared<LinphonePrivate::Call>(call, lc, LinphoneCallIncoming,
L_SET_CPP_PTR_FROM_C_OBJECT(call, LinphonePrivate::ObjectFactory::create<LinphonePrivate::Call>(call, lc, LinphoneCallIncoming,
*L_GET_CPP_PTR_FROM_C_OBJECT(from), *L_GET_CPP_PTR_FROM_C_OBJECT(to),
nullptr, op, nullptr));
call->currentParamsCache = linphone_call_params_new_for_wrapper();
......
......@@ -289,9 +289,9 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
LinphoneChatRoom *linphone_chat_room_new (LinphoneCore *core, const LinphoneAddress *addr) {
LinphoneChatRoom *cr = L_INIT(ChatRoom);
if (linphone_core_realtime_text_enabled(core))
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::RealTimeTextChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create<LinphonePrivate::RealTimeTextChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
else
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::BasicChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create<LinphonePrivate::BasicChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Created);
return cr;
......@@ -311,7 +311,7 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons
from = linphone_core_get_primary_contact(core);
LinphonePrivate::Address me(from);
LinphoneChatRoom *cr = L_INIT(ChatRoom);
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ClientGroupChatRoom>(core, me, L_C_TO_STRING(subject)));
L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create<LinphonePrivate::ClientGroupChatRoom>(core, me, L_C_TO_STRING(subject)));
L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
return cr;
}
......
......@@ -294,7 +294,7 @@ public:
return nullptr;
try {
return getCBackPtr(std::static_pointer_cast<CppType>(cppObject->shared_from_this()));
return getCBackPtr(std::static_pointer_cast<CppType>(cppObject->getSharedFromThis()));
} catch (const std::bad_weak_ptr &e) {
abort(e.what());
}
......@@ -545,13 +545,6 @@ LINPHONE_END_NAMESPACE
FALSE \
);
#define L_DECLARE_C_OBJECT_NEW_DEFAULT(C_TYPE, C_NAME) \
Linphone ## C_TYPE * linphone_ ## C_NAME ## _new() { \
Linphone ## C_TYPE *object = _linphone_ ## C_TYPE ## _init(); \
object->cppPtr = std::make_shared<LinphonePrivate::C_TYPE>(); \
return object; \
}
// -----------------------------------------------------------------------------
// Helpers.
// -----------------------------------------------------------------------------
......
......@@ -60,7 +60,7 @@ int BasicChatRoom::getNbParticipants () const {
list<shared_ptr<Participant>> BasicChatRoom::getParticipants () const {
L_D();
list<shared_ptr<Participant>> l;
l.push_back(make_shared<Participant>(d->peerAddress));
l.push_back(ObjectFactory::create<Participant>(d->peerAddress));
return l;
}
......
......@@ -37,20 +37,20 @@ public:
virtual ~ChatMessagePrivate ();
void setChatRoom (std::shared_ptr<ChatRoom> chatRoom);
// -----------------------------------------------------------------------------
void setDirection (ChatMessage::Direction dir);
void setState(ChatMessage::State state);
void setTime(time_t time);
void setIsReadOnly(bool readOnly);
unsigned int getStorageId() const;
void setStorageId(unsigned int id);
belle_http_request_t *getHttpRequest() const;
void setHttpRequest(belle_http_request_t *request);
......@@ -67,16 +67,16 @@ public:
// -----------------------------------------------------------------------------
// Methods only used for C wrapper
// -----------------------------------------------------------------------------
const std::string& getContentType();
void setContentType(const std::string& contentType);
const std::string& getText();
void setText(const std::string& text);
LinphoneContent * getFileTransferInformation() const;
void setFileTransferInformation(LinphoneContent *content);
// -----------------------------------------------------------------------------
// Need to be public to be called from static C callbacks
// -----------------------------------------------------------------------------
......@@ -94,11 +94,11 @@ public:
void processAuthRequestedUpload(const belle_sip_auth_event *event);
void processIoErrorDownload(const belle_sip_io_error_event_t *event);
void processResponseFromGetFile(const belle_http_response_event_t *event);
// -----------------------------------------------------------------------------
void sendImdn(ImdnType imdnType, LinphoneReason reason);
LinphoneReason receive();
void send();
......@@ -133,7 +133,7 @@ private:
std::string cText = "";
// Used for compatibility with previous C API
LinphoneContent *cFileTransferInformation = NULL;
// -----------------------------------------------------------------------------
std::string createImdnXml(ImdnType imdnType, LinphoneReason reason);
......@@ -145,10 +145,6 @@ private:
void releaseHttpRequest();
void createFileTransferInformationsFromVndGsmaRcsFtHttpXml();
std::shared_ptr<ChatMessage> getPublicSharedPtr();
// -----------------------------------------------------------------------------
L_DECLARE_PUBLIC(ChatMessage);
};
......
......@@ -55,11 +55,6 @@ ChatMessagePrivate::~ChatMessagePrivate () {}
// -----------------------------------------------------------------------------
shared_ptr<ChatMessage> ChatMessagePrivate::getPublicSharedPtr() {
L_Q();
return q->getSharedPtr();
}
void ChatMessagePrivate::setChatRoom (shared_ptr<ChatRoom> cr) {
chatRoom = cr;
}
......@@ -607,7 +602,7 @@ void ChatMessagePrivate::processResponseFromPostFile(const belle_http_response_e
_chat_message_file_transfer_on_progress, NULL, NULL,
_chat_message_on_send_body, _chat_message_on_send_end, this);
if (!fileTransferFilePath.empty()) {
belle_sip_user_body_handler_t *body_handler = (belle_sip_user_body_handler_t *)first_part_bh;
belle_sip_user_body_handler_t *body_handler = (belle_sip_user_body_handler_t *)first_part_bh;
// No need to add again the callback for progression, otherwise it will be called twice
first_part_bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(fileTransferFilePath.c_str(), NULL, this);
linphone_content_set_size(cFileTransferInformation, belle_sip_file_body_handler_get_file_size((belle_sip_file_body_handler_t *)first_part_bh));
......@@ -765,8 +760,8 @@ void ChatMessagePrivate::processResponseHeadersFromGetFile(const belle_http_resp
body_size = linphone_content_get_size(cFileTransferInformation);
}
body_handler = (belle_sip_body_handler_t *)belle_sip_user_body_handler_new(body_size, _chat_message_file_transfer_on_progress,
NULL, _chat_message_on_recv_body,
body_handler = (belle_sip_body_handler_t *)belle_sip_user_body_handler_new(body_size, _chat_message_file_transfer_on_progress,
NULL, _chat_message_on_recv_body,
NULL, _chat_message_on_recv_end, this);
if (!fileTransferFilePath.empty()) {
belle_sip_user_body_handler_t *bh = (belle_sip_user_body_handler_t *)body_handler;
......@@ -805,7 +800,7 @@ void ChatMessagePrivate::processIoErrorUpload(const belle_sip_io_error_event_t *
lError() << "I/O Error during file upload of msg [" << this << "]";
q->updateState(ChatMessage::State::NotDelivered);
releaseHttpRequest();
chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr());
chatRoom->getPrivate()->removeTransientMessage(q->getSharedFromThis());
}
static void _chat_message_process_auth_requested_upload(void *data, belle_sip_auth_event *event) {
......@@ -818,7 +813,7 @@ void ChatMessagePrivate::processAuthRequestedUpload(const belle_sip_auth_event *
lError() << "Error during file upload: auth requested for msg [" << this << "]";
q->updateState(ChatMessage::State::NotDelivered);
releaseHttpRequest();
chatRoom->getPrivate()->removeTransientMessage(q->getSharedPtr());
chatRoom->getPrivate()->removeTransientMessage(q->getSharedFromThis());
}
static void _chat_message_process_io_error_download(void *data, const belle_sip_io_error_event_t *event) {
......@@ -983,7 +978,7 @@ LinphoneReason ChatMessagePrivate::receive() {
LinphoneReason reason = LinphoneReasonNone;
bool store = false;
// ---------------------------------------
// Start of message modification
// ---------------------------------------
......@@ -998,7 +993,7 @@ LinphoneReason ChatMessagePrivate::receive() {
retval = ecmm.decode(this);
if (retval > 0) {
/* Unable to decrypt message */
chatRoom->getPrivate()->notifyUndecryptableMessageReceived(getPublicSharedPtr());
chatRoom->getPrivate()->notifyUndecryptableMessageReceived(q->getSharedFromThis());
reason = linphone_error_code_to_reason(retval);
q->sendDeliveryNotification(reason);
return reason;
......@@ -1006,7 +1001,7 @@ LinphoneReason ChatMessagePrivate::receive() {
MultipartChatMessageModifier mcmm;
mcmm.decode(this);
// ---------------------------------------
// End of message modification
// ---------------------------------------
......@@ -1040,7 +1035,7 @@ void ChatMessagePrivate::send() {
L_Q();
SalOp *op = salOp;
LinphoneCall *call = NULL;
if (lp_config_get_int(chatRoom->getCore()->config, "sip", "chat_use_call_dialogs", 0) != 0) {
call = linphone_core_get_call_by_remote_address(chatRoom->getCore(), chatRoom->getPeerAddress().asString().c_str());
if (call) {
......@@ -1076,7 +1071,7 @@ void ChatMessagePrivate::send() {
op->set_user_pointer(L_GET_C_BACK_PTR(q)); /* If out of call, directly store msg */
linphone_address_unref(peer);
}
// ---------------------------------------
// Start of message modification
// ---------------------------------------
......@@ -1090,7 +1085,7 @@ void ChatMessagePrivate::send() {
if (!getContentType().empty()) {
clearTextContentType = getContentType();
}
if (contents.size() > 1) {
MultipartChatMessageModifier mcmm;
mcmm.encode(this);
......@@ -1098,7 +1093,6 @@ void ChatMessagePrivate::send() {
EncryptionChatMessageModifier ecmm;
int retval = ecmm.encode(this);
if (retval > 0) {
sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", nullptr);
q->updateState(ChatMessage::State::NotDelivered);
......@@ -1110,7 +1104,7 @@ void ChatMessagePrivate::send() {
CpimChatMessageModifier ccmm;
ccmm.encode(this);
}
// ---------------------------------------
// End of message modification
// ---------------------------------------
......@@ -1144,7 +1138,7 @@ void ChatMessagePrivate::send() {
/* Might be better fixed by delivering status, but too costly for now */
return;
}
/* If operation failed, we should not change message state */
if (q->isOutgoing()) {
setIsReadOnly(true);
......@@ -1379,9 +1373,8 @@ void ChatMessage::updateState(State state) {
d->setState(state);
linphone_chat_message_store_state(L_GET_C_BACK_PTR(this));
if (state == Delivered || state == NotDelivered) {
d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(static_pointer_cast<ChatMessage>(shared_from_this()));
}
if (state == Delivered || state == NotDelivered)
d->chatRoom->getPrivate()->moveTransientMessageToWeakMessages(getSharedFromThis());
}
void ChatMessage::reSend() {
......@@ -1392,7 +1385,7 @@ void ChatMessage::reSend() {
return;
}
d->chatRoom->sendMessage(static_pointer_cast<ChatMessage>(shared_from_this()));
d->chatRoom->sendMessage(getSharedFromThis());
}
void ChatMessage::sendDeliveryNotification(LinphoneReason reason) {
......@@ -1512,8 +1505,4 @@ int ChatMessage::putCharacter(uint32_t character) {
return -1;
}
shared_ptr<ChatMessage> ChatMessage::getSharedPtr() {
return static_pointer_cast<ChatMessage>(shared_from_this());
}
LINPHONE_END_NAMESPACE
......@@ -44,12 +44,14 @@ class LINPHONE_PUBLIC ChatMessage : public Object {
friend class ChatRoomPrivate;
friend class RealTimeTextChatRoomPrivate;
public:
public:
L_OVERRIDE_SHARED_FROM_THIS(ChatMessage);
enum Direction {
Incoming,
Outgoing
};
enum State {
Idle,
InProgress,
......@@ -100,22 +102,22 @@ public:
const std::string& getExternalBodyUrl() const;
void setExternalBodyUrl(const std::string &url);
time_t getTime() const;
bool isSecured() const;
void setIsSecured(bool isSecured);
State getState() const;
const std::string& getId() const;
void setId(const std::string&);
bool isRead() const;
const std::string& getAppdata() const;
void setAppdata(const std::string &appData);
const Address& getFromAddress() const;
void setFromAddress(Address from);
void setFromAddress(const std::string& from);
......@@ -131,9 +133,9 @@ public:
void setIsToBeStored(bool store);
const LinphoneErrorInfo * getErrorInfo() const;
bool isReadOnly() const;
std::list<std::shared_ptr<const Content> > getContents() const;
void addContent(const std::shared_ptr<Content> &content);
void removeContent(const std::shared_ptr<const Content> &content);
......@@ -143,7 +145,6 @@ public:
void removeCustomHeader(const std::string &headerName);
protected:
std::shared_ptr<ChatMessage> getSharedPtr();
explicit ChatMessage(ChatMessagePrivate &p);
private:
......
......@@ -211,7 +211,7 @@ void ChatRoomPrivate::sendIsComposingNotification () {
shared_ptr<ChatMessage> msg = q->createMessage();
msg->setFromAddress(identity);
msg->setToAddress(peerAddress.asString());
shared_ptr<Content> content = make_shared<Content>();
content->setContentType("application/im-iscomposing+xml");
content->setBody(payload);
......@@ -277,7 +277,7 @@ int ChatRoomPrivate::createChatMessageFromDb (int argc, char **argv, char **colN
}
if (argv[13]) {
content->setContentType(argv[13]);
}
}
Address peer(peerAddress.asString());
if (atoi(argv[3]) == ChatMessage::Direction::Incoming) {
......@@ -555,7 +555,6 @@ shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (const LinphoneConte
chatMessage->setToAddress(d->peerAddress);
chatMessage->setFromAddress(linphone_core_get_identity(d->core));
chatMessage->getPrivate()->setDirection(ChatMessage::Direction::Outgoing);
chatMessage->getPrivate()->setFileTransferInformation(linphone_content_copy(initialContent));
......@@ -578,7 +577,7 @@ shared_ptr<ChatMessage> ChatRoom::createMessage (const string &message) {
}
shared_ptr<ChatMessage> ChatRoom::createMessage () {
shared_ptr<ChatMessage> chatMessage = make_shared<ChatMessage>(static_pointer_cast<ChatRoom>(shared_from_this()));
shared_ptr<ChatMessage> chatMessage = ObjectFactory::create<ChatMessage>(getSharedFromThis());
chatMessage->getPrivate()->setTime(ms_time(0));
return chatMessage;
}
......@@ -742,7 +741,7 @@ void ChatRoom::sendMessage (shared_ptr<ChatMessage> msg) {
d->addTransientMessage(msg);
/* Store the message so that even if the upload is stopped, it can be done again */
d->storeOrUpdateMessage(msg);
msg->getPrivate()->setState(ChatMessage::State::InProgress);
} else {
return;
......
......@@ -44,6 +44,7 @@ class LINPHONE_PUBLIC ChatRoom : public Object, public ConferenceInterface {
public:
L_DECLARE_ENUM(State, L_ENUM_VALUES_CHAT_ROOM_STATE);
L_OVERRIDE_SHARED_FROM_THIS(ChatRoom);
ChatRoom (LinphoneCore *core);
virtual ~ChatRoom () = default;
......
......@@ -40,7 +40,7 @@ int EncryptionChatMessageModifier::encode (ChatMessagePrivate *messagePrivate) {
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsOutgoingMessageCb cbProcessOutgoingMessage = linphone_im_encryption_engine_cbs_get_process_outgoing_message(imeeCbs);
if (cbProcessOutgoingMessage) {
retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublicSharedPtr()));
retval = cbProcessOutgoingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis()));
if (retval == 0) {
messagePrivate->isSecured = true;
}
......@@ -56,7 +56,7 @@ int EncryptionChatMessageModifier::decode (ChatMessagePrivate *messagePrivate) {
LinphoneImEncryptionEngineCbs *imeeCbs = linphone_im_encryption_engine_get_callbacks(imee);
LinphoneImEncryptionEngineCbsIncomingMessageCb cbProcessIncomingMessage = linphone_im_encryption_engine_cbs_get_process_incoming_message(imeeCbs);
if (cbProcessIncomingMessage) {
retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublicSharedPtr()));
retval = cbProcessIncomingMessage(imee, L_GET_C_BACK_PTR(messagePrivate->chatRoom), L_GET_C_BACK_PTR(messagePrivate->getPublic()->getSharedFromThis()));
if (retval == 0) {
messagePrivate->isSecured = true;
}
......
......@@ -156,7 +156,7 @@ int RealTimeTextChatRoom::getNbParticipants () const {
list<shared_ptr<Participant>> RealTimeTextChatRoom::getParticipants () const {
L_D();
list<shared_ptr<Participant>> l;
l.push_back(make_shared<Participant>(d->peerAddress));
l.push_back(ObjectFactory::create<Participant>(d->peerAddress));
return l;
}
......
......@@ -29,7 +29,7 @@ LINPHONE_BEGIN_NAMESPACE
Conference::Conference (LinphoneCore *core, const Address &myAddress, CallListener *listener)
: core(core), callListener(listener) {
me = make_shared<Participant>(myAddress);
me = ObjectFactory::create<Participant>(myAddress);
}
// -----------------------------------------------------------------------------
......
......@@ -42,7 +42,7 @@ shared_ptr<Participant> LocalConference::addParticipant (const Address &addr, co
shared_ptr<Participant> participant = findParticipant(addr);
if (participant)
return participant;
participant = make_shared<Participant>(addr);
participant = ObjectFactory::create<Participant>(addr);
participant->getPrivate()->createSession(*this, params, hasMedia, this);
participants.push_back(participant);
if (!activeParticipant)
......
......@@ -29,11 +29,13 @@ LINPHONE_BEGIN_NAMESPACE
// =============================================================================
shared_ptr<CallSession> ParticipantPrivate::createSession (const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener) {
shared_ptr<CallSession> ParticipantPrivate::createSession (
const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener
) {
if (hasMedia && (!params || dynamic_cast<const MediaSessionParams *>(params))) {
session = make_shared<MediaSession>(conference, params, listener);
session = ObjectFactory::create<MediaSession>(conference, params, listener);
} else {
session = make_shared<CallSession>(conference, params, listener);
session = ObjectFactory::create<CallSession>(conference, params, listener);
}
return session;
}
......
......@@ -43,7 +43,7 @@ shared_ptr<Participant> RemoteConference::addParticipant (const Address &addr, c
shared_ptr<Participant> participant = findParticipant(addr);
if (participant)
return participant;
participant = make_shared<Participant>(addr);
participant = ObjectFactory::create<Participant>(addr);
participant->getPrivate()->createSession(*this, params, hasMedia, this);
participants.push_back(participant);
if (!activeParticipant)
......
......@@ -839,7 +839,7 @@ void CallSession::startIncomingNotification () {
if (d->listener)
d->listener->onCallSessionAccepted(*this);
/* Prevent the CallSession from being destroyed while we are notifying, if the user declines within the state callback */
shared_ptr<CallSession> ref = static_pointer_cast<CallSession>(shared_from_this());
shared_ptr<CallSession> ref = getSharedFromThis();
#if 0
call->bg_task_id=sal_begin_background_task("liblinphone call notification", NULL, NULL);
#endif
......@@ -883,7 +883,7 @@ int CallSession::startInvite (const Address *destination, const string &subject)
}
char *from = linphone_address_as_string(d->log->from);
/* Take a ref because sal_call() may destroy the CallSession if no SIP transport is available */
shared_ptr<CallSession> ref = static_pointer_cast<CallSession>(shared_from_this());
shared_ptr<CallSession> ref = getSharedFromThis();
int result = d->op->call(from, destinationStr.c_str(), subject.empty() ? nullptr : subject.c_str());
ms_free(from);
if (result < 0) {
......
......@@ -38,6 +38,8 @@ class LINPHONE_PUBLIC CallSession : public Object {
friend class ClientGroupChatRoom;
public:
L_OVERRIDE_SHARED_FROM_THIS(CallSession);
CallSession (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener);
LinphoneStatus accept (const CallSessionParams *csp = nullptr);
......
......@@ -609,7 +609,7 @@ float MediaSessionPrivate::aggregateQualityRatings (float audioRating, float vid
void MediaSessionPrivate::setState (LinphoneCallState newState, const string &message) {
L_Q();
/* Take a ref on the session otherwise it might get destroyed during the call to setState */
shared_ptr<CallSession> session = static_pointer_cast<CallSession>(q->shared_from_this());
shared_ptr<CallSession> session = q->getSharedFromThis();
CallSessionPrivate::setState(newState, message);
updateReportingCallState();
}
......
......@@ -19,6 +19,7 @@
#ifndef _OBJECT_P_H_
#define _OBJECT_P_H_
#include <memory>
#include <unordered_map>
#include "variant/variant.h"
......@@ -28,14 +29,17 @@
LINPHONE_BEGIN_NAMESPACE
class ObjectPrivate {
friend class ObjectFactory;
public:
virtual ~ObjectPrivate () = default;
protected:
Object *mPublic = nullptr;
Object *mPublic;
private:
std::unordered_map<std::string, Variant> properties;
std::weak_ptr<Object> weak;
L_DECLARE_PUBLIC(Object);
};
......
......@@ -30,8 +30,21 @@ Object::~Object () {
delete mPrivate;
}
Object::Object (ObjectPrivate &p) : mPrivate(&p) {
mPrivate->mPublic = this;
Object::Object (ObjectPrivate &p) : mPrivate(&p) {}
shared_ptr<Object> Object::getSharedFromThis () {
return mPrivate->weak.lock();
}
shared_ptr<const Object> Object::getSharedFromThis () const {
return mPrivate->weak.lock();
}
void ObjectFactory::setPublic (const shared_ptr<Object> &object) {
L_ASSERT(object);
ObjectPrivate *d = object->getPrivate();
d->mPublic = object.get();
d->weak = object;
}
LINPHONE_END_NAMESPACE
......@@ -27,15 +27,18 @@
LINPHONE_BEGIN_NAMESPACE
class LINPHONE_PUBLIC Object :
public std::enable_shared_from_this<Object>,
public PropertyContainer {
class LINPHONE_PUBLIC Object : public PropertyContainer {
friend class ObjectFactory;
public:
virtual ~Object ();
protected:
explicit Object (ObjectPrivate &p);
std::shared_ptr<Object> getSharedFromThis ();
std::shared_ptr<const Object> getSharedFromThis () const;
ObjectPrivate *mPrivate = nullptr;
private:
......@@ -43,6 +46,24 @@ private:
L_DISABLE_COPY(Object);
};
class ObjectFactory {
public:
template<typename T, class ...Args>
static inline std::shared_ptr<T> create (Args &&...args) {
static_assert(std::is_base_of<Object, T>::value, "Not an object.");
std::shared_ptr<T> object = std::make_shared<T>(args...);
setPublic(object);
return object;
}
private:
ObjectFactory () = delete;
static void setPublic (const std::shared_ptr<Object> &object);
L_DISABLE_COPY(ObjectFactory);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _OBJECT_H_
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