object.hh 4.26 KB
Newer Older
François Grisez's avatar
François Grisez committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
object.hh
Copyright (C) 2017 Belledonne Communications SARL

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

20 21 22 23 24 25
#ifndef _LINPHONE_OBJECT_HH
#define _LINPHONE_OBJECT_HH

#include <memory>
#include <list>
#include <map>
26
#include <string>
27

28 29 30 31 32 33 34 35 36 37 38 39
#ifndef LINPHONECXX_PUBLIC
#if defined(_MSC_VER)
#ifdef LINPHONECXX_EXPORTS
#define LINPHONECXX_PUBLIC	__declspec(dllexport)
#else
#define LINPHONECXX_PUBLIC	__declspec(dllimport)
#endif
#else
#define LINPHONECXX_PUBLIC
#endif
#endif

40 41 42 43 44 45 46 47
#ifndef LINPHONECXX_DEPRECATED
#if defined(_MSC_VER)
#define LINPHONECXX_DEPRECATED __declspec(deprecated)
#else
#define LINPHONECXX_DEPRECATED __attribute__ ((deprecated))
#endif
#endif

48
namespace linphone {
49

50 51
	class Object: public std::enable_shared_from_this<Object> {
	public:
52
		Object(void *ptr, bool takeRef=true);
53
		virtual ~Object();
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
	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;
			}
		}
71 72
		LINPHONECXX_PUBLIC void unsetData(const std::string &key);
		LINPHONECXX_PUBLIC bool dataExists(const std::string &key);
73

74 75
	public:
		template <class T>
76
		static std::shared_ptr<T> cPtrToSharedPtr(void *ptr, bool takeRef=true) {
77 78 79
			if (ptr == NULL) {
				return nullptr;
			} else {
80
				Object *cppPtr = getBackPtrFromCPtr(ptr);
81 82 83 84 85 86 87
				if (cppPtr == NULL) {
					return std::make_shared<T>(ptr, takeRef);
				} else {
					return std::static_pointer_cast<T,Object>(cppPtr->shared_from_this());
				}
			}
		}
88 89 90 91 92 93 94 95 96 97 98 99 100
		template <class T>
		static std::shared_ptr<const T> cPtrToSharedPtr(const void *ptr, bool takeRef=true) {
			if (ptr == NULL) {
				return nullptr;
			} else {
				Object *cppPtr = getBackPtrFromCPtr(ptr);
				if (cppPtr == NULL) {
					return std::make_shared<const T>((void *)ptr, takeRef);
				} else {
					return std::static_pointer_cast<const T,Object>(cppPtr->shared_from_this());
				}
			}
		}
101
		static void *sharedPtrToCPtr(const std::shared_ptr<const Object> &sharedPtr);
102

103

104
	private:
105
		LINPHONECXX_PUBLIC std::map<std::string,void *> &getUserData() const;
106
		static Object *getBackPtrFromCPtr(const void *ptr);
107 108
		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;}
109

110
	protected:
111
		void *mPrivPtr;
112

113 114 115
	private:
		static const std::string sUserDataKey;
	};
116 117 118 119


	class Listener {
	public:
120
		LINPHONECXX_PUBLIC virtual ~Listener() = 0;
121 122 123
	};


124 125
	class ListenableObject: public Object {
	protected:
126
		ListenableObject(void *ptr, bool takeRef=true);
127
		void setListener(const std::shared_ptr<Listener> &listener);
128

129 130
	public:
		static std::shared_ptr<Listener> & getListenerFromObject(void *object);
131

132 133
	private:
		static void deleteListenerPtr(std::shared_ptr<Listener> *ptr) {delete ptr;}
134

135 136 137
	private:
		static std::string sListenerDataName;
	};
138

139 140
	class MultiListenableObject: public Object {
		friend class Factory;
141

142
	protected:
143
		MultiListenableObject(void *ptr, bool takeRef=true);
144
		virtual ~MultiListenableObject() {};
145

146 147 148
	protected:
		void addListener(const std::shared_ptr<Listener> &listener);
		void removeListener(const std::shared_ptr<Listener> &listener);
149
		std::list<std::shared_ptr<Listener> > &getListeners() const;
150

151 152
	private:
		static void deleteListenerList(std::list<std::shared_ptr<Listener> > *listeners) {delete listeners;}
153

154 155 156
	private:
		static std::string sListenerListName;
	};
157

158 159 160
};

#endif // _LINPHONE_OBJECT_HH