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