Mercurial > projects > qtd
comparison qt/d1/qt/QtdObject.d @ 262:90131f64c9c9 lifetime
looks like enabling/disabling GC is enough
author | maxter |
---|---|
date | Tue, 22 Sep 2009 15:19:04 +0000 |
parents | 8f7bb7fc3123 |
children |
comparison
equal
deleted
inserted
replaced
261:8f7bb7fc3123 | 262:90131f64c9c9 |
---|---|
149 | 149 |
150 return static_cast!(QtdObject)(_createWrapper(nativeId, flags)); | 150 return static_cast!(QtdObject)(_createWrapper(nativeId, flags)); |
151 } | 151 } |
152 } | 152 } |
153 | 153 |
154 /* | |
154 class IdMappings | 155 class IdMappings |
155 { | 156 { |
156 private void* _data; | 157 private void* _data; |
157 | 158 |
158 this() | 159 this() |
174 ~this() | 175 ~this() |
175 { | 176 { |
176 free(_data); | 177 free(_data); |
177 } | 178 } |
178 } | 179 } |
180 */ | |
179 | 181 |
180 abstract class QtdObjectBase | 182 abstract class QtdObjectBase |
181 { | 183 { |
184 } | |
185 | |
186 // Base class for by-reference objects | |
187 abstract class QtdObject | |
188 { | |
182 alias typeof(this) This; | 189 alias typeof(this) This; |
183 | 190 |
191 private | |
192 { | |
193 typeof(this) __next, __prev; | |
194 static typeof(this) __root; | |
195 } | |
196 | |
197 /// Internal members. Do not change | |
184 void* __nativeId; | 198 void* __nativeId; |
199 /// ditto | |
185 QtdObjectFlags __flags; | 200 QtdObjectFlags __flags; |
186 | 201 |
187 new (size_t size, QtdObjectFlags flags = QtdObjectFlags.none) | 202 new (size_t size, QtdObjectFlags flags = QtdObjectFlags.none) |
188 { | 203 { |
189 return flags & QtdObjectFlags.stackAllocated ? __stackAlloc.alloc(size) : | 204 return flags & QtdObjectFlags.stackAllocated ? __stackAlloc.alloc(size) : |
196 __stackAlloc.free(this.classinfo.init.length); | 211 __stackAlloc.free(this.classinfo.init.length); |
197 else | 212 else |
198 GC.free(p); | 213 GC.free(p); |
199 } | 214 } |
200 | 215 |
201 this(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) | 216 |
217 mixin SignalHandlerOps; | |
218 | |
219 this(void* nativeId, QtdObjectFlags flags) | |
202 { | 220 { |
203 __nativeId = nativeId; | 221 __nativeId = nativeId; |
204 __flags = flags; | 222 __flags = flags; |
205 | 223 |
206 debug(QtdVerbose) __print("D wrapper constructed"); | 224 debug(QtdVerbose) __print("D wrapper constructed"); |
225 /* | |
226 if (!(flags & QtdObjectFlags.isQObject) && !(flags & QtdObjectFlags.hasDId)) | |
227 __addIdMapping; | |
228 */ | |
207 } | 229 } |
208 | 230 |
209 debug(QtdVerbose) | 231 debug(QtdVerbose) |
210 { | 232 { |
211 void __print(string msg) | 233 void __print(string msg) |
219 assert(false, "Cannot delete native " | 241 assert(false, "Cannot delete native " |
220 ~ this.classinfo.name | 242 ~ this.classinfo.name |
221 ~ " because it has no public destructor"); | 243 ~ " because it has no public destructor"); |
222 } | 244 } |
223 | 245 |
246 /* | |
247 void __addIdMapping() {} | |
248 void __removeIdMapping() {} | |
249 */ | |
250 | |
251 final void __pin() | |
252 { | |
253 assert (!__prev && !__root is this); | |
254 __next = __root; | |
255 __root = this; | |
256 if (__next) | |
257 __next.__prev = this; | |
258 | |
259 debug(QtdVerbose) __print("Wrapper GC disabled"); | |
260 } | |
261 | |
262 final void __unpin() | |
263 { | |
264 assert (__prev || __root is this); | |
265 | |
266 if (__prev) | |
267 { | |
268 __prev.__next = __next; | |
269 __prev = null; | |
270 } | |
271 else | |
272 __root = __next; | |
273 | |
274 if (__next) | |
275 __next.__prev = __prev; | |
276 | |
277 debug(QtdVerbose) __print("Wrapper GC reenabled"); | |
278 } | |
279 | |
224 ~this() | 280 ~this() |
225 { | 281 { |
226 debug(QtdVerbose) __print("In QtdObjectBase destructor"); | 282 /* |
283 if (!(__flags & QtdObjectFlags.isQObject) && !(__flags & QtdObjectFlags.hasDId)) | |
284 __removeMapping; | |
285 */ | |
286 | |
287 debug(QtdVerbose) __print("In QtdObject destructor"); | |
227 | 288 |
228 if (!(__flags & QtdObjectFlags.skipNativeDelete)) | 289 if (!(__flags & QtdObjectFlags.skipNativeDelete)) |
229 { | 290 { |
230 // Avoid deleting the wrapper twice | 291 // Avoid deleting the wrapper twice |
231 __flags |= QtdObjectFlags.skipDDelete; | 292 __flags |= QtdObjectFlags.skipDDelete; |
232 debug(QtdVerbose) __print("About to call native delete"); | 293 debug(QtdVerbose) __print("About to call native delete"); |
233 __deleteNative; | 294 __deleteNative; |
234 } | 295 } |
235 } | 296 |
236 } | 297 if (__prev || __root is this) |
237 | 298 __unpin; |
238 // Base class for by-reference objects | |
239 abstract class QtdObject : QtdObjectBase | |
240 { | |
241 private | |
242 { | |
243 typeof(this) __next, __prev; | |
244 ubyte __nativeRef_; | |
245 static typeof(this) __root; | |
246 } | |
247 | |
248 mixin SignalHandlerOps; | |
249 | |
250 this(void* nativeId, QtdObjectFlags flags) | |
251 { | |
252 super (nativeId, flags); | |
253 | |
254 if (!(flags & QtdObjectFlags.isQObject) && !(flags & QtdObjectFlags.hasDId)) | |
255 __addIdMapping; | |
256 } | |
257 | |
258 void __addIdMapping() {} | |
259 void __removeIdMapping() {} | |
260 | |
261 final void __nativeRef() | |
262 { | |
263 assert (__nativeRef_ < 255); | |
264 | |
265 if (!__nativeRef_) | |
266 { | |
267 __next = __root; | |
268 __root = this; | |
269 if (__next) | |
270 __next.__prev = this; | |
271 } | |
272 __nativeRef_++; | |
273 | |
274 debug(QtdVerbose) __print("Native ref incremented"); | |
275 } | |
276 | |
277 final void __nativeDeref() | |
278 { | |
279 assert (__nativeRef > 0); | |
280 __nativeRef_--; | |
281 | |
282 if (!__nativeRef_) | |
283 { | |
284 if (__prev) | |
285 __prev.__next = __next; | |
286 else | |
287 __root = __next; | |
288 | |
289 if (__next) | |
290 __next.__prev = __prev; | |
291 } | |
292 | |
293 debug(QtdVerbose) __print("Native ref decremented"); | |
294 } | |
295 | |
296 ~this() | |
297 { | |
298 if (!(__flags & QtdObjectFlags.isQObject) && !(__flags & QtdObjectFlags.hasDId)) | |
299 __removeMapping; | |
300 | |
301 if (__nativeRef_) | |
302 { | |
303 if (__nativeRef_ > 1) | |
304 { | |
305 debug(QtdVerbose) __print("Native ref is greater then 1 when deleting the object"); | |
306 __nativeRef_ = 1; | |
307 } | |
308 __nativeDeref; | |
309 } | |
310 } | 299 } |
311 } | 300 } |
312 | 301 |
313 // Called from shell destructors | 302 // Called from shell destructors |
314 extern(C) void qtd_delete_d_object(void* dId) | 303 extern(C) void qtd_delete_d_object(void* dId) |
322 obj.__flags |= QtdObjectFlags.skipNativeDelete; | 311 obj.__flags |= QtdObjectFlags.skipNativeDelete; |
323 delete obj; | 312 delete obj; |
324 } | 313 } |
325 } | 314 } |
326 | 315 |
327 extern(C) void qtd_native_ref(void* dId) | 316 extern(C) void qtd_pin(void* dId) |
328 { | 317 { |
329 (cast(QtdObject)dId).__nativeRef; | 318 (cast(QtdObject)dId).__pin; |
330 } | 319 } |
331 | 320 |
332 extern(C) void qtd_native_deref(void* dId) | 321 extern(C) void qtd_native_unpin(void* dId) |
333 { | 322 { |
334 (cast(QtdObject)dId).__nativeDeref; | 323 (cast(QtdObject)dId).__unpin; |
335 } | 324 } |
336 | |
337 |