Mercurial > projects > qtd
diff generator/cppimplgenerator.cpp @ 253:073b9153ed8a
Rev. 264 done right.
Problems:
- classwizard segfaults on exit due to a bug in signals/slots or runtime.
- hellogl doesn't compile with dmd2 due to a bug in the compiler backend
author | maxter |
---|---|
date | Sun, 30 Aug 2009 09:59:12 +0000 |
parents | 37eed70de029 |
children | 17b5e13364b7 49bfc86ff583 |
line wrap: on
line diff
--- a/generator/cppimplgenerator.cpp Sat Aug 22 12:50:58 2009 +0000 +++ b/generator/cppimplgenerator.cpp Sun Aug 30 09:59:12 2009 +0000 @@ -465,26 +465,6 @@ return !java_class->isQObject() && !java_class->typeEntry()->isValue(); } -void writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class) -{ -// if (!(java_class->typeEntry()->isObject() || java_class->typeEntry()->isQObject())) -// return; - if (!java_class->hasVirtualFunctions()) - return; - - s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl; - s << "{" << endl; - { - Indentation indent(INDENT); - s << INDENT << "Qtd_QObjectEntity* a = dynamic_cast<Qtd_QObjectEntity*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl - << INDENT << "if (a != NULL)" << endl - << INDENT << " return a->d_entity();" << endl - << INDENT << "else" << endl - << INDENT << " return NULL;" << endl; - } - s << "}" << endl << endl; -} - void CppImplGenerator::writeInterfaceCasts(QTextStream &s, const AbstractMetaClass *java_class) { // pointers to native interface objects for classes that implement interfaces @@ -532,11 +512,6 @@ s << " emit_callbacks_" << java_class->name() << "[" << i << "] = (EmitCallback)" "sigs[" << i << "];" << endl; - if (java_class->isQObject()) - s << " qtd_D_" << java_class->name() << "_delete = " - "(qtd_pf_D_" << java_class->name() << "_delete)qobj_del;" << endl; - - s << "}" << endl; } @@ -571,7 +546,13 @@ if (java_class->isQObject()) s << "#include <qtdynamicmetaobject.h>" << endl; */ + if (java_class->isQObject()) + s << "#include <QObjectEntity.h>" << endl; + s << "#include <iostream>" << endl; + + + Include inc = java_class->typeEntry()->include(); if (!inc.name.isEmpty()) { s << "#include "; @@ -608,7 +589,8 @@ writeDefaultConstructedValues(s, java_class); if (hasCustomDestructor(java_class)) */ - writeFinalDestructor(s, java_class); + if (!java_class->isQObject()) + writeFinalDestructor(s, java_class); if (java_class->isQObject()) writeSignalsHandling(s, java_class); @@ -620,7 +602,8 @@ } writeShellDestructor(s, java_class); - writeQtdEntityFunction(s, java_class); + if (!java_class->isQObject() && java_class->hasVirtualFunctions()) + writeQtdEntityFunction(s, java_class); if (java_class->isQObject()) writeQObjectFunctions(s, java_class); @@ -723,6 +706,14 @@ */ // qtd writeJavaLangObjectOverrideFunctions(s, java_class); + if (java_class->isQObject()) + { + s << endl << endl + << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_staticMetaObject() {" << endl + << " return (void*)&" << java_class->name() << "::staticMetaObject;" << endl + << "}" << endl; + } + s << endl << endl; priGenerator->addSource(java_class->package(), fileNameForClass(java_class)); @@ -838,7 +829,7 @@ } s << function->marshalledName() << "_dispatch(" - << "this->d_entity()"; + << "this->dId"; if (f_type) { if (f_type->isTargetLangString()) @@ -861,7 +852,7 @@ if (f_type->name() == "QModelIndex") { s << INDENT << "QModelIndex __qt_return_value = qtd_to_QModelIndex( __d_return_value );" << endl; #ifdef Q_OS_WIN32 -s << "__qtd_dummy();" << endl; // hack!!! +s << "qtd_dummy();" << endl; // hack!!! #endif s << INDENT << "return __qt_return_value;" << endl; } else if (f_type->typeEntry()->isStructInD()) @@ -1214,6 +1205,37 @@ } } +void CppImplGenerator::writeQObjectEntity(QTextStream &s, const AbstractMetaClass *java_class) +{ + QString entityName = java_class->name() + "Entity"; + QString className = java_class->name(); + + s << "class " << entityName << " : public QObject, public QtD_QObjectEntity" << endl + << "{" << endl + << "public:" << endl + << " Q_OBJECT_CHECK" << endl + << " virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl << endl + + << " " << entityName << "(QObject *qObject, void *dId) : QObject(), QtD_QObjectEntity(qObject, dId) {}" << endl + << "};" << endl << endl; + + // QObject_Link::qt_metacall() + s << "int " << entityName << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl + << "{" << endl + << " _id = QObject::qt_metacall(_c, _id, _a);" << endl + << " if (_id < 0 || _c != QMetaObject::InvokeMetaMethod)" << endl + << " return _id;" << endl +// << " Q_ASSERT(_id < 2);" << endl + << " emit_callbacks_" << java_class->name() << "[_id](dId, _a);" << endl + << " return -1;" << endl + << "}" << endl << endl; + + s << "extern \"C\" DLL_PUBLIC void qtd_" << className << "_createEntity(void *nativeId, void* dId)" << endl + << "{" << endl + << " new " << entityName << "((QObject*)nativeId, dId);" << endl + << "}" << endl << endl; +} + void CppImplGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class) { // QObject::metaObject() @@ -1257,21 +1279,16 @@ << " return " << java_class->qualifiedCppName() << "::qt_metacast(_clname);" << endl << "}" << endl << endl; */ - -// writeSignalsHandling(s, java_class); -/* - // QObject_Link::qt_metacall() + s << "int " << shellClassName(java_class) << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl << "{" << endl; - s << " _id = " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" << endl + s << " _id = " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" << endl << " if (_id < 0 || _c != QMetaObject::InvokeMetaMethod)" << endl - << " return _id;" << endl -// << " Q_ASSERT(_id < 2);" << endl - << " emit_callbacks_" << java_class->name() << "[_id](this->d_entity(), _a);" << endl + << " return _id;" << endl + << " emit_callbacks_" << java_class->name() << "[_id](this->dId, _a);" << endl << " return -1;" << endl << "}" << endl << endl; -*/ } void CppImplGenerator::writeSignalHandler(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunction *function) @@ -1316,65 +1333,6 @@ } -void CppImplGenerator::writeQObjectLink(QTextStream &s, const AbstractMetaClass *java_class) -{ - QString linkName = java_class->name() + "_Link"; - QString className = java_class->name(); - - if (cpp_shared) - s << "extern \"C\" typedef void (*qtd_pf_D_" << java_class->name() << "_delete)(void *d_ptr);" << endl - << "qtd_pf_D_" << java_class->name() << "_delete qtd_D_" << java_class->name() << "_delete;" << endl << endl; - else - s << "extern \"C\" void qtd_D_" << java_class->name() << "_delete(void *d_ptr);" << endl << endl; - - s << "class " << linkName << " : public QObject, public QObjectUserData" << endl - << "{" << endl - << "public:" << endl - << " Q_OBJECT_CHECK" << endl - << " virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl << endl - - << " " << linkName << "(QObject *parent, void *d_ptr) : QObject() { _d_ptr = d_ptr; }" << endl - << " ~" << linkName << "() { qtd_D_" << className << "_delete(_d_ptr); }" << endl - << " void *d_entity() const { return _d_ptr; }" << endl << endl - - << "private:" << endl - << " void *_d_ptr;" << endl - << "};" << endl << endl; - - // QObject_Link::qt_metacall() - s << "int " << linkName << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl - << "{" << endl - << " _id = QObject::qt_metacall(_c, _id, _a);" << endl - << " if (_id < 0 || _c != QMetaObject::InvokeMetaMethod)" << endl - << " return _id;" << endl -// << " Q_ASSERT(_id < 2);" << endl - << " emit_callbacks_" << java_class->name() << "[_id](this->d_entity(), _a);" << endl - << " return -1;" << endl - << "}" << endl << endl; - - s << QString("inline %1_Link *get_%1_link(%1 *obj)").arg(className) << endl - << "{" << endl - << " return static_cast<" << linkName << "*>(obj->userData(USER_DATA_ID));" << endl - << "}" << endl << endl; - - s << QString("extern \"C\" DLL_PUBLIC void* qtd_%1_d_pointer(%1 *obj)").arg(className) << endl - << "{" << endl - << " if (obj->userData(USER_DATA_ID)) {" << endl - << " " << QString("%1_Link *qobj_helper = get_%1_link(obj);").arg(className) << endl - << " return qobj_helper->d_entity();" << endl - << " } else" << endl - << " return NULL;" << endl - << "}" << endl << endl; - - s << QString("extern \"C\" DLL_PUBLIC void qtd_%1_create_link(%1 *obj, void* d_obj)").arg(className) << endl - << "{" << endl - << " if(obj->userData(USER_DATA_ID))" << endl - << " return;" << endl - << " " << QString("%1 *qobj_link = new %1(obj, d_obj);").arg(linkName) << endl - << " obj->setUserData(USER_DATA_ID, qobj_link);" << endl - << "}" << endl << endl; -} - void CppImplGenerator::writeSignalsHandling(QTextStream &s, const AbstractMetaClass *java_class) { s << "extern \"C\" typedef void (*EmitCallback)(void*, void**);" << endl; @@ -1406,31 +1364,7 @@ s << endl << "};" << endl << endl; } - writeQObjectLink(s, java_class); - - // Functions connecting/disconnecting shell's slots - for(int i = 0; i < signal_funcs.size(); i++) { - AbstractMetaFunction *signal = signal_funcs.at(i); - QString sigExternName = signalExternName(java_class, signal); - - s << "extern \"C\" DLL_PUBLIC void " << sigExternName << "_connect" - << "(void* native_id)" << endl << "{" << endl - << " " << shellClassName(java_class) << " *qobj = (" << shellClassName(java_class) << "*) native_id;" << endl - << " const QMetaObject &mo = " << java_class->name() << "::staticMetaObject;" << endl - << " const QMetaObject &mo2 = " << java_class->name() << "_Link::staticMetaObject;" << endl - << " int signalId = mo.indexOfSignal(\"" << signal->minimalSignature() << "\");" << endl - << " mo.connect(qobj, signalId, get_" << java_class->name() << "_link(qobj), mo2.methodCount() + " << i << ");" << endl - << "}" << endl; - - s << "extern \"C\" DLL_PUBLIC void " << sigExternName << "_disconnect" - << "(void* native_id)" << endl << "{" << endl - << " " << shellClassName(java_class) << " *qobj = (" << shellClassName(java_class) << "*) native_id;" << endl - << " const QMetaObject &mo = " << shellClassName(java_class) << "::staticMetaObject;" << endl - << " const QMetaObject &mo2 = " << java_class->name() << "_Link::staticMetaObject;" << endl - << " int signalId = mo.indexOfSignal(\"" << signal->minimalSignature() << "\");" << endl - << " mo.disconnect(qobj, signalId, get_" << java_class->name() << "_link(qobj), mo2.methodCount() + " << i << ");" << endl - << "}" << endl << endl; - } + writeQObjectEntity(s, java_class); } @@ -1452,8 +1386,10 @@ s << ", "; } s << ")"; - if (cls->hasVirtualFunctions()) - s << "," << endl << " Qtd_QObjectEntity(d_ptr)"; + if (cls->isQObject()) + s << "," << endl << " QtD_QObjectEntity(this, d_ptr)"; + else if (cls->hasVirtualFunctions()) + s << "," << endl << " QtD_Entity(d_ptr)"; /* qtd s << " m_meta_object(0)," << endl; s << " m_vtable(0)," << endl << " m_link(0)" << endl; @@ -1462,6 +1398,7 @@ s << "{" << endl; { Indentation indent(INDENT); + writeCodeInjections(s, java_function, cls, CodeSnip::Beginning, TypeSystem::ShellCode); writeCodeInjections(s, java_function, cls, CodeSnip::End, TypeSystem::ShellCode); } @@ -1474,35 +1411,9 @@ << shellClassName(java_class) << "()" << endl << "{" << endl; { -/* qtd - Indentation indent(INDENT); - - s << "#ifdef QT_DEBUG" << endl - << INDENT << "if (m_vtable)" << endl - << INDENT << " m_vtable->deref();" << endl - << "#endif" << endl - << INDENT << "if (m_link) {" << endl; - - AbstractMetaClassList interfaces = java_class->interfaces(); - if (interfaces.size() + (java_class->baseClass() != 0 ? 1 : 0) > 1) { - if (java_class->baseClass() != 0) - interfaces += java_class->baseClass(); - foreach (AbstractMetaClass *iface, interfaces) { - AbstractMetaClass *impl = iface->isInterface() ? iface->primaryInterfaceImplementor() : iface; - s << INDENT << " m_link->unregisterSubObject((" << impl->qualifiedCppName() << " *) this);" << endl; - } - } - - if (!java_class->isQObject()) { - s << INDENT << " JNIEnv *__jni_env = qtjambi_current_environment();" << endl - << INDENT << " if (__jni_env != 0) m_link->nativeShellObjectDestroyed(__jni_env);" << endl; - } - -#if defined(QTJAMBI_DEBUG_TOOLS) - s << INDENT << " qtjambi_increase_shellDestructorCalledCount(QString::fromLatin1(\"" << java_class->name() << "\"));" << endl; -#endif - - s << INDENT << "}" << endl; */ + //s << " std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;"; + if (java_class->isQObject()) + s << " destroyEntity(this);"; } s << "}" << endl << endl; } @@ -1818,6 +1729,20 @@ s << "}" << endl << endl; } +void CppImplGenerator::writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class) +{ + s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl; + s << "{" << endl; + { + Indentation indent(INDENT); + s << INDENT << "QtD_Entity* a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl + << INDENT << "if (a != NULL)" << endl + << INDENT << " return a->dId;" << endl + << INDENT << "else" << endl + << INDENT << " return NULL;" << endl; + } + s << "}" << endl << endl; +} void CppImplGenerator::writeVirtualFunctionOverride(QTextStream &s, const AbstractMetaFunction *java_function, @@ -2156,8 +2081,11 @@ function_prefix = "__override_"; extra_param.append("__do_static_call"); s << INDENT - << "bool __do_static_call = __this_nativeId ? " - << "__" << java_class->name() << "_entity(__this_nativeId) : false;" << endl; + << "bool __do_static_call = __this_nativeId ? "; + if (java_class->isQObject()) + s << "QtD_QObjectEntity::getQObjectEntity((QObject*)__this_nativeId) : false;" << endl; + else + s << "__" << java_class->name() << "_entity(__this_nativeId) : false;" << endl; } else { option = OriginalName; } @@ -2214,7 +2142,7 @@ AbstractMetaType *d_type = argument->type(); const TypeEntry *te = d_type->typeEntry(); if ((te && d_type->isNativePointer() && te->name() == "QString")) - s << QString(" _d_toUtf8(__qt_%1.utf16(), __qt_%1.size(), &%1);").arg(argument->indexedName()) << endl; + s << QString(" qtd_toUtf8(__qt_%1.utf16(), __qt_%1.size(), &%1);").arg(argument->indexedName()) << endl; } } @@ -2366,25 +2294,7 @@ s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl << INDENT << "{" << endl; { - Indentation indent(INDENT); -/* qtd - if (!cls->isQObject() && !cls->generateShellClass()) { - s << INDENT << "QtJambiLink *link = QtJambiLink::findLinkForUserObject(ptr);" << endl - << INDENT << "if (link) link->resetObject(qtjambi_current_environment());" << endl; - } - - // Code injectsions... - foreach (const CodeSnip &snip, cls->typeEntry()->codeSnips()) { - if (snip.language == TypeSystem::DestructorFunction) { - s << snip.code(); - } - } -*/ s << INDENT << "delete (" << shellClassName(cls) << " *)ptr;" << endl; - -#if defined(QTJAMBI_DEBUG_TOOLS) - s << INDENT << "qtjambi_increase_destructorFunctionCalledCount(QString::fromLatin1(\"" << cls->name() << "\"));" << endl; -#endif } s << INDENT << "}" << endl << endl; @@ -3080,13 +2990,13 @@ if(java_type->typeEntry()->qualifiedCppName() == "QStringRef") { s << INDENT << "const QString *str_ref = " << qt_name << ".string();" << endl << INDENT << "if(str_ref)" << endl - << INDENT << " _d_toUtf8(str_ref->utf16(), str_ref->size(), " << java_name << ");" << endl + << INDENT << " qtd_toUtf8(str_ref->utf16(), str_ref->size(), " << java_name << ");" << endl << INDENT << "else {" << endl << INDENT << " QString empty_str;" << endl - << INDENT << " _d_toUtf8(empty_str.utf16(), empty_str.size(), " << java_name << ");" << endl + << INDENT << " qtd_toUtf8(empty_str.utf16(), empty_str.size(), " << java_name << ");" << endl << INDENT << "}" << endl; } else { - s << INDENT << QString("_d_toUtf8(%1.utf16(), %1.size(), %2);").arg(qt_name, java_name) << endl; + s << INDENT << QString("qtd_toUtf8(%1.utf16(), %1.size(), %2);").arg(qt_name, java_name) << endl; } } else if (java_type->isTargetLangChar()) { s << INDENT << "jchar " << java_name << " = " << qt_name << ".unicode();" << endl;