Mercurial > projects > qtd
view qt/core/QMetaObject.d @ 248:7664de4a55e5
Fixed #23.
QtD_QObjectEntity is not created dynamically for shell classes any more.
Class initialization is now performed by static constructors.
When wrapping QObjects returned from functions, their run-time types are now taken into account.
QObjects are allocated on GC heap, a doubly-linked list is used to prevent them from been collected (arguably a better solution than allocating on C heap and adding GC ranges)
Minor changes (including unnecessary).
author | maxter |
---|---|
date | Thu, 20 Aug 2009 14:47:17 +0000 |
parents | |
children |
line wrap: on
line source
module qt.core.QMetaObject; import qt.QGlobal; import qt.core.QObject; import qt.QtdObject; final class QMetaObject { private { void* _nativeId; QMetaObject _base; // super class QMetaObject _firstDerived; // head of the linked list of derived classes QMetaObject _next; // next sibling on this derivation level ClassInfo _classInfo; QObject function(void* nativeId) _createWrapper; } private void addDerived(QMetaObject mo) { mo._next = _firstDerived; _firstDerived = mo; } // NOTE: construction is split between this non-templated constructor and 'construct' function below. this(void* nativeId, QMetaObject base) { _nativeId = nativeId; if (base) { base.addDerived(this); _base = base; } } // TODO: remove when D acquires templated constructors void construct(T : QObject, Concrete = T)() { _classInfo = T.classinfo; static QObject createWrapper(void* nativeId) { T obj = new Concrete(nativeId, QtdObjectFlags.nativeOwnership); // TODO: this probably should be moved to QObject constructor qtd_create_qobject_entity(nativeId, cast(void*)obj); return obj; } _createWrapper = &createWrapper; } /++ +/ QMetaObject base() { return _base; } /++ +/ void* nativeId() { return _nativeId; } /++ +/ ClassInfo classInfo() { return _classInfo; } private QObject lookupDerived(void*[] moIds, void* nativeObjId) { assert (moIds.length >= 1); for (auto mo = _firstDerived; mo !is null; mo = mo._next) { if (mo._nativeId == moIds[0]) { if (moIds.length == 1) // exact match found return mo._createWrapper(nativeObjId); else // look deeper return mo.lookupDerived(moIds[1..$], nativeObjId); } } // no initialized wrapper that matches the native object. // use the base class wrapper return _createWrapper(nativeObjId); } QObject getObject(void* nativeObjId) { QObject result; if (nativeObjId) { result = cast(QObject)qtd_get_d_qobject(nativeObjId); if (!result) { auto moId = qtd_QObject_metaObject(nativeObjId); if (_nativeId == moId) result = _createWrapper(nativeObjId); else { // get native metaobjects for the entire derivation lattice // up to, but not including, the current metaobject. size_t moCount = 1; for (void* tmp = moId;;) { tmp = qtd_QMetaObject_superClass(tmp); assert(tmp); if (tmp == _nativeId) break; moCount++; } void*[] moIds = (cast(void**)alloca(moCount * (void*).sizeof))[0..moCount]; moIds[--moCount] = moId; while (moCount > 0) moIds[--moCount] = moId = qtd_QMetaObject_superClass(moId); result = lookupDerived(moIds, nativeObjId); } } } return result; } } extern(C) void* qtd_QMetaObject_superClass(void* nativeId);