Mercurial > projects > qtd
changeset 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 | 3b0545d4d479 |
children | 958e8b9a89bd |
files | d2/qt/core/QMetaObject.d d2/qtd/MOC.d d2/qtd/meta/Compiletime.d d2/qtd/meta/Runtime.d generator/dgenerator.cpp generator/typesystem_core-java.java |
diffstat | 6 files changed, 199 insertions(+), 163 deletions(-) [+] |
line wrap: on
line diff
--- a/d2/qt/core/QMetaObject.d Thu Jun 10 00:57:32 2010 +0300 +++ b/d2/qt/core/QMetaObject.d Fri Jun 11 12:16:09 2010 +0300 @@ -13,11 +13,11 @@ std.typetuple, std.c.stdlib; -class QMetaArgument : Meta +class QMetaArgument : MetaBase { } -class QMetaMethod : Meta +class QMetaMethod : MetaBase { alias typeof(this) This; @@ -84,9 +84,31 @@ } } -class MetaObject : MetaType +/** + Base class for QtD meta-classes. + */ +abstract class QtdMetaClass : MetaClass { - MetaObject _base; +private: + void* nativeId_; + + this() {} + +public: + + /** + */ + @property + void* nativeId() + { + return nativeId_; + } + + /* internal */ void construct(T)() + { + super.construct!T(); + nativeId_ = T.qtd_nativeMetaObject; + } } struct QMetaObjectNative @@ -99,12 +121,10 @@ class QMetaException : Exception { this(string msg) { super(msg); } } -final class QMetaObject +final class QMetaObject : QtdMetaClass { alias typeof(this) This; - private this() {} - enum Call { InvokeMetaMethod, @@ -121,40 +141,13 @@ private { - QMetaObjectNative* _nativeId; - QMetaObject _base; // super class - QMetaObject _firstDerived; // head of the linked list of derived classes - QMetaObject _next; // next sibling on this derivation level QMetaMethod[] _methods; - ClassInfo _classInfo; - QObject function(void* nativeId) _createWrapper; } - private void addDerived(QMetaObject mo) - { - mo._next = _firstDerived; - _firstDerived = mo; - } - - // ctor - void construct(T : QObject)(void* nativeId) + void construct(T : QObject)() { - alias BaseClassesTuple!(T)[0] Base; - This base; - static if (is(Base : QObject)) - base = Base.staticMetaObject; - - _nativeId = cast(QMetaObjectNative*)nativeId; - T.setStaticMetaObject(this); - - if (base) - { - base.addDerived(this); - _base = base; - } - _classInfo = T.classinfo; - + super.construct!T(); static if (isQtType!T) { @@ -171,9 +164,11 @@ T._populateMetaInfo; } + // create run time meta-objects for user-defined signals and slots else static if (is(typeof(T.methods))) { + alias BaseClassesTuple!(T)[0] Base; int index = Base.staticMetaObject().methodCount(); static if (T.signals.length) @@ -196,35 +191,41 @@ } } - // new - static This create(T : QObject)(void* nativeId) + /* internal */ alias createImpl!This create; + + /** + */ + @property + override This base() { - auto m = new This(); - m.construct!T(nativeId); - return m; + return super.base; } - /++ - +/ - QMetaObject base() + /** + */ + @property + override This firstDerived() { - return _base; + return super.firstDerived; } - /++ - +/ - QMetaObjectNative* nativeId() + /** + */ + @property + override This next() { - return _nativeId; + return super.next; } - /++ - +/ - ClassInfo classInfo() + /** + */ + @property + override QMetaObjectNative* nativeId() { - return _classInfo; + return cast(QMetaObjectNative*)super.nativeId; } + @property const (QMetaMethod[]) methods() { return _methods; @@ -240,8 +241,8 @@ foreach (method; _methods) if (method.signature == slot) return method; - if (_base) - return _base.lookUpMethod(slot); + if (base) + return base.lookUpMethod(slot); else return null; } @@ -251,8 +252,8 @@ foreach (method; _methods) if (method.signature == signal && cast(QMetaSignal)method) return cast(QMetaSignal)method; - if (_base) - return _base.lookUpSignal(signal); + if (base) + return base.lookUpSignal(signal); else return null; } @@ -263,8 +264,8 @@ foreach (method; _methods) if (method.name == methodName) result ~= method; - if (_base) - result ~= _base.lookUpMethodOverloads(methodName); + if (base) + result ~= base.lookUpMethodOverloads(methodName); return result; } @@ -274,8 +275,8 @@ foreach (method; _methods) if (method.name == signalName && cast(QMetaSignal)method) result ~= cast(QMetaSignal)method; - if (_base) - result ~= _base.lookUpSignalOverloads(signalName); + if (base) + result ~= base.lookUpSignalOverloads(signalName); return result; } @@ -283,9 +284,9 @@ { assert (moIds.length >= 1); - for (auto mo = _firstDerived; mo !is null; mo = mo._next) + for (auto mo = firstDerived; mo !is null; mo = mo.next) { - if (mo._nativeId == moIds[0]) + if (mo.nativeId == moIds[0]) { if (moIds.length == 1) // exact match found return mo; @@ -308,8 +309,9 @@ result = cast(QObject)qtd_get_d_qobject(nativeObjId); if (!result) { + auto nId = nativeId; auto moId = qtd_QObject_metaObject(nativeObjId); - if (_nativeId == moId) + if (nId == moId) result = _createWrapper(nativeObjId); else { @@ -321,7 +323,7 @@ { tmp = qtd_QMetaObject_superClass(tmp); assert(tmp); - if (tmp == _nativeId) + if (tmp == nId) break; moCount++; } @@ -359,12 +361,12 @@ int indexOfMethod_Cpp(string method) { - return qtd_QMetaObject_indexOfMethod(_nativeId, toStringz(method)); + return qtd_QMetaObject_indexOfMethod(nativeId, toStringz(method)); } int methodCount() { - return qtd_QMetaObject_methodCount(_nativeId); + return qtd_QMetaObject_methodCount(nativeId); } static void connectImpl(QObject sender, string signalString, QObject receiver, string methodString, int type)
--- a/d2/qtd/MOC.d Thu Jun 10 00:57:32 2010 +0300 +++ b/d2/qtd/MOC.d Fri Jun 11 12:16:09 2010 +0300 @@ -490,10 +490,12 @@ mixin template Q_OBJECT() { - import std.typetuple; - import qtd.Marshal; - import std.stdio; - import qt.core.QString; // for QStringUtil.toNative + import + std.typetuple, + qtd.meta.Runtime, + qtd.Marshal, + qt.core.QString, + std.stdio; public: // required to override the outside scope protection. @@ -530,43 +532,24 @@ @property override QMetaObject metaObject() const { return staticMetaObject(); } - private static - { - __gshared QMetaObject staticMetaObject_; - __gshared QMetaObjectNative nativeStaticMetaObject_; - bool staticMoInited_; - } - @property static QMetaObject staticMetaObject() { - // using a thread-local flag to mitigate - // the performance hit caused by lazy initialization - if(!staticMoInited_) - { - synchronized(qtdMoLock) - { - if (!staticMetaObject_) - { - alias BaseClassesTuple!(This)[0] Base; - - nativeStaticMetaObject_ = QMetaObjectNative( - Base.staticMetaObject.nativeId, - qt_meta_stringdata.ptr, - qt_meta_data.ptr, null); - - QMetaObject.create!This(&nativeStaticMetaObject_); - } - } - staticMoInited_ = true; - } - - return staticMetaObject_; + return meta!This; } - /*internal*/ static void setStaticMetaObject(QMetaObject m) + @property static void* qtd_nativeMetaObject() { - staticMetaObject_ = m; + __gshared static QMetaObjectNative nativeMo; + if (!nativeMo.data) + { + alias BaseClassesTuple!(This)[0] Base; + nativeMo = QMetaObjectNative( + Base.staticMetaObject.nativeId, + qt_meta_stringdata.ptr, + qt_meta_data.ptr, null); + } + return &nativeMo; } }
--- a/d2/qtd/meta/Compiletime.d Thu Jun 10 00:57:32 2010 +0300 +++ b/d2/qtd/meta/Compiletime.d Fri Jun 11 12:16:09 2010 +0300 @@ -6,11 +6,12 @@ module qtd.meta.Compiletime; import - std.traits, std.conv, std.variant, std.typetuple; +public import std.traits; + import std.string : startsWith; /**
--- a/d2/qtd/meta/Runtime.d Thu Jun 10 00:57:32 2010 +0300 +++ b/d2/qtd/meta/Runtime.d Fri Jun 11 12:16:09 2010 +0300 @@ -8,6 +8,7 @@ //and leave switch dispatch only in C interface import + qtd.Core, qtd.meta.Compiletime, std.typetuple, @@ -87,13 +88,13 @@ } } -abstract class Meta +abstract class MetaBase { alias typeof(this) This; string name; MetaAttribute[] attributes; - Meta[] members; + MetaBase[] members; template createImpl(M : This) { @@ -153,7 +154,7 @@ } } -abstract class MetaType : Meta +abstract class MetaType : MetaBase { } @@ -164,7 +165,63 @@ class MetaClass : MetaAggregate { alias typeof(this) This; - alias createImpl!This create; + +private: + This base_; + This firstDerived_; + This next_; + TypeInfo_Class classInfo_; + + this() {} + +public: + /** + Returns the meta-object of the base class. + */ + @property + This base() + { + return base_; + } + + /** + Returns next meta-object on this level of the derivation hierarchy. + */ + @property + This next() + { + return next_; + } + + /** + Returns meta-object of the first derived class. + */ + @property + This firstDerived() + { + return firstDerived_; + } + + /** + D class info. + */ + @property + TypeInfo_Class classInfo() + { + return classInfo_; + } + + /* internal */ alias createImpl!This create; + + /* internal */ void construct(T : Object)() + { + static if (!is(T == Object)) + { + alias BaseClassesTuple!(T)[0] Base; + base_ = meta!Base; + } + classInfo_ = T.classinfo; + } } class MetaStruct : MetaAggregate @@ -174,24 +231,21 @@ } @property -auto meta(alias symbol, M : Meta)() +auto meta(alias symbol, M : MetaBase)() { - __gshared static M m; + __gshared static M sharedM; + static M m; + if (!m) { - lock.reader.lock; - scope(exit) - lock.reader.unlock; - if (m) - return m; + synchronized(qtdMoLock) + { + if (!sharedM) + sharedM = M.create!symbol; + } + m = sharedM; } - lock.writer.lock; - scope(exit) - lock.writer.unlock; - - if (!m) - m = M.create!symbol; return m; } @@ -199,8 +253,8 @@ @property auto meta(T)() { - static if (is(typeof(T.staticMetaObject))) - return T.staticMetaObject; + static if (is(T.Meta)) // If the type defines a meta-class - use that. + return meta!(T, T.Meta); else static if (is(T == class)) return meta!(T, MetaClass); else static if (is(T == struct))
--- a/generator/dgenerator.cpp Thu Jun 10 00:57:32 2010 +0300 +++ b/generator/dgenerator.cpp Fri Jun 11 12:16:09 2010 +0300 @@ -1958,8 +1958,9 @@ if (d_class->isQObject()) { s << "public import qtd.Signal;" << endl << "public import qtd.MOC;" << endl - << "public import qtd.Traits;" << endl - << "public import qt.core.QMetaObject;" << endl; + << "public import qtd.Traits;" << endl + << "public import qt.core.QMetaObject;" << endl + << "import qtd.meta.Runtime;" << endl; if (d_class->name() != "QObject") s << "public import qt.core.QObject;" << endl; @@ -2568,11 +2569,6 @@ if (d_class->typeEntry()->isValue()) s << INDENT << d_class->name() << ".QTypeInfo.init();" << endl; - if (d_class->isQObject()) { - // ensure meta-object is created at static construction - s << INDENT << d_class->name() << ".staticMetaObject();" << endl; - } - if (cpp_shared && d_class->generateShellClass()) { AbstractMetaFunction::Options opts(AbstractMetaFunction::DeclaringClass | AbstractMetaFunction::NoExternNamespace); @@ -2694,7 +2690,7 @@ void DGenerator::writeQObjectFreeFunctions(QTextStream &s, const AbstractMetaClass *d_class) { - s << "extern(C) QMetaObjectNative* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl + s << "extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl << "extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl << "extern(C) int qtd_" << d_class->name() << "_qt_metacall(void *nativeId, QMetaObject.Call _c, int _id, void **_a);" << endl; @@ -2761,31 +2757,29 @@ << " }" << endl << endl; } - s << " private static __gshared QMetaObject staticMetaObject_;" << endl - << " protected static void setStaticMetaObject(QMetaObject m) {" << endl - << " staticMetaObject_ = m;" << endl - << " }" << endl << endl + s << " @property static void* qtd_nativeMetaObject() {" << endl + << " return qtd_" << d_class->name() << "_staticMetaObject();" << endl + << " }" << " @property QMetaObject metaObject() {" << endl - << " return staticMetaObject_;" << endl + << " return staticMetaObject;" << endl << " }" << endl << endl << " @property static QMetaObject staticMetaObject() {" << endl - << " if (!staticMetaObject_)" << endl - << " QMetaObject.create!(typeof(this))(qtd_" << d_class->name() << "_staticMetaObject());" << endl - << " return staticMetaObject_;" << endl + << " return meta!(typeof(this));" << endl << " }" << endl << endl << " static " << d_class->name() << " __getObject(void* nativeId) {" << endl - << " return static_cast!(" << d_class->name() << ")(staticMetaObject_.getObject(nativeId));" << endl + << " return static_cast!(" << d_class->name() << ")(staticMetaObject.getObject(nativeId));" << endl << " }" << endl << endl - << " /* internal */ static void __createEntity(void* nativeId, void* dId) {" << endl + << " static void __createEntity(void* nativeId, void* dId) {" << endl << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl << " }" << endl << endl - << " /* internal */ static void _populateMetaInfo() {" << endl - << " int index;" << endl << endl; + << " static void _populateMetaInfo() {" << endl + << " int index;" << endl + << " auto mo = staticMetaObject;" << endl << endl; AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false); @@ -2797,8 +2791,8 @@ do // need this to look for default arguments and generate extra signatures { AbstractMetaFunction *fn = signal_funcs.at(i); - s << " index = staticMetaObject_.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl - << " staticMetaObject_.addMethod(new QMetaSignal(signature!("; + s << " index = mo.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl + << " mo.addMethod(new QMetaSignal(signature!("; writeMetaMethodArguments(s, fn, j); s << ")(\"" << fn->name() << "\"), index));" << endl << endl; AbstractMetaArgumentList args = fn->arguments(); @@ -2819,8 +2813,8 @@ do // need this to look for default arguments and generate extra signatures { AbstractMetaFunction *fn = slot_funcs.at(i); - s << " index = staticMetaObject_.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl - << " staticMetaObject_.addMethod(new QMetaSlot(signature!("; + s << " index = mo.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl + << " mo.addMethod(new QMetaSlot(signature!("; writeMetaMethodArguments(s, fn, j); s << ")(\"" << fn->name() << "\"), index));" << endl << endl; AbstractMetaArgumentList args = fn->arguments();
--- a/generator/typesystem_core-java.java Thu Jun 10 00:57:32 2010 +0300 +++ b/generator/typesystem_core-java.java Fri Jun 11 12:16:09 2010 +0300 @@ -45,10 +45,12 @@ import qt.core.*; class QObject___ extends QObject { - + + alias QMetaObject Meta; + /* TODO: test whether the linked list is really a better solution public bool __stackAllocated = false; - + new(size_t size, void* p = null) { if (!p) @@ -72,23 +74,23 @@ } } */ - + private { static QObject __root; QObject __next; QObject __prev; } -/* +/* override void onSignalHandlerCreated(ref SignalHandler sh) { sh.signalEvent = &onSignalEvent; } - + private void onSignalEvent(int signalId, SignalEventId event) { stringz signature; - signalSignature(signalId, signature); + signalSignature(signalId, signature); if (signature) { switch (event) @@ -111,11 +113,11 @@ __prev.__next = __next; else __root = __next; - - if (__next) - __next.__prev = __prev; + + if (__next) + __next.__prev = __prev; } - + /** */ T findChild(T : QObject = QObject)(string name = null) @@ -125,23 +127,23 @@ auto tmp = cast(T)obj; if (tmp && (!name.length || tmp.objectName == name)) return tmp; - + tmp = obj.findChild!(T)(name); if (tmp) return tmp; } - + return null; } - + /** */ T[] findChildren(T : QObject = QObject)(string name = null) { T[] result; - + void find(QObject[] objects) - { + { foreach (obj; objects) { auto tmp = cast(T)obj; @@ -150,11 +152,11 @@ find(obj.children); } } - + find(children); return result; } - + static void connect(QObject sender, string signal, QObject receiver, string method, int type = 0) { QMetaObject.connectImpl(sender, signal, receiver, method, type);