# HG changeset patch # User Max Samukha # Date 1276276165 -10800 # Node ID 958e8b9a89bd2897eeaf60bf1ad5b601d07ad6dc # Parent a084e2df37761fe8a0aa8521840a47dd6b3c445a Changeset a084e2df3776 is broken. Backing out. diff -r a084e2df3776 -r 958e8b9a89bd d2/qt/core/QMetaObject.d --- a/d2/qt/core/QMetaObject.d Fri Jun 11 12:16:09 2010 +0300 +++ b/d2/qt/core/QMetaObject.d Fri Jun 11 20:09:25 2010 +0300 @@ -13,11 +13,11 @@ std.typetuple, std.c.stdlib; -class QMetaArgument : MetaBase +class QMetaArgument : Meta { } -class QMetaMethod : MetaBase +class QMetaMethod : Meta { alias typeof(this) This; @@ -84,31 +84,9 @@ } } -/** - Base class for QtD meta-classes. - */ -abstract class QtdMetaClass : MetaClass +class MetaObject : MetaType { -private: - void* nativeId_; - - this() {} - -public: - - /** - */ - @property - void* nativeId() - { - return nativeId_; - } - - /* internal */ void construct(T)() - { - super.construct!T(); - nativeId_ = T.qtd_nativeMetaObject; - } + MetaObject _base; } struct QMetaObjectNative @@ -121,10 +99,12 @@ class QMetaException : Exception { this(string msg) { super(msg); } } -final class QMetaObject : QtdMetaClass +final class QMetaObject { alias typeof(this) This; + private this() {} + enum Call { InvokeMetaMethod, @@ -141,13 +121,40 @@ 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; } - void construct(T : QObject)() + private void addDerived(QMetaObject mo) + { + mo._next = _firstDerived; + _firstDerived = mo; + } + + // ctor + void construct(T : QObject)(void* nativeId) { - super.construct!T(); + 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; + static if (isQtType!T) { @@ -164,11 +171,9 @@ 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) @@ -191,41 +196,35 @@ } } - /* internal */ alias createImpl!This create; - - /** - */ - @property - override This base() + // new + static This create(T : QObject)(void* nativeId) { - return super.base; + auto m = new This(); + m.construct!T(nativeId); + return m; } - /** - */ - @property - override This firstDerived() + /++ + +/ + QMetaObject base() { - return super.firstDerived; + return _base; } - /** - */ - @property - override This next() + /++ + +/ + QMetaObjectNative* nativeId() { - return super.next; + return _nativeId; } - /** - */ - @property - override QMetaObjectNative* nativeId() + /++ + +/ + ClassInfo classInfo() { - return cast(QMetaObjectNative*)super.nativeId; + return _classInfo; } - @property const (QMetaMethod[]) methods() { return _methods; @@ -241,8 +240,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; } @@ -252,8 +251,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; } @@ -264,8 +263,8 @@ foreach (method; _methods) if (method.name == methodName) result ~= method; - if (base) - result ~= base.lookUpMethodOverloads(methodName); + if (_base) + result ~= _base.lookUpMethodOverloads(methodName); return result; } @@ -275,8 +274,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; } @@ -284,9 +283,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; @@ -309,9 +308,8 @@ result = cast(QObject)qtd_get_d_qobject(nativeObjId); if (!result) { - auto nId = nativeId; auto moId = qtd_QObject_metaObject(nativeObjId); - if (nId == moId) + if (_nativeId == moId) result = _createWrapper(nativeObjId); else { @@ -323,7 +321,7 @@ { tmp = qtd_QMetaObject_superClass(tmp); assert(tmp); - if (tmp == nId) + if (tmp == _nativeId) break; moCount++; } @@ -361,12 +359,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) diff -r a084e2df3776 -r 958e8b9a89bd d2/qtd/MOC.d --- a/d2/qtd/MOC.d Fri Jun 11 12:16:09 2010 +0300 +++ b/d2/qtd/MOC.d Fri Jun 11 20:09:25 2010 +0300 @@ -490,12 +490,10 @@ mixin template Q_OBJECT() { - import - std.typetuple, - qtd.meta.Runtime, - qtd.Marshal, - qt.core.QString, - std.stdio; + import std.typetuple; + import qtd.Marshal; + import std.stdio; + import qt.core.QString; // for QStringUtil.toNative public: // required to override the outside scope protection. @@ -532,24 +530,43 @@ @property override QMetaObject metaObject() const { return staticMetaObject(); } + private static + { + __gshared QMetaObject staticMetaObject_; + __gshared QMetaObjectNative nativeStaticMetaObject_; + bool staticMoInited_; + } + @property static QMetaObject staticMetaObject() { - return meta!This; + // 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_; } - @property static void* qtd_nativeMetaObject() + /*internal*/ static void setStaticMetaObject(QMetaObject 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; + staticMetaObject_ = m; } } diff -r a084e2df3776 -r 958e8b9a89bd d2/qtd/meta/Compiletime.d --- a/d2/qtd/meta/Compiletime.d Fri Jun 11 12:16:09 2010 +0300 +++ b/d2/qtd/meta/Compiletime.d Fri Jun 11 20:09:25 2010 +0300 @@ -6,12 +6,11 @@ module qtd.meta.Compiletime; import + std.traits, std.conv, std.variant, std.typetuple; -public import std.traits; - import std.string : startsWith; /** diff -r a084e2df3776 -r 958e8b9a89bd d2/qtd/meta/Runtime.d --- a/d2/qtd/meta/Runtime.d Fri Jun 11 12:16:09 2010 +0300 +++ b/d2/qtd/meta/Runtime.d Fri Jun 11 20:09:25 2010 +0300 @@ -8,7 +8,6 @@ //and leave switch dispatch only in C interface import - qtd.Core, qtd.meta.Compiletime, std.typetuple, @@ -88,13 +87,13 @@ } } -abstract class MetaBase +abstract class Meta { alias typeof(this) This; string name; MetaAttribute[] attributes; - MetaBase[] members; + Meta[] members; template createImpl(M : This) { @@ -154,7 +153,7 @@ } } -abstract class MetaType : MetaBase +abstract class MetaType : Meta { } @@ -165,63 +164,7 @@ class MetaClass : MetaAggregate { alias typeof(this) This; - -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; - } + alias createImpl!This create; } class MetaStruct : MetaAggregate @@ -231,21 +174,24 @@ } @property -auto meta(alias symbol, M : MetaBase)() +auto meta(alias symbol, M : Meta)() { - __gshared static M sharedM; - static M m; + __gshared static M m; + + { + lock.reader.lock; + scope(exit) + lock.reader.unlock; + if (m) + return m; + } + + lock.writer.lock; + scope(exit) + lock.writer.unlock; if (!m) - { - synchronized(qtdMoLock) - { - if (!sharedM) - sharedM = M.create!symbol; - } - m = sharedM; - } - + m = M.create!symbol; return m; } @@ -253,8 +199,8 @@ @property auto meta(T)() { - static if (is(T.Meta)) // If the type defines a meta-class - use that. - return meta!(T, T.Meta); + static if (is(typeof(T.staticMetaObject))) + return T.staticMetaObject; else static if (is(T == class)) return meta!(T, MetaClass); else static if (is(T == struct)) diff -r a084e2df3776 -r 958e8b9a89bd generator/dgenerator.cpp --- a/generator/dgenerator.cpp Fri Jun 11 12:16:09 2010 +0300 +++ b/generator/dgenerator.cpp Fri Jun 11 20:09:25 2010 +0300 @@ -1958,9 +1958,8 @@ 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 - << "import qtd.meta.Runtime;" << endl; + << "public import qtd.Traits;" << endl + << "public import qt.core.QMetaObject;" << endl; if (d_class->name() != "QObject") s << "public import qt.core.QObject;" << endl; @@ -2569,6 +2568,11 @@ 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); @@ -2690,7 +2694,7 @@ void DGenerator::writeQObjectFreeFunctions(QTextStream &s, const AbstractMetaClass *d_class) { - s << "extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl + s << "extern(C) QMetaObjectNative* 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; @@ -2757,29 +2761,31 @@ << " }" << endl << endl; } - s << " @property static void* qtd_nativeMetaObject() {" << endl - << " return qtd_" << d_class->name() << "_staticMetaObject();" << endl - << " }" + s << " private static __gshared QMetaObject staticMetaObject_;" << endl + << " protected static void setStaticMetaObject(QMetaObject m) {" << endl + << " staticMetaObject_ = m;" << endl + << " }" << endl << endl << " @property QMetaObject metaObject() {" << endl - << " return staticMetaObject;" << endl + << " return staticMetaObject_;" << endl << " }" << endl << endl << " @property static QMetaObject staticMetaObject() {" << endl - << " return meta!(typeof(this));" << endl + << " if (!staticMetaObject_)" << endl + << " QMetaObject.create!(typeof(this))(qtd_" << d_class->name() << "_staticMetaObject());" << endl + << " return staticMetaObject_;" << 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 - << " static void __createEntity(void* nativeId, void* dId) {" << endl + << " /* internal */ static void __createEntity(void* nativeId, void* dId) {" << endl << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl << " }" << endl << endl - << " static void _populateMetaInfo() {" << endl - << " int index;" << endl - << " auto mo = staticMetaObject;" << endl << endl; + << " /* internal */ static void _populateMetaInfo() {" << endl + << " int index;" << endl << endl; AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false); @@ -2791,8 +2797,8 @@ do // need this to look for default arguments and generate extra signatures { AbstractMetaFunction *fn = signal_funcs.at(i); - s << " index = mo.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl - << " mo.addMethod(new QMetaSignal(signature!("; + s << " index = staticMetaObject_.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl + << " staticMetaObject_.addMethod(new QMetaSignal(signature!("; writeMetaMethodArguments(s, fn, j); s << ")(\"" << fn->name() << "\"), index));" << endl << endl; AbstractMetaArgumentList args = fn->arguments(); @@ -2813,8 +2819,8 @@ do // need this to look for default arguments and generate extra signatures { AbstractMetaFunction *fn = slot_funcs.at(i); - s << " index = mo.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl - << " mo.addMethod(new QMetaSlot(signature!("; + s << " index = staticMetaObject_.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl + << " staticMetaObject_.addMethod(new QMetaSlot(signature!("; writeMetaMethodArguments(s, fn, j); s << ")(\"" << fn->name() << "\"), index));" << endl << endl; AbstractMetaArgumentList args = fn->arguments(); diff -r a084e2df3776 -r 958e8b9a89bd generator/typesystem_core-java.java --- a/generator/typesystem_core-java.java Fri Jun 11 12:16:09 2010 +0300 +++ b/generator/typesystem_core-java.java Fri Jun 11 20:09:25 2010 +0300 @@ -45,12 +45,10 @@ 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) @@ -74,23 +72,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) @@ -113,11 +111,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) @@ -127,23 +125,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; @@ -152,11 +150,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);