comparison d2/qt/core/QMetaObject.d @ 364:a084e2df3776

Preparing for non-QObject meta-objects. Now meta-objects for static types can be uniformly accessed using meta!T
author Max Samukha <maxter@maxter.com>
date Fri, 11 Jun 2010 12:16:09 +0300
parents 9784459f0750
children 958e8b9a89bd
comparison
equal deleted inserted replaced
363:3b0545d4d479 364:a084e2df3776
11 qtd.MOC, 11 qtd.MOC,
12 std.string, 12 std.string,
13 std.typetuple, 13 std.typetuple,
14 std.c.stdlib; 14 std.c.stdlib;
15 15
16 class QMetaArgument : Meta 16 class QMetaArgument : MetaBase
17 { 17 {
18 } 18 }
19 19
20 class QMetaMethod : Meta 20 class QMetaMethod : MetaBase
21 { 21 {
22 alias typeof(this) This; 22 alias typeof(this) This;
23 23
24 // QMetaArgument[] arguments; 24 // QMetaArgument[] arguments;
25 string signature; 25 string signature;
82 { 82 {
83 return typeof(super).create!(method, This)(index); 83 return typeof(super).create!(method, This)(index);
84 } 84 }
85 } 85 }
86 86
87 class MetaObject : MetaType 87 /**
88 { 88 Base class for QtD meta-classes.
89 MetaObject _base; 89 */
90 abstract class QtdMetaClass : MetaClass
91 {
92 private:
93 void* nativeId_;
94
95 this() {}
96
97 public:
98
99 /**
100 */
101 @property
102 void* nativeId()
103 {
104 return nativeId_;
105 }
106
107 /* internal */ void construct(T)()
108 {
109 super.construct!T();
110 nativeId_ = T.qtd_nativeMetaObject;
111 }
90 } 112 }
91 113
92 struct QMetaObjectNative 114 struct QMetaObjectNative
93 { 115 {
94 QMetaObjectNative *superdata; 116 QMetaObjectNative *superdata;
97 void *extradata; 119 void *extradata;
98 } 120 }
99 121
100 class QMetaException : Exception { this(string msg) { super(msg); } } 122 class QMetaException : Exception { this(string msg) { super(msg); } }
101 123
102 final class QMetaObject 124 final class QMetaObject : QtdMetaClass
103 { 125 {
104 alias typeof(this) This; 126 alias typeof(this) This;
105
106 private this() {}
107 127
108 enum Call 128 enum Call
109 { 129 {
110 InvokeMetaMethod, 130 InvokeMetaMethod,
111 ReadProperty, 131 ReadProperty,
119 CreateInstance 139 CreateInstance
120 } 140 }
121 141
122 private 142 private
123 { 143 {
124 QMetaObjectNative* _nativeId;
125 QMetaObject _base; // super class
126 QMetaObject _firstDerived; // head of the linked list of derived classes
127 QMetaObject _next; // next sibling on this derivation level
128 QMetaMethod[] _methods; 144 QMetaMethod[] _methods;
129 ClassInfo _classInfo;
130
131 QObject function(void* nativeId) _createWrapper; 145 QObject function(void* nativeId) _createWrapper;
132 } 146 }
133 147
134 private void addDerived(QMetaObject mo) 148 void construct(T : QObject)()
135 { 149 {
136 mo._next = _firstDerived; 150 super.construct!T();
137 _firstDerived = mo;
138 }
139
140 // ctor
141 void construct(T : QObject)(void* nativeId)
142 {
143 alias BaseClassesTuple!(T)[0] Base;
144 This base;
145 static if (is(Base : QObject))
146 base = Base.staticMetaObject;
147
148 _nativeId = cast(QMetaObjectNative*)nativeId;
149 T.setStaticMetaObject(this);
150
151 if (base)
152 {
153 base.addDerived(this);
154 _base = base;
155 }
156 _classInfo = T.classinfo;
157
158 151
159 static if (isQtType!T) 152 static if (isQtType!T)
160 { 153 {
161 static if (is(T.ConcreteType)) 154 static if (is(T.ConcreteType))
162 alias T.ConcreteType Concrete; 155 alias T.ConcreteType Concrete;
169 return obj; 162 return obj;
170 }; 163 };
171 164
172 T._populateMetaInfo; 165 T._populateMetaInfo;
173 } 166 }
167
174 // create run time meta-objects for user-defined signals and slots 168 // create run time meta-objects for user-defined signals and slots
175 else static if (is(typeof(T.methods))) 169 else static if (is(typeof(T.methods)))
176 { 170 {
171 alias BaseClassesTuple!(T)[0] Base;
177 int index = Base.staticMetaObject().methodCount(); 172 int index = Base.staticMetaObject().methodCount();
178 173
179 static if (T.signals.length) 174 static if (T.signals.length)
180 { 175 {
181 foreach (signal; T.signals) 176 foreach (signal; T.signals)
194 } 189 }
195 } 190 }
196 } 191 }
197 } 192 }
198 193
199 // new 194 /* internal */ alias createImpl!This create;
200 static This create(T : QObject)(void* nativeId) 195
201 { 196 /**
202 auto m = new This(); 197 */
203 m.construct!T(nativeId); 198 @property
204 return m; 199 override This base()
205 } 200 {
206 201 return super.base;
207 /++ 202 }
208 +/ 203
209 QMetaObject base() 204 /**
210 { 205 */
211 return _base; 206 @property
212 } 207 override This firstDerived()
213 208 {
214 /++ 209 return super.firstDerived;
215 +/ 210 }
216 QMetaObjectNative* nativeId() 211
217 { 212 /**
218 return _nativeId; 213 */
219 } 214 @property
220 215 override This next()
221 /++ 216 {
222 +/ 217 return super.next;
223 ClassInfo classInfo() 218 }
224 { 219
225 return _classInfo; 220 /**
226 } 221 */
227 222 @property
223 override QMetaObjectNative* nativeId()
224 {
225 return cast(QMetaObjectNative*)super.nativeId;
226 }
227
228 @property
228 const (QMetaMethod[]) methods() 229 const (QMetaMethod[]) methods()
229 { 230 {
230 return _methods; 231 return _methods;
231 } 232 }
232 233
238 QMetaMethod lookUpMethod(string slot) 239 QMetaMethod lookUpMethod(string slot)
239 { 240 {
240 foreach (method; _methods) 241 foreach (method; _methods)
241 if (method.signature == slot) 242 if (method.signature == slot)
242 return method; 243 return method;
243 if (_base) 244 if (base)
244 return _base.lookUpMethod(slot); 245 return base.lookUpMethod(slot);
245 else 246 else
246 return null; 247 return null;
247 } 248 }
248 249
249 QMetaSignal lookUpSignal(string signal) 250 QMetaSignal lookUpSignal(string signal)
250 { 251 {
251 foreach (method; _methods) 252 foreach (method; _methods)
252 if (method.signature == signal && cast(QMetaSignal)method) 253 if (method.signature == signal && cast(QMetaSignal)method)
253 return cast(QMetaSignal)method; 254 return cast(QMetaSignal)method;
254 if (_base) 255 if (base)
255 return _base.lookUpSignal(signal); 256 return base.lookUpSignal(signal);
256 else 257 else
257 return null; 258 return null;
258 } 259 }
259 260
260 QMetaMethod[] lookUpMethodOverloads(string methodName) 261 QMetaMethod[] lookUpMethodOverloads(string methodName)
261 { 262 {
262 typeof(return) result; 263 typeof(return) result;
263 foreach (method; _methods) 264 foreach (method; _methods)
264 if (method.name == methodName) 265 if (method.name == methodName)
265 result ~= method; 266 result ~= method;
266 if (_base) 267 if (base)
267 result ~= _base.lookUpMethodOverloads(methodName); 268 result ~= base.lookUpMethodOverloads(methodName);
268 return result; 269 return result;
269 } 270 }
270 271
271 QMetaSignal[] lookUpSignalOverloads(string signalName) 272 QMetaSignal[] lookUpSignalOverloads(string signalName)
272 { 273 {
273 typeof(return) result; 274 typeof(return) result;
274 foreach (method; _methods) 275 foreach (method; _methods)
275 if (method.name == signalName && cast(QMetaSignal)method) 276 if (method.name == signalName && cast(QMetaSignal)method)
276 result ~= cast(QMetaSignal)method; 277 result ~= cast(QMetaSignal)method;
277 if (_base) 278 if (base)
278 result ~= _base.lookUpSignalOverloads(signalName); 279 result ~= base.lookUpSignalOverloads(signalName);
279 return result; 280 return result;
280 } 281 }
281 282
282 private QMetaObject lookupDerived(void*[] moIds) 283 private QMetaObject lookupDerived(void*[] moIds)
283 { 284 {
284 assert (moIds.length >= 1); 285 assert (moIds.length >= 1);
285 286
286 for (auto mo = _firstDerived; mo !is null; mo = mo._next) 287 for (auto mo = firstDerived; mo !is null; mo = mo.next)
287 { 288 {
288 if (mo._nativeId == moIds[0]) 289 if (mo.nativeId == moIds[0])
289 { 290 {
290 if (moIds.length == 1) // exact match found 291 if (moIds.length == 1) // exact match found
291 return mo; 292 return mo;
292 else // look deeper 293 else // look deeper
293 return mo.lookupDerived(moIds[1..$]); 294 return mo.lookupDerived(moIds[1..$]);
306 if (nativeObjId) 307 if (nativeObjId)
307 { 308 {
308 result = cast(QObject)qtd_get_d_qobject(nativeObjId); 309 result = cast(QObject)qtd_get_d_qobject(nativeObjId);
309 if (!result) 310 if (!result)
310 { 311 {
312 auto nId = nativeId;
311 auto moId = qtd_QObject_metaObject(nativeObjId); 313 auto moId = qtd_QObject_metaObject(nativeObjId);
312 if (_nativeId == moId) 314 if (nId == moId)
313 result = _createWrapper(nativeObjId); 315 result = _createWrapper(nativeObjId);
314 else 316 else
315 { 317 {
316 // get native metaobjects for the entire derivation lattice 318 // get native metaobjects for the entire derivation lattice
317 // up to, but not including, the current metaobject. 319 // up to, but not including, the current metaobject.
319 321
320 for (void* tmp = moId;;) 322 for (void* tmp = moId;;)
321 { 323 {
322 tmp = qtd_QMetaObject_superClass(tmp); 324 tmp = qtd_QMetaObject_superClass(tmp);
323 assert(tmp); 325 assert(tmp);
324 if (tmp == _nativeId) 326 if (tmp == nId)
325 break; 327 break;
326 moCount++; 328 moCount++;
327 } 329 }
328 330
329 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; 331 void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount];
357 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types); 359 return qtd_QMetaObject_connect(sender.__nativeId, signal_index, receiver.__nativeId, method_index, type, types);
358 } 360 }
359 361
360 int indexOfMethod_Cpp(string method) 362 int indexOfMethod_Cpp(string method)
361 { 363 {
362 return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); 364 return qtd_QMetaObject_indexOfMethod(nativeId, toStringz(method));
363 } 365 }
364 366
365 int methodCount() 367 int methodCount()
366 { 368 {
367 return qtd_QMetaObject_methodCount(_nativeId); 369 return qtd_QMetaObject_methodCount(nativeId);
368 } 370 }
369 371
370 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type) 372 static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type)
371 { 373 {
372 QMetaSignal[] signals; 374 QMetaSignal[] signals;