author | simon <simon> | 2002-11-21 12:02:07 (UTC) |
---|---|---|
committer | simon <simon> | 2002-11-21 12:02:07 (UTC) |
commit | 58715bab157ca913a08b7ce26c230bbc0be5f70b (patch) (unidiff) | |
tree | c104abd25c1ed2450b8fe469701e77f2e132aa2d | |
parent | 74b4b55fd5f09c1b8f38228488aa5876e40c0ae3 (diff) | |
download | opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.zip opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.tar.gz opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.tar.bz2 |
- backporting two changes from qt3:
- added QInterfacePtr template class to take over the tedious work
of manual refcounting on interface objects
- the QREFCOUNT macro no longer relies on the developer to declare
(and initialize!) a refcnt variable but defines a qtrefcount class
variable itself, that takes care of proper initialization
(fixes various missing refcounter initializations found)
Harlekin suggested to commit :)
-rw-r--r-- | library/qcom.h | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/library/qcom.h b/library/qcom.h index 8c0fa60..9972d8f 100644 --- a/library/qcom.h +++ b/library/qcom.h | |||
@@ -54,30 +54,118 @@ struct Q_EXPORT QUnknownInterface | |||
54 | #define IID_QLibrary QUuid( 0xd16111d4, 0xe1e7, 0x4c47, 0x85, 0x99, 0x24, 0x48, 0x3d, 0xae, 0x2e, 0x07) | 54 | #define IID_QLibrary QUuid( 0xd16111d4, 0xe1e7, 0x4c47, 0x85, 0x99, 0x24, 0x48, 0x3d, 0xae, 0x2e, 0x07) |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | struct Q_EXPORT QLibraryInterface : public QUnknownInterface | 57 | struct Q_EXPORT QLibraryInterface : public QUnknownInterface |
58 | { | 58 | { |
59 | virtual bool init() = 0; | 59 | virtual bool init() = 0; |
60 | virtual void cleanup() = 0; | 60 | virtual void cleanup() = 0; |
61 | virtual bool canUnload() const = 0; | 61 | virtual bool canUnload() const = 0; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #define Q_CREATE_INSTANCE( IMPLEMENTATION ) \ | 64 | #define Q_CREATE_INSTANCE( IMPLEMENTATION ) \ |
65 | IMPLEMENTATION *i = new IMPLEMENTATION; \ | 65 | IMPLEMENTATION *i = new IMPLEMENTATION; \ |
66 | QUnknownInterface* iface = 0; \ | 66 | QUnknownInterface* iface = 0; \ |
67 | i->queryInterface( IID_QUnknown, &iface ); \ | 67 | i->queryInterface( IID_QUnknown, &iface ); \ |
68 | return iface; | 68 | return iface; |
69 | 69 | ||
70 | template <class T> | ||
71 | class QInterfacePtr | ||
72 | { | ||
73 | public: | ||
74 | QInterfacePtr():iface(0){} | ||
75 | |||
76 | QInterfacePtr( T* i) { | ||
77 | if ( (iface = i) ) | ||
78 | iface->addRef(); | ||
79 | } | ||
80 | |||
81 | QInterfacePtr(const QInterfacePtr<T> &p) { | ||
82 | if ( (iface = p.iface) ) | ||
83 | iface->addRef(); | ||
84 | } | ||
85 | |||
86 | ~QInterfacePtr() { | ||
87 | if ( iface ) | ||
88 | iface->release(); | ||
89 | } | ||
90 | |||
91 | QInterfacePtr<T> &operator=(const QInterfacePtr<T> &p) { | ||
92 | if ( iface != p.iface ) { | ||
93 | if ( iface ) | ||
94 | iface->release(); | ||
95 | if ( (iface = p.iface) ) | ||
96 | iface->addRef(); | ||
97 | } | ||
98 | return *this; | ||
99 | } | ||
100 | |||
101 | QInterfacePtr<T> &operator=(T* i) { | ||
102 | if (iface != i ) { | ||
103 | if ( iface ) | ||
104 | iface->release(); | ||
105 | if ( (iface = i) ) | ||
106 | iface->addRef(); | ||
107 | } | ||
108 | return *this; | ||
109 | } | ||
110 | |||
111 | bool operator==( const QInterfacePtr<T> &p ) const { return iface == p.iface; } | ||
112 | |||
113 | bool operator!= ( const QInterfacePtr<T>& p ) const { return !( *this == p ); } | ||
114 | |||
115 | bool isNull() const { return !iface; } | ||
116 | |||
117 | T* operator->() const { return iface; } | ||
118 | |||
119 | T& operator*() const { return *iface; } | ||
120 | |||
121 | operator T*() const { return iface; } | ||
122 | |||
123 | QUnknownInterface** operator &() const { | ||
124 | if( iface ) | ||
125 | iface->release(); | ||
126 | return (QUnknownInterface**)&iface; | ||
127 | } | ||
128 | |||
129 | T** operator &() { | ||
130 | if ( iface ) | ||
131 | iface->release(); | ||
132 | return &iface; | ||
133 | } | ||
134 | |||
135 | private: | ||
136 | T* iface; | ||
137 | }; | ||
138 | |||
139 | |||
140 | // internal class that wraps an initialized ulong | ||
141 | struct Q_EXPORT QtULong | ||
142 | { | ||
143 | QtULong() : ref( 0 ) { } | ||
144 | operator unsigned long () const { return ref; } | ||
145 | unsigned long& operator++() { return ++ref; } | ||
146 | unsigned long operator++( int ) { return ref++; } | ||
147 | unsigned long& operator--() { return --ref; } | ||
148 | unsigned long operator--( int ) { return ref--; } | ||
149 | |||
150 | unsigned long ref; | ||
151 | }; | ||
152 | |||
70 | #define Q_EXPORT_INTERFACE() \ | 153 | #define Q_EXPORT_INTERFACE() \ |
71 | extern "C" QUnknownInterface* ucm_instantiate() | 154 | extern "C" QUnknownInterface* ucm_instantiate() |
72 | 155 | ||
73 | #define Q_REFCOUNT ulong addRef() {return ref++;}ulong release() {if(!--ref){delete this;return 0;}return ref;} | 156 | #define Q_REFCOUNT \ |
157 | private: \ | ||
158 | QtULong qtrefcount; \ | ||
159 | public: \ | ||
160 | ulong addRef() {return qtrefcount++;} \ | ||
161 | ulong release() {if(!--qtrefcount){delete this;return 0;}return qtrefcount;} | ||
74 | 162 | ||
75 | #else // QT_NO_COMPONENT | 163 | #else // QT_NO_COMPONENT |
76 | 164 | ||
77 | struct Q_EXPORT QUnknownInterface | 165 | struct Q_EXPORT QUnknownInterface |
78 | { | 166 | { |
79 | }; | 167 | }; |
80 | 168 | ||
81 | #endif // QT_NO_COMPONENT | 169 | #endif // QT_NO_COMPONENT |
82 | 170 | ||
83 | #endif // QCOM_H | 171 | #endif // QCOM_H |