comparison d1/qtd/QtdObject.d @ 311:8674fd5f34f4 lifetime

Added d1/d2 top directories
author maxter <spambox@d-coding.com>
date Wed, 23 Dec 2009 16:17:22 +0200
parents
children 80b52f5e97b6
comparison
equal deleted inserted replaced
310:5bcfe9e7db7f 311:8674fd5f34f4
1 /**
2 *
3 * Copyright: Copyright QtD Team, 2008-2009
4 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>
5 * Authors: Max Samukha, Eldar Insafutdinov
6 *
7 * Copyright QtD Team, 2008-2009
8 * Distributed under the Boost Software License, Version 1.0.
9 * (See accompanying file boost-license-1.0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 *
11 */
12
13 module qt.QtdObject;
14
15 import qt.Signal;
16 import tango.core.Memory;
17 debug (QtdVerbose)
18 import tango.io.Stdout;
19
20
21 enum QtdObjectFlags : ubyte
22 {
23 none,
24 // The native object will not be deleted when the wrapper is deleted
25 skipNativeDelete = 0b0_0001,
26 // The wrapper will not be deleted when the native object is deleted
27 skipDDelete = 0b0_0010,
28 // D object reference is stored in the shell
29 hasDId = 0b0_0100,
30 // The wrapper is allocated on thread-local stack and destroyed at the end of the scope
31 stackAllocated = 0b0_1000
32 // It is a QObject
33 isQObject = 0b1_0000
34 }
35
36 class MetaObject
37 {
38 alias typeof(this) This;
39
40 private
41 {
42 MetaObject _base;
43 ClassInfo _classInfo;
44 }
45
46 //COMPILER BUG: not accessible from QMetaObject
47 protected
48 {
49 This _firstDerived;
50 This _next;
51 }
52
53 private void addDerived(This mo)
54 {
55 mo._next = _firstDerived;
56 _firstDerived = mo;
57 }
58
59 /++
60 Next sibling on this derivation level
61 +/
62 final This next()
63 {
64 return _next;
65 }
66
67 /++
68 Head of the linked list of derived classes
69 +/
70 final This firstDerived()
71 {
72 return _firstDerived;
73 }
74
75 // NOTE: construction is split between this non-templated constructor and 'construct' function below.
76 this(This base)
77 {
78 if (base)
79 {
80 base.addDerived(this);
81 _base = base;
82 }
83 }
84
85 // TODO: can be removed when D acquires templated constructors
86 void construct(T : Object)()
87 {
88 _classInfo = T.classinfo;
89 }
90
91 final This base()
92 {
93 return _base;
94 }
95
96 final ClassInfo classInfo()
97 {
98 return _classInfo;
99 }
100 }
101
102
103 abstract class QtdMetaObjectBase : MetaObject
104 {
105 QtdObjectBase function(void* nativeId, QtdObjectFlags flags) _createWrapper;
106
107 this(QtdMetaObjectBase base)
108 {
109 super(base);
110 }
111
112 void construct(T : QtdObject)()
113 {
114 super.construct!(T);
115 _createWrapper = &T.__createWrapper;
116 }
117 }
118
119
120 final class QtdMetaObject : QtdMetaObjectBase
121 {
122 alias typeof(this) This;
123
124 private void* _typeId;
125
126 this(void* typeId, QtdMetaObject base)
127 {
128 super(base);
129 _typeId = typeId;
130 }
131
132 QtdObject wrap(void* nativeId, void* typeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete)
133 {
134 if (typeId == _typeId)
135 {
136 /+
137 if (auto p = nativeId in _nativeToDMap)
138 return *p;
139 +/
140 }
141 else
142 {
143 for (auto mo = static_cast!(This)(_firstDerived); mo; mo = static_cast!(This)(mo._next))
144 {
145 if (auto obj = mo.wrap(nativeId, typeId, flags))
146 return obj;
147 }
148 }
149
150 return static_cast!(QtdObject)(_createWrapper(nativeId, flags));
151 }
152 }
153
154 /*
155 class IdMappings
156 {
157 private void* _data;
158
159 this()
160 {
161 }
162
163 void add(void* nativeId, void* dId)
164 {
165 }
166
167 void remove(void* dId)
168 {
169 }
170
171 void* opIndex[void* nativeId]
172 {
173 }
174
175 ~this()
176 {
177 free(_data);
178 }
179 }
180 */
181
182 abstract class QtdObjectBase
183 {
184 }
185
186 // Base class for by-reference objects
187 abstract class QtdObject
188 {
189 alias typeof(this) This;
190
191 private
192 {
193 typeof(this) __next, __prev;
194 static typeof(this) __root;
195 }
196
197 /// Internal members. Do not change
198 void* __nativeId;
199 /// ditto
200 QtdObjectFlags __flags;
201
202 new (size_t size, QtdObjectFlags flags = QtdObjectFlags.none)
203 {
204 return flags & QtdObjectFlags.stackAllocated ? __stackAlloc.alloc(size) :
205 GC.malloc(size, GC.BlkAttr.FINALIZE);
206 }
207
208 delete (void* p)
209 {
210 if ((cast(This)p).__flags & QtdObjectFlags.stackAllocated)
211 __stackAlloc.free(this.classinfo.init.length);
212 else
213 GC.free(p);
214 }
215
216
217 mixin SignalHandlerOps;
218
219 this(void* nativeId, QtdObjectFlags flags)
220 {
221 __nativeId = nativeId;
222 __flags = flags;
223
224 debug(QtdVerbose) __print("D wrapper constructed");
225 /*
226 if (!(flags & QtdObjectFlags.isQObject) && !(flags & QtdObjectFlags.hasDId))
227 __addIdMapping;
228 */
229 }
230
231 debug(QtdVerbose)
232 {
233 void __print(string msg)
234 {
235 Stdout.formatln("{} (native: {}, D: {}, flags 0b{:b})", msg, __nativeId, cast(void*)this, __flags);
236 }
237 }
238
239 protected void __deleteNative()
240 {
241 assert(false, "Cannot delete native "
242 ~ this.classinfo.name
243 ~ " because it has no public destructor");
244 }
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
280 ~this()
281 {
282 /*
283 if (!(__flags & QtdObjectFlags.isQObject) && !(__flags & QtdObjectFlags.hasDId))
284 __removeMapping;
285 */
286
287 debug(QtdVerbose) __print("In QtdObject destructor");
288
289 if (__prev || __root is this)
290 __unpin;
291 }
292 }
293
294 // Called from shell destructors
295 extern(C) void qtd_delete_d_object(void* dId)
296 {
297 auto obj = cast(QtdObject)dId;
298 debug(QtdVerbose) obj.__print("In qtd_delete_d_object");
299
300 if (!(obj.__flags & QtdObjectFlags.skipDDelete))
301 {
302 // Avoid deleting native object twice
303 obj.__flags |= QtdObjectFlags.skipNativeDelete;
304 delete obj;
305 }
306 }
307
308 extern(C) void qtd_pin(void* dId)
309 {
310 (cast(QtdObject)dId).__pin;
311 }
312
313 extern(C) void qtd_native_unpin(void* dId)
314 {
315 (cast(QtdObject)dId).__unpin;
316 }