comparison qt/d1/qt/QtdObject.d @ 261:8f7bb7fc3123 lifetime

Preparing for a better world
author maxter
date Mon, 21 Sep 2009 13:11:04 +0000
parents b5773ccab07d
children 90131f64c9c9
comparison
equal deleted inserted replaced
260:b5773ccab07d 261:8f7bb7fc3123
20 20
21 enum QtdObjectFlags : ubyte 21 enum QtdObjectFlags : ubyte
22 { 22 {
23 none, 23 none,
24 // The native object will not be deleted when the wrapper is deleted 24 // The native object will not be deleted when the wrapper is deleted
25 skipNativeDelete = 0b0001, 25 skipNativeDelete = 0b0_0001,
26 skipDDelete = 0b0010, 26 // The wrapper will not be deleted when the native object is deleted
27 hasDId = 0b0100, 27 skipDDelete = 0b0_0010,
28 stackAllocated = 0b1000 28 // D object reference is stored in the shell
29 /+ 29 hasDId = 0b0_0100,
30 // The will be deleted when is goes out of scope. Implies skipNativeDelete 30 // The wrapper is allocated on thread-local stack and destroyed at the end of the scope
31 scoped = 0x08 31 stackAllocated = 0b0_1000
32 +/ 32 // It is a QObject
33 isQObject = 0b1_0000
33 } 34 }
34 35
35 class MetaObject 36 class MetaObject
36 { 37 {
37 alias typeof(this) This; 38 alias typeof(this) This;
38 39
39 private 40 private
40 { 41 {
41 MetaObject _base; 42 MetaObject _base;
42 ClassInfo _classInfo; 43 ClassInfo _classInfo;
43 } 44 }
44 45
45 //COMPILER BUG: not accessible from QMetaObject 46 //COMPILER BUG: not accessible from QMetaObject
46 protected 47 protected
47 { 48 {
106 this(QtdMetaObjectBase base) 107 this(QtdMetaObjectBase base)
107 { 108 {
108 super(base); 109 super(base);
109 } 110 }
110 111
111 void construct(T : QtdObject, Concrete = T)() 112 void construct(T : QtdObject)()
112 { 113 {
113 super.construct!(T); 114 super.construct!(T);
114 _createWrapper = &T.__createWrapper; 115 _createWrapper = &T.__createWrapper;
115 } 116 }
116 } 117 }
117 118
118 /++ 119
119 Meta-object for polymorphic Qt classes.
120 +/
121 final class QtdMetaObject : QtdMetaObjectBase 120 final class QtdMetaObject : QtdMetaObjectBase
122 { 121 {
123 alias typeof(this) This; 122 alias typeof(this) This;
124 123
125 private void* _typeId; 124 private void* _typeId;
150 149
151 return static_cast!(QtdObject)(_createWrapper(nativeId, flags)); 150 return static_cast!(QtdObject)(_createWrapper(nativeId, flags));
152 } 151 }
153 } 152 }
154 153
154 class IdMappings
155 {
156 private void* _data;
157
158 this()
159 {
160 }
161
162 void add(void* nativeId, void* dId)
163 {
164 }
165
166 void remove(void* dId)
167 {
168 }
169
170 void* opIndex[void* nativeId]
171 {
172 }
173
174 ~this()
175 {
176 free(_data);
177 }
178 }
179
155 abstract class QtdObjectBase 180 abstract class QtdObjectBase
156 { 181 {
157 alias typeof(this) This; 182 alias typeof(this) This;
158 183
159 void* __nativeId; 184 void* __nativeId;
160 QtdObjectFlags __flags; 185 QtdObjectFlags __flags;
161 186
162 new (size_t size, QtdObjectFlags flags = QtdObjectFlags.none) 187 new (size_t size, QtdObjectFlags flags = QtdObjectFlags.none)
163 { 188 {
164 return flags & QtdObjectFlags.stackAllocated ? __stackAlloc.alloc(size) : 189 return flags & QtdObjectFlags.stackAllocated ? __stackAlloc.alloc(size) :
165 GC.malloc(size, GC.BlkAttr.FINALIZE); 190 GC.malloc(size, GC.BlkAttr.FINALIZE);
166 } 191 }
175 200
176 this(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) 201 this(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none)
177 { 202 {
178 __nativeId = nativeId; 203 __nativeId = nativeId;
179 __flags = flags; 204 __flags = flags;
205
180 debug(QtdVerbose) __print("D wrapper constructed"); 206 debug(QtdVerbose) __print("D wrapper constructed");
181 } 207 }
182 208
183 debug(QtdVerbose) 209 debug(QtdVerbose)
184 { 210 {
199 { 225 {
200 debug(QtdVerbose) __print("In QtdObjectBase destructor"); 226 debug(QtdVerbose) __print("In QtdObjectBase destructor");
201 227
202 if (!(__flags & QtdObjectFlags.skipNativeDelete)) 228 if (!(__flags & QtdObjectFlags.skipNativeDelete))
203 { 229 {
230 // Avoid deleting the wrapper twice
204 __flags |= QtdObjectFlags.skipDDelete; 231 __flags |= QtdObjectFlags.skipDDelete;
205 debug(QtdVerbose) __print("About to call native delete"); 232 debug(QtdVerbose) __print("About to call native delete");
206 __deleteNative; 233 __deleteNative;
207 } 234 }
208 } 235 }
209 } 236 }
210 237
211 // Base class for by-reference objects 238 // Base class for by-reference objects
212 abstract class QtdObject : QtdObjectBase 239 abstract class QtdObject : QtdObjectBase
213 { 240 {
214 private 241 private
215 { 242 {
216 typeof(this) __next, __prev; 243 typeof(this) __next, __prev;
244 ubyte __nativeRef_;
217 static typeof(this) __root; 245 static typeof(this) __root;
218 }
219
220 /++
221 Use this method instead of 'is' operator to check if two D objects
222 wrap the same native object.
223 +/
224 bool isSame(QtdObject other)
225 {
226 return __nativeId == other.__nativeId;
227 } 246 }
228 247
229 mixin SignalHandlerOps; 248 mixin SignalHandlerOps;
230 249
231 this(void* nativeId, QtdObjectFlags flags) 250 this(void* nativeId, QtdObjectFlags flags)
232 { 251 {
233 super (nativeId, flags); 252 super (nativeId, flags);
234 if (!(flags & QtdObjectFlags.skipNativeDelete)) 253
235 __pin; 254 if (!(flags & QtdObjectFlags.isQObject) && !(flags & QtdObjectFlags.hasDId))
236 } 255 __addIdMapping;
237 256 }
238 final void __pin() 257
239 { 258 void __addIdMapping() {}
240 debug(QtdVerbose) __print("Pinning"); 259 void __removeIdMapping() {}
241 260
242 __next = __root; 261 final void __nativeRef()
243 __root = this; 262 {
244 if (__next) 263 assert (__nativeRef_ < 255);
245 __next.__prev = this; 264
246 } 265 if (!__nativeRef_)
247 266 {
248 final void __unpin() 267 __next = __root;
249 { 268 __root = this;
250 debug(QtdVerbose) __print("Unpinning"); 269 if (__next)
251 270 __next.__prev = this;
252 if (__prev) 271 }
253 __prev.__next = __next; 272 __nativeRef_++;
254 else 273
255 __root = __next; 274 debug(QtdVerbose) __print("Native ref incremented");
256 275 }
257 if (__next) 276
258 __next.__prev = __prev; 277 final void __nativeDeref()
259 } 278 {
260 279 assert (__nativeRef > 0);
261 void __nativeOwnership(bool value) 280 __nativeRef_--;
262 { 281
263 if (value) 282 if (!__nativeRef_)
264 { 283 {
265 assert (!(__flags & QtdObjectFlags.skipNativeDelete)); 284 if (__prev)
266 __flags |= QtdObjectFlags.skipNativeDelete; 285 __prev.__next = __next;
267 __unpin; 286 else
268 } 287 __root = __next;
269 else 288
270 { 289 if (__next)
271 assert (__flags & QtdObjectFlags.skipNativeDelete); 290 __next.__prev = __prev;
272 __flags = __flags &= ~QtdObjectFlags.skipNativeDelete; 291 }
273 __pin; 292
274 } 293 debug(QtdVerbose) __print("Native ref decremented");
275 } 294 }
276 295
277 ~this() 296 ~this()
278 { 297 {
279 debug(QtdVerbose) __print("In QtdObject destructor"); 298 if (!(__flags & QtdObjectFlags.isQObject) && !(__flags & QtdObjectFlags.hasDId))
280 299 __removeMapping;
281 if (__prev || __root is this) 300
282 __unpin; 301 if (__nativeRef_)
283 } 302 {
284 } 303 if (__nativeRef_ > 1)
285 304 {
286 /++ 305 debug(QtdVerbose) __print("Native ref is greater then 1 when deleting the object");
287 +/ 306 __nativeRef_ = 1;
288 void dispose(QtdObjectBase obj) 307 }
289 { 308 __nativeDeref;
290 obj.__flags &= ~QtdObjectFlags.skipNativeDelete; 309 }
291 delete obj; 310 }
292 } 311 }
293 312
294 // Called from shell destructors 313 // Called from shell destructors
295 extern(C) void qtd_delete_d_object(void* dId) 314 extern(C) void qtd_delete_d_object(void* dId)
296 { 315 {
302 // Avoid deleting native object twice 321 // Avoid deleting native object twice
303 obj.__flags |= QtdObjectFlags.skipNativeDelete; 322 obj.__flags |= QtdObjectFlags.skipNativeDelete;
304 delete obj; 323 delete obj;
305 } 324 }
306 } 325 }
326
327 extern(C) void qtd_native_ref(void* dId)
328 {
329 (cast(QtdObject)dId).__nativeRef;
330 }
331
332 extern(C) void qtd_native_deref(void* dId)
333 {
334 (cast(QtdObject)dId).__nativeDeref;
335 }
336
337