# HG changeset patch # User maxter # Date 1250779637 0 # Node ID 7664de4a55e51e11f6d0a87ef23b444a62c8e6d4 # Parent 27497bbe62a126fcbc27bd4b3128770cd2e3ca2d 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). diff -r 27497bbe62a1 -r 7664de4a55e5 CMakeLists.txt --- a/CMakeLists.txt Fri Jul 31 11:05:22 2009 +0000 +++ b/CMakeLists.txt Thu Aug 20 14:47:17 2009 +0000 @@ -15,7 +15,7 @@ Please delete them. Or you can restart cmake with `-DALLOW_IN_SOURCE_BUILDS=1`, but it is not -recomended. +recommended. ") endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT ALLOW_IN_SOURCE_BUILDS) @@ -389,7 +389,11 @@ endforeach(d_source ${d_generated_files}) set(classes ArrayOps ${classes}) foreach(class ${classes}) - set(d_sources ${d_sources} ${CMAKE_BINARY_DIR}/qt/${package}/${class}.d) + set(d_sources ${d_sources} ${CMAKE_BINARY_DIR}/qt/${package}/${class}.d) + set(aux_name ${CMAKE_BINARY_DIR}/qt/${package}/${class}_aux.d ) + if(EXISTS ${aux_name}) + set(d_sources ${d_sources} ${aux_name}) + endif(EXISTS ${aux_name}) set(cpp_sources ${cpp_sources} ${CMAKE_BINARY_DIR}/cpp/qt_${package}/${class}_shell.cpp) endforeach(class ${classes}) set(files_for_gen ${files_for_gen} ${cpp_sources} ${d_sources}) @@ -417,7 +421,7 @@ set(regexp_str_tmp "(${ver_safe_tmp}/|${cbd_safe_tmp}/|${csd_safe_tmp}/|)(.+)") string(REGEX REPLACE ${regexp_str_tmp} "\\2" ins_path "${path}") install(FILES ${d_source} DESTINATION include/d/${ins_path} COMPONENT qtd RENAME ${name}.di) - install(FILES ${path}/${name}_enum.d DESTINATION include/d/${ins_path} COMPONENT qtd RENAME ${name}_enum.di OPTIONAL) + install(FILES ${path}/${name}_aux.d DESTINATION include/d/${ins_path} COMPONENT qtd RENAME ${name}_aux.di OPTIONAL) endforeach(d_source ${d_sources}) endif(NOT GENERATE_DI_FILES) diff -r 27497bbe62a1 -r 7664de4a55e5 build/core.makefile --- a/build/core.makefile Fri Jul 31 11:05:22 2009 +0000 +++ b/build/core.makefile Thu Aug 20 14:47:17 2009 +0000 @@ -5,7 +5,7 @@ endif ##-------------------------- -QTD_CORE += QGlobal $(D_PATH)/qtd/Str core/Qt qtd/ArrayOpsPrimitive $(D_PATH)/QtDObject $(D_PATH)/Signal \ +QTD_CORE += QGlobal $(D_PATH)/qtd/Str core/Qt qtd/ArrayOpsPrimitive $(D_PATH)/QtdObject $(D_PATH)/Signal \ $(D_PATH)/core/QPoint \ $(D_PATH)/core/QPointF \ $(D_PATH)/core/QRect \ diff -r 27497bbe62a1 -r 7664de4a55e5 build/core.txt --- a/build/core.txt Fri Jul 31 11:05:22 2009 +0000 +++ b/build/core.txt Thu Aug 20 14:47:17 2009 +0000 @@ -7,13 +7,19 @@ qt_core/QLine_shell qt_core/QLineF_shell qt_core/QRect_shell qt_core/QRectF_shell qt_core/QString_shell qt_core/QVariant_shell - qt_core/QModelIndex_shell qt_core/QMetaType_shell) + qt_core/QModelIndex_shell qt_core/QMetaType_shell + qt_core/QMetaObject_shell) ## Module specific d files. -set (d_files QGlobal qtd/Array +set (d_files + QGlobal + qtd/Array qtd/ArrayOpsPrimitive - core/QString core/QMetaType) + qtd/Traits + core/QString + core/QMetaType + core/QMetaObject) set (d_version_files - QtDObject + QtdObject Signal qtd/Str core/QLine core/QLineF core/QModelIndex diff -r 27497bbe62a1 -r 7664de4a55e5 cpp/qt_core/QVariant_shell.cpp --- a/cpp/qt_core/QVariant_shell.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/cpp/qt_core/QVariant_shell.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -857,7 +857,7 @@ QVariant_QtDShell *__qt_this = (QVariant_QtDShell *) __this_nativeId; QString __qt_return_value = __qt_this->toString(); - _d_toUtf8(__qt_return_value.utf16(), __qt_return_value.size(), __java_return_value); + qtd_toUtf8(__qt_return_value.utf16(), __qt_return_value.size(), __java_return_value); } diff -r 27497bbe62a1 -r 7664de4a55e5 cpp/qt_gui/UrlHandler_shell.cpp --- a/cpp/qt_gui/UrlHandler_shell.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/cpp/qt_gui/UrlHandler_shell.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -4,19 +4,19 @@ UrlHandler::UrlHandler(void *d_ptr, QObject* parent0) : QObject(parent0), - Qtd_QObjectEntity(d_ptr) + QtD_QObjectEntity(this, d_ptr) { } #ifdef CPP_SHARED -extern "C" typedef void (*pfqtd_UrlHandler_handleUrl_QUrl_dispatch)(void *d_entity, void* arg__1); +extern "C" typedef void (*pfqtd_UrlHandler_handleUrl_QUrl_dispatch)(void *dId, void* arg__1); pfqtd_UrlHandler_handleUrl_QUrl_dispatch qtd_UrlHandler_handleUrl_QUrl_dispatch; #else -extern "C" void qtd_UrlHandler_handleUrl_QUrl_dispatch(void *d_entity, void* name1); +extern "C" void qtd_UrlHandler_handleUrl_QUrl_dispatch(void *dId, void* name1); #endif void UrlHandler::handleUrl(const QUrl &url) { - qtd_UrlHandler_handleUrl_QUrl_dispatch(this->d_entity(), &(QUrl& )url); + qtd_UrlHandler_handleUrl_QUrl_dispatch(this->dId, &(QUrl& )url); } extern "C" DLL_PUBLIC void qtd_UrlHandler_destructor(void *ptr) diff -r 27497bbe62a1 -r 7664de4a55e5 cpp/qt_gui/UrlHandler_shell.h --- a/cpp/qt_gui/UrlHandler_shell.h Fri Jul 31 11:05:22 2009 +0000 +++ b/cpp/qt_gui/UrlHandler_shell.h Thu Aug 20 14:47:17 2009 +0000 @@ -1,7 +1,7 @@ #include #include -class UrlHandler : public QObject, public Qtd_QObjectEntity +class UrlHandler : public QObject, public QtD_QObjectEntity { Q_OBJECT diff -r 27497bbe62a1 -r 7664de4a55e5 cpp/qt_qtd/ArrayOpsPrimitive_shell.cpp --- a/cpp/qt_qtd/ArrayOpsPrimitive_shell.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/cpp/qt_qtd/ArrayOpsPrimitive_shell.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -37,15 +37,15 @@ QTD_EXPORT_VAR_SET(qtd_allocate_int_array, callbacks[0]); QTD_EXPORT_VAR_SET(qtd_assign_int_array_element, callbacks[1]); QTD_EXPORT_VAR_SET(qtd_get_int_from_array, callbacks[2]); - + QTD_EXPORT_VAR_SET(qtd_allocate_uint_array, callbacks[3]); QTD_EXPORT_VAR_SET(qtd_assign_uint_array_element, callbacks[4]); QTD_EXPORT_VAR_SET(qtd_get_uint_from_array, callbacks[5]); - + QTD_EXPORT_VAR_SET(qtd_allocate_double_array, callbacks[6]); QTD_EXPORT_VAR_SET(qtd_assign_double_array_element, callbacks[7]); QTD_EXPORT_VAR_SET(qtd_get_double_from_array, callbacks[8]); - + QTD_EXPORT_VAR_SET(qtd_allocate_string_array, callbacks[9]); QTD_EXPORT_VAR_SET(qtd_assign_string_array_element, callbacks[10]); QTD_EXPORT_VAR_SET(qtd_string_from_array, callbacks[11]); diff -r 27497bbe62a1 -r 7664de4a55e5 cpp/qt_qtd/qtd_core.cpp --- a/cpp/qt_qtd/qtd_core.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/cpp/qt_qtd/qtd_core.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -40,13 +40,13 @@ } #ifdef CPP_SHARED -QTD_EXPORT_VAR(_d_toUtf8) -QTD_EXPORT_VAR(__qtd_dummy) +QTD_EXPORT_VAR(qtd_toUtf8); +QTD_EXPORT_VAR(qtd_dummy); -extern "C" DLL_PUBLIC void __qtd_qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr dummy) { - QTD_EXPORT_VAR_SET(_d_toUtf8, d_func); - QTD_EXPORT_VAR_SET(__qtd_dummy, dummy); -// std::cout << _d_toUtf8 << "\n"; +extern "C" DLL_PUBLIC void qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr dummy) { + QTD_EXPORT_VAR_SET(qtd_toUtf8, d_func); + QTD_EXPORT_VAR_SET(qtd_dummy, dummy); + //std::cout << "qtd_core initialized" << std::endl; } #endif diff -r 27497bbe62a1 -r 7664de4a55e5 generator/containergenerator.cpp --- a/generator/containergenerator.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/containergenerator.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -447,7 +447,7 @@ d_type = cls_name; if (centry->designatedInterface()) d_type = centry->designatedInterface()->name(); - nativeId = ".nativeId"; + nativeId = ".__nativeId"; } if (centry->designatedInterface()) { @@ -470,7 +470,7 @@ << INDENT << "*elem = arr[pos]" << nativeId << ";" << endl << "}" << endl << endl - << "package " << d_type << " qtd_" << cls_name << "_cpp_to_d(" << cpp_type << " __qt_return_value)" << endl + << "package " << d_type << " qtd_" << cls_name << "_cpp_to_d(" << cpp_type << " ret)" << endl << "{" << endl; marshallFromCppToD(s, centry); diff -r 27497bbe62a1 -r 7664de4a55e5 generator/cppheadergenerator.cpp --- a/generator/cppheadergenerator.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/cppheadergenerator.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -178,13 +178,15 @@ s << "class " << shellClassName(java_class) << " : public " << java_class->qualifiedCppName(); - if (java_class->hasVirtualFunctions()) - s << ", public Qtd_QObjectEntity"; + if (java_class->isQObject()) + s << ", public QtD_QObjectEntity"; + else if(java_class->hasVirtualFunctions()) + s << ", public QtD_Entity"; s << endl << "{" << endl; if (java_class->isQObject()) { s << "public:" << endl - << " Q_OBJECT_CHECK" << endl; + << " Q_OBJECT_CHECK" << endl // << " mutable const QMetaObject *m_meta_object;" << endl; /* if (java_class->hasVirtualSlots()) { @@ -193,9 +195,9 @@ */ // s << " const QMetaObject *metaObject() const;" << endl // << " void *qt_metacast(const char *);" << endl -// << " QT_TR_FUNCTIONS" << endl -// << " virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl - s << "private:" << endl; +// << " QT_TR_FUNCTIONS" << end + << " virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl + << "private:" << endl; } diff -r 27497bbe62a1 -r 7664de4a55e5 generator/cppimplgenerator.cpp --- a/generator/cppimplgenerator.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/cppimplgenerator.cpp Thu Aug 20 14:47:17 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((" << 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; } @@ -608,7 +583,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 +596,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 +700,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 +823,7 @@ } s << function->marshalledName() << "_dispatch(" - << "this->d_entity()"; + << "this->dId"; if (f_type) { if (f_type->isTargetLangString()) @@ -861,7 +846,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()) @@ -1257,21 +1242,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 << " 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 + << " 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 +1296,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,8 +1327,6 @@ 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); @@ -1417,18 +1336,16 @@ << "(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 + << " mo.connect(qobj, signalId, qobj, mo.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 + << " mo.disconnect(qobj, signalId, qobj, mo.methodCount() + " << i << ");" << endl << "}" << endl << endl; } } @@ -1452,8 +1369,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 +1381,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 +1394,8 @@ << 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; */ + if (java_class->isQObject()) + s << " setUserData(userDataId, NULL);"; } s << "}" << endl << endl; } @@ -1818,6 +1711,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((" << 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 +2063,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 +2124,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 +2276,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 +2972,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; diff -r 27497bbe62a1 -r 7664de4a55e5 generator/cppimplgenerator.h --- a/generator/cppimplgenerator.h Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/cppimplgenerator.h Thu Aug 20 14:47:17 2009 +0000 @@ -212,6 +212,7 @@ void writeQObjectLink(QTextStream &s, const AbstractMetaClass *java_class); void writeSignalHandler(QTextStream &s, const AbstractMetaClass *java_class, AbstractMetaFunction *signal); static void writeInitCallbacks(QTextStream &s, const AbstractMetaClass *java_class); + static void writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class); void writeRefArguments(QTextStream &s, const AbstractMetaFunction *java_function); private: diff -r 27497bbe62a1 -r 7664de4a55e5 generator/dgenerator.cpp --- a/generator/dgenerator.cpp Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/dgenerator.cpp Thu Aug 20 14:47:17 2009 +0000 @@ -317,7 +317,7 @@ } */ // Generates Java 1.5 type enums - s << " public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl; + s << "public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl; const AbstractMetaEnumValueList &values = d_enum->values(); EnumTypeEntry *entry = d_enum->typeEntry(); @@ -477,11 +477,11 @@ } static QString function_call_for_ownership(TypeSystem::Ownership owner) -{ +{ if (owner == TypeSystem::CppOwnership) { - return "__set_native_ownership(true)"; + return "__setFlags(QtdObjectFlags.nativeOwnership, true)"; } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ { - return "__set_native_ownership(false)"; + return "__setFlags(QtdObjectFlags.nativeOwnership, false)"; }/* else if (owner == TypeSystem::DefaultOwnership) { return "__no_real_delete = false"; @@ -696,21 +696,21 @@ s << INDENT; if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd if(d_function->type() && d_function->type()->isQObject()) { // qtd - s << "void *__qt_return_value = "; + s << "void *ret = "; } else if(return_in_arg) // qtd ; else if (d_function->isConstructor()) { // qtd - s << "void* __qt_return_value = "; + s << "void* ret = "; } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) { - s << "void* __qt_return_value = "; + s << "void* ret = "; } else if (return_type && return_type->isVariant()) { - s << "void* __qt_return_value = "; + s << "void* ret = "; } else if (return_type && ( return_type->isObject() || (return_type->isNativePointer() && return_type->typeEntry()->isValue()) || return_type->typeEntry()->isInterface()) ) { - s << "void* __qt_return_value = "; + s << "void* ret = "; } else if (return_type && return_type->isArray()) { - s << return_type->arrayElementType()->name() + "* __qt_return_value = "; + s << return_type->arrayElementType()->name() + "* ret = "; } else { returnImmediately = true; s << "return "; @@ -765,9 +765,9 @@ if (!d_function->isConstructor() && !d_function->isStatic()) { if(dVersion == 2 && d_function->isConstant()) - s << "(cast(" << d_function->ownerClass()->name() << ")this).nativeId"; + s << "(cast(" << d_function->ownerClass()->name() << ")this).__nativeId"; else - s << "nativeId"; + s << "__nativeId"; } if (d_function->isConstructor() && @@ -801,7 +801,7 @@ QString arg_name = arg->argumentName(); if (type->isVariant()) - s << arg_name << " is null ? null : " << arg_name << ".nativeId"; + s << arg_name << " is null ? null : " << arg_name << ".__nativeId"; else if (te->designatedInterface()) s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name(); else if (modified_type == "string" /* && type->fullName() == "char" */) { @@ -831,9 +831,9 @@ } // else if (value type is abstract) then we will get a null pointer exception, which is all right if(dVersion == 2 && type->isConstant()) - s << "(cast(" << type->name() << ")" << arg_name << ").nativeId"; + s << "(cast(" << type->name() << ")" << arg_name << ").__nativeId"; else - s << arg_name << ".nativeId"; + s << arg_name << ".__nativeId"; } } } @@ -864,14 +864,14 @@ /* qtd2 if (needs_return_variable) { if (owner != TypeSystem::InvalidOwnership) { - s << INDENT << "if (__qt_return_value != null) {" << endl; + s << INDENT << "if (ret != null) {" << endl; if (return_type->isContainer()) - writeOwnershipForContainer(s, owner, return_type, "__qt_return_value"); + writeOwnershipForContainer(s, owner, return_type, "ret"); else - s << INDENT << " __qt_return_value." << function_call_for_ownership(owner) << ";" << endl; + s << INDENT << " ret." << function_call_for_ownership(owner) << ";" << endl; s << INDENT << "}" << endl; } - s << INDENT << "return __qt_return_value;" << endl; + s << INDENT << "return ret;" << endl; } */ if (d_function->isConstructor()) { @@ -893,29 +893,31 @@ } if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd + { if(return_type->isQObject()) - s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl; + s << return_type->name() << ".getObject(ret);" << endl; + } if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) - s << "new " << return_type->name() << "(__qt_return_value, false);" << endl; + s << "new " << return_type->name() << "(ret);" << endl; if (return_type->isVariant()) - s << "new QVariant(__qt_return_value, false);" << endl; + s << "new QVariant(ret);" << endl; if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) - s << "new " << return_type->name() << "(__qt_return_value, true);" << endl; + s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl; if (return_type->isObject()) { if(d_function->storeResult()) - s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl + s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; else - s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl; + s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl; s << endl; } if (return_type->isArray()) { - s << "__qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl; + s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl; } foreach (ReferenceCount referenceCount, referenceCounts) { @@ -1680,60 +1682,32 @@ if (!d_class->hasConstructors()) return; - s << endl; - if (d_class->baseClassName().isEmpty()) { - s << INDENT << "~this() { " << endl; + bool isTheQObject = d_class->name() == "QObject"; + if (isTheQObject || !d_class->isQObject()) + { + s << INDENT << "protected override void __deleteNative() {" << endl; { - Indentation indent(INDENT); - -/* - if(d_class->name() == "QObject") - s << INDENT << "if(!__gc_managed)" << endl - << INDENT << " remove(__gc_ref_list, this);" << endl - << INDENT << "if(!__no_real_delete && __gc_managed) {" << endl - << INDENT << " __qobject_is_deleting = true;" << endl - << INDENT << " scope(exit) __qobject_is_deleting = false;" << endl - << INDENT << " __free_native_resources();" << endl - << INDENT << "}" << endl; -*/ - if(d_class->name() == "QObject") - s << INDENT << "if(!__no_real_delete) {" << endl - << INDENT << " __qobject_is_deleting = true;" << endl - << INDENT << " scope(exit) __qobject_is_deleting = false;" << endl - << INDENT << " __free_native_resources();" << endl - << INDENT << "}" << endl; - else - s << INDENT << "if(!__no_real_delete)" << endl - << INDENT << " __free_native_resources();" << endl; + if (isTheQObject) + s << INDENT << "qtd_delete_qobject(__nativeId);" << endl; + else if (!d_class->isQObject()) + s << INDENT << "qtd_" << d_class->name() << "_destructor(__nativeId);" << endl; } s << INDENT << "}" << endl << endl; } - - s << INDENT << "protected void __free_native_resources() {" << endl; - { - Indentation indent(INDENT); - s << INDENT << "qtd_" << d_class->name() << "_destructor(nativeId());" << endl; - } - s << INDENT << "}" << endl << endl; } -void DGenerator::writeOwnershipMethods(QTextStream &s, const AbstractMetaClass *d_class) +void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class) { - s << INDENT << "void __set_native_ownership(bool ownership_)"; if (d_class->isInterface() || d_class->isNamespace()) - s << ";"; - else { - s << " {" << endl - << INDENT << " __no_real_delete = ownership_;" << endl - << INDENT << "}" << endl << endl; - } + s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);"; + else // COMPILER BUG: + s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }"; } void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class) { AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); - //TODO: linkage trivia should be abstracted away QString attr; s << "// signal handlers" << endl; @@ -1789,8 +1763,7 @@ if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; s << INDENT << "scope " << arg_name << " = new " << type_name - << "(cast(void*)(" << arg_ptr << "), true);" << endl - << INDENT << arg_name << ".__no_real_delete = true;"; + << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl; } s << endl; } @@ -1816,6 +1789,20 @@ bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake; + + QString auxModName = d_class->package() + "." + d_class->name() + "_aux"; + FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d"); + auxFile.isDone = true; + auxFile.stream << "module " << auxModName << ";" << endl << endl; + + bool staticInit = d_class->isQObject() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); + if (staticInit) + { + auxFile.isDone = false; + auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl; + auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl; + } + if (m_docs_enabled) { m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc"); } @@ -1897,14 +1884,31 @@ } } + // Enums aliases outside of the class - hack + if (!d_class->enums().isEmpty()) { + auxFile.isDone = false; + foreach (AbstractMetaEnum *d_enum, d_class->enums()) + writeEnum(auxFile.stream, d_enum); + } + + // Auxiliary file contents should have been written at this point + if (!auxFile.isDone) + { + s << "public import " << auxModName << ";" << endl; + auxFile.done(); + } + if (!m_isRecursive) { s << "public import qt.QGlobal;" << endl << "public import qt.core.Qt;" << endl - << "private import qt.QtDObject;" << endl + << "private import qt.QtdObject;" << endl << "private import qt.core.QString;" << endl << "private import qt.qtd.Array;" << endl; if (d_class->isQObject()) { - s << "public import qt.Signal;" << endl; + s << "public import qt.Signal;" << endl + << "public import qt.core.QMetaObject;" << endl + << "public import qt.qtd.Traits;" << endl; + if (d_class->name() != "QObject") s << "public import qt.core.QObject;" << endl; } @@ -1924,9 +1928,6 @@ if(d_class->isQObject()) s << "private import " << d_class->package() << ".ArrayOps2;" << endl; - if (!d_class->enums().isEmpty()) - s << "public import " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl; - s << "// automatic imports-------------" << endl; writeRequiredImports(s, d_class); s << endl; @@ -1935,35 +1936,23 @@ s << "import std.stdio;" << endl << "import std.string;" << endl << "import std.utf;" << endl - << "import core.memory;"; + << "import core.memory;" << endl; } else { s << "import tango.io.Stdout;" << endl << "import tango.stdc.stringz;" << endl << "import tango.text.convert.Utf;" << endl - << "import tango.core.Memory;"; + << "import tango.core.Memory;" << endl; } - s << endl << endl << endl; + + s << endl << endl; } if (m_doc_parser) { s << m_doc_parser->documentation(d_class) << endl << endl; } - // Enums aliases outside of the class - hack - if (!d_class->enums().isEmpty()) { - QString fileName = QString("%1_enum.d").arg(d_class->name()); - FileOut fileOut(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + fileName); - - fileOut.stream << "module " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl; - foreach (AbstractMetaEnum *d_enum, d_class->enums()) - writeEnum(fileOut.stream, d_enum); - } - - - s << endl; - /* qtd s << "@QtJambiGeneratedClass" << endl; if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) { @@ -2156,9 +2145,6 @@ foreach (AbstractMetaEnum *d_enum, d_class->enums()) writeEnumAlias(s, d_enum); - if (!d_class->enums().isEmpty() && !d_class->functions().isEmpty()) - s << endl; - // Signals AbstractMetaFunctionList signal_funcs; @@ -2251,37 +2237,39 @@ << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl; } */ + if (d_class->isQObject()) + writeQObjectFunctions(s, d_class); + // Add dummy constructor for use when constructing subclasses if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { s << endl << INDENT << "public " << "this"; - if(d_class->name() == "QObject") + + Indentation indent(INDENT); + + s << "(void* native_id, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl + << INDENT << "super(native_id, flags);" << endl; + + if (d_class->name() == "QObject") { - { - Indentation indent(INDENT); - s << "(void* native_id, bool gc_managed) {" << endl -/* << INDENT << "if(!gc_managed)" << endl - << INDENT << " __gc_ref_list ~= this;" << endl - << INDENT << "__gc_managed = gc_managed;" << endl */ - << INDENT << "super(native_id);" << endl; - } + // To prevent GC from collecting the object, add it to the statically rooted linked list + s << INDENT << " __next = __root;" << endl + << INDENT << " __root = this;" << endl + << INDENT << " if (__next) {" << endl + << INDENT << " __next.__prev = this;" << endl + << INDENT << " }" << endl << endl; } - else { - Indentation indent(INDENT); - if(d_class->isQObject()) - s << "(void* native_id, bool gc_managed) {" << endl - << INDENT << "super(native_id, gc_managed);" << endl; - else - s << "(void* native_id, bool no_real_delete = false) {" << endl - << INDENT << "super(native_id, no_real_delete);" << endl; - } + + /* if (cpp_shared) { if (d_class->generateShellClass() && !d_class->isInterface()) - s << INDENT << "if (!init_flag_" << d_class->name() << ")" << endl + s << INDENT << "if (!static_inited)" << endl << INDENT << " static_init_" << d_class->name() << "();" << endl << endl; } + */ + // customized store-result instances d_funcs = d_class->functionsInTargetLang(); for (int i=0; iname() << " = new " << type_name << "(cast(void*)null);" << endl; if (d_function->type()->isQObject()) - s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl; + s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; } } @@ -2316,14 +2304,14 @@ AbstractMetaClass *iface = interfaces.at(i); s << INDENT << " __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName() - << "(nativeId);" << endl; + << "(__nativeId);" << endl; } } s << INDENT << "}" << endl << endl; -/******************!!!DUBLICATE OF ABOVE!!!*********************/ +/******************!!!DUPLICATE OF ABOVE!!!*********************/ for (int i=0; ifunctionsInTargetLang(); for (int i=0; iname() << " = new " << type_name << "(cast(void*)null);" << endl; if (d_function->type()->isQObject()) - s << INDENT << " __m_" << d_function->name() << ".__no_real_delete = true;" << endl; + s << INDENT << " __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl; } } @@ -2509,18 +2494,15 @@ if (d_class->generateShellClass()) { // qtd2 if (d_class->hasVirtualFunctions() - && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) ) + && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) ) s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; } - if (d_class->isQObject()) - writeQObjectFunctions(s, d_class); - // if (d_class->needsConversionFunc) writeConversionFunction(s, d_class); - if (d_class->hasConstructors()) + if (d_class->hasConstructors() && !d_class->isQObject()) s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; // qtd @@ -2564,22 +2546,29 @@ writeShellVirtualFunction(s, function, d_class, pos); } - //init callbacks from dll to D side - if (cpp_shared) { - bool shellClass = d_class->generateShellClass(); - if (shellClass && !d_class->isInterface()) { - QString initArgs = "void* virtuals"; + // write static constructor + if (staticInit) { + QString initArgs; + if (cpp_shared) + { + initArgs = "void* virtuals"; if (d_class->isQObject()) - initArgs += ", void* signals, void* qobj_del"; + initArgs += ", void* signals"; s << "private extern (C) void qtd_" << d_class->name() - << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl - << "private bool init_flag_" << d_class->name() << " = false;" << endl - << "void static_init_" << d_class->name() << "() {" << endl - << INDENT << "init_flag_" << d_class->name() << " = true;" << endl << endl - - // virtual functions - << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; + << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; + } + + s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; + + if (d_class->isQObject()) { + s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl + << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; + } + + if (cpp_shared) { + // virtual functions + s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; for (int pos = 0; posisQObject()) { + + // signals AbstractMetaFunctionList signal_funcs = signalFunctions(d_class); s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl; for(int i = 0; i < signal_funcs.size(); i++) { @@ -2602,16 +2592,12 @@ initArgs += ", null"; else initArgs += ", sign_arr.ptr"; - - // QObject_delete - s << endl << INDENT << "void *qobj_del;" << endl - << INDENT << "qobj_del = &qtd_D_" << d_class->name() << "_delete;" << endl; - initArgs += ", qobj_del"; } - s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl - << "}" << endl << endl; + s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl; } + + s << "}" << endl << endl; } writeSignalHandlers(s, d_class); @@ -2628,56 +2614,43 @@ write(s, cls); m_isRecursive = false; } + + // qtd static metaobject + if (d_class->isQObject()) + s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();"; } void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class) { const ComplexTypeEntry *ctype = d_class->typeEntry(); - if(!ctype->isQObject() && !ctype->isObject()) + if(ctype->isQObject() || !ctype->isObject()) return; QString class_name = ctype->name(); QString return_type_name = class_name; if(ctype->designatedInterface()) return_type_name = ctype->designatedInterface()->name(); - s << return_type_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl; - - if(ctype->isQObject()) { - QString type_name = class_name; - if(ctype->isAbstract()) - type_name = type_name + "_ConcreteWrapper"; - - s << INDENT << "if (__qt_return_value is null)" << endl - << INDENT << " return null;" << endl - << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl - << INDENT << "if (d_obj is null) {" << endl - << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, false);" << endl - << INDENT << " qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl - << INDENT << " new_obj.__no_real_delete = true;" << endl - << INDENT << " return new_obj;" << endl - << INDENT << "} else" << endl - << INDENT << " return cast(" << class_name << ") d_obj;" << endl; - } else if (ctype->isObject()) { - QString type_name = class_name; - if(ctype->isAbstract()) - type_name = ctype->targetLangName() + "_ConcreteWrapper"; - - // if class has virtual functions then it has classname_entity function so - // we can look for D Object pointer. otherwise create new wrapper - if (d_class->hasVirtualFunctions()) { - s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(__qt_return_value);" << endl - << INDENT << "if (d_obj !is null) {" << endl - << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl - << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl - << INDENT << "} else {" << endl - << INDENT << " auto return_value = new " << type_name << "(__qt_return_value, true);" << endl - << INDENT << " return_value.__no_real_delete = true;" << endl - << INDENT << " return return_value;" << endl - << INDENT << "}" << endl; - } else { - s << INDENT << "auto return_value = new " << type_name << "(__qt_return_value, true);" << endl - << INDENT << "return_value.__no_real_delete = true;" << endl - << INDENT << "return return_value;" << endl; - } + + s << return_type_name << " qtd_" << class_name << "_from_ptr(void* ret) {" << endl; + + + QString type_name = class_name; + if(ctype->isAbstract()) + type_name = ctype->targetLangName() + "_ConcreteWrapper"; + + // if class has virtual functions then it has classname_entity function so + // we can look for D Object pointer. otherwise create new wrapper + if (d_class->hasVirtualFunctions()) { + s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(ret);" << endl + << INDENT << "if (d_obj !is null) {" << endl + << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl + << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl + << INDENT << "} else {" << endl + << INDENT << " auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl + << INDENT << " return return_value;" << endl + << INDENT << "}" << endl; + } else { + s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl + << INDENT << "return return_value;" << endl; } s << "}" << endl << endl; } @@ -2685,14 +2658,36 @@ void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) { - s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl - << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl; - s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl - << " auto d_ref = cast(QObject) d_ptr;" << endl - << " d_ref.__no_real_delete = true;" << endl - << " if(!d_ref.__qobject_is_deleting)" - << " delete d_ref;" << endl - << "}" << endl << endl; + QString concreteArg; + if (d_class->isAbstract()) + concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; + + s << " private static QMetaObject _staticMetaObject;" << endl + << " protected static void createStaticMetaObject() {" << endl + << " assert(!_staticMetaObject);" << endl + << " QMetaObject base;" << endl + + << " static if (!is(typeof(this) == QObject)) {" << endl + << " alias BaseTypeTuple!(typeof(this))[0] B;" << endl + << " if (!B._staticMetaObject)" << endl + << " B.createStaticMetaObject;" << endl + << " base = B._staticMetaObject;" << endl + << " }" << endl + << " _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);" << endl + << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl + << " }" << endl << endl + + << " QMetaObject metaObject() {" << endl + << " return _staticMetaObject;" << endl + << " }" << endl << endl + + << " static QMetaObject 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 + << " }" << endl << endl; } /* @@ -2705,16 +2700,18 @@ { if(ctype->isQObject()) { QString type_name = ctype->name(); - s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl; + if (ctype->isAbstract()) + type_name += "_ConcreteWrapper"; + s << "return " << type_name << ".getObject(ret);" << endl; } else if (ctype->isValue() && !ctype->isStructInD()) { - s << INDENT << "return new " << ctype->name() << "(__qt_return_value, false);" << endl; + s << INDENT << "return new " << ctype->name() << "(ret);" << endl; } else if (ctype->isVariant()) { - s << INDENT << "return new QVariant(__qt_return_value, false);" << endl; + s << INDENT << "return new QVariant(ret);" << endl; } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) { - s << INDENT << "return __qt_return_value;" << endl; + s << INDENT << "return ret;" << endl; } else if (ctype->isObject()) { QString type_name = ctype->name(); - s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl; + s << "return qtd_" << type_name << "_from_ptr(ret);" << endl; } } @@ -2779,7 +2776,7 @@ { Indentation indent(INDENT); s << INDENT << "if (signalId < __slotConnectors.length) {" << endl; - s << INDENT << " __slotConnectors[signalId](nativeId);" << endl; + s << INDENT << " __slotConnectors[signalId](__nativeId);" << endl; s << INDENT << "}" << endl; } s << INDENT << "}" << endl; @@ -2788,7 +2785,7 @@ { Indentation indent(INDENT); s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl; - s << INDENT << " __slotDisconnectors[signalId](nativeId);" << endl; + s << INDENT << " __slotDisconnectors[signalId](__nativeId);" << endl; s << INDENT << "}" << endl; } s << INDENT << "}" << endl; @@ -2854,7 +2851,7 @@ s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();"; } else if(type->isVariant()) - s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", true);"; + s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; else if (type->typeEntry()->isStructInD()) continue; else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer())) @@ -2866,7 +2863,7 @@ const ComplexTypeEntry *ctype = static_cast(type->typeEntry()); if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; - s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", true);"; + s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);"; } else if (type->isQObject()) { QString type_name = type->name(); @@ -2874,13 +2871,7 @@ if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; - s << INDENT << "scope " << arg_name << "_so = new StackObject!(" << type_name << ");" << endl - << INDENT << "auto " << arg_name << "_d_ref = " << arg_name << "_so(" << arg_name <<", true);" << endl - << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; -/* - s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name <<", true);" << endl - << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; -*/ + s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);" << endl; } s << endl; } @@ -2959,7 +2950,7 @@ if(f_type) { if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() || (f_type->isValue() && !f_type->typeEntry()->isStructInD())) { - QString native_id = "nativeId"; + QString native_id = "__nativeId"; if (f_type->typeEntry()->designatedInterface()) native_id = "__ptr_" + f_type->typeEntry()->designatedInterface()->name(); s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl; @@ -3255,34 +3246,7 @@ } } - if(d_function->implementingClass()->isQObject()) - { - bool hasParentArg = false; - AbstractMetaArgumentList arguments = d_function->arguments(); - int arg_index = 0; - for (int i=0; iargumentName().contains("parent", Qt::CaseInsensitive)) { - arg_index = i; - hasParentArg = true; - } - } - - const AbstractMetaArgument *arg = arguments.at(arg_index); -// QString ctor_call = d_function->implementingClass()->name() == "QObject"? "this" : "super"; - QString ctor_call = "this"; - if (hasParentArg) { - s << INDENT << "bool gc_managed = " << arg->argumentName() << " is null ? true : false;" << endl - << INDENT << ctor_call << "(__qt_return_value, gc_managed);" << endl; - } else { - s << INDENT << ctor_call << "(__qt_return_value, true);" << endl; - } - - // creating a link object associated with the current QObject for signal handling and metadata - s << INDENT << "qtd_" << d_function->ownerClass()->name() << "_create_link(this.nativeId, cast(void*) this);" << endl; - } - else - s << INDENT << "this(__qt_return_value);" << endl; + s << INDENT << "this(ret);" << endl; } s << INDENT << "}" << endl << endl; @@ -3353,7 +3317,7 @@ s << endl << " @Override" << endl << " public String toString() {" << endl - << " if (nativeId() == 0)" << endl + << " if (__nativeId == 0)" << endl << " throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl << " return __qt_toString(nativeId());" << endl << " }" << endl diff -r 27497bbe62a1 -r 7664de4a55e5 generator/dgenerator.h --- a/generator/dgenerator.h Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/dgenerator.h Thu Aug 20 14:47:17 2009 +0000 @@ -151,7 +151,7 @@ const TypeEntry* fixedTypeEntry(const TypeEntry *type); void writeDestructor(QTextStream &s, const AbstractMetaClass *d_class); - void writeOwnershipMethods(QTextStream &s, const AbstractMetaClass *d_class); + void writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class); void writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class); void writeEnumAlias(QTextStream &s, const AbstractMetaEnum *d_enum); void writeSignalConnectors(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunctionList signal_funcs); diff -r 27497bbe62a1 -r 7664de4a55e5 generator/fileout.h --- a/generator/fileout.h Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/fileout.h Thu Aug 20 14:47:17 2009 +0000 @@ -71,7 +71,6 @@ static bool dummy; static bool diff; - private: bool isDone; }; diff -r 27497bbe62a1 -r 7664de4a55e5 generator/typesystem_core-java.java --- a/generator/typesystem_core-java.java Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/typesystem_core-java.java Thu Aug 20 14:47:17 2009 +0000 @@ -22,7 +22,7 @@ * exception, Nokia gives you certain additional rights. These rights * are described in the Nokia Qt GPL Exception version 1.2, included in * the file GPL_EXCEPTION.txt in this package. -* +* * Qt for Windows(R) Licensees * As a special exception, Nokia, as the sole copyright holder for Qt * Designer, grants users of the Qt/Eclipse Integration plug-in the @@ -46,10 +46,9 @@ class QObject___ extends QObject { + /* TODO: test whether the linked list is really a better solution public bool __stackAllocated = false; - public bool __qobject_is_deleting = false; - new(size_t size, void* p = null) { if (!p) @@ -72,12 +71,64 @@ } } } + */ - // list of QObjects references to prevent them from garbage collecting if they are managed by Qt - private static QObject[] __gc_ref_list; + private + { + static QObject __root; + QObject __next; + QObject __prev; + } + + ~this() + { + if (__prev) + __prev.__next = __next; + else + __root = __next; + + if (__next) + __next.__prev = __prev; + } - // this flag needs to be set false when QObject is deleted from inside Qt so when deleting it from D it won't delete C++ object - public bool __no_real_delete = false; + /** + */ + T findChild(T : QObject = QObject)(string name = null) + { + foreach (obj; children) + { + 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; + if (tmp && (!name.length || tmp.objectName == name)) + result ~= tmp; + find(obj.children); + } + } + + find(children); + return result; + } }// class abstract class QAbstractItemModel___ extends QAbstractItemModel { @@ -141,14 +192,14 @@ { // if (m_instance != null) // throw new RuntimeException("QCoreApplication can only be initialized once"); - + argc = args.length; argv = toStringzArray(args); this(&argc, argv); // m_instance.aboutToQuit.connect(m_instance, "disposeOfMyself()"); } - + private int argc; private char **argv; /* @@ -489,7 +540,7 @@ public final long write(string str) { return write(str.ptr, str.length); - } + } }// class class QCryptographicHash___ extends QCryptographicHash { diff -r 27497bbe62a1 -r 7664de4a55e5 generator/typesystem_core-java.xml --- a/generator/typesystem_core-java.xml Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/typesystem_core-java.xml Thu Aug 20 14:47:17 2009 +0000 @@ -1,5 +1,5 @@ - + qt.Utilities.loadQtLibrary("QtCore"); diff -r 27497bbe62a1 -r 7664de4a55e5 generator/typesystem_core.xml --- a/generator/typesystem_core.xml Fri Jul 31 11:05:22 2009 +0000 +++ b/generator/typesystem_core.xml Thu Aug 20 14:47:17 2009 +0000 @@ -1,5 +1,5 @@ - + qt.Utilities.loadQtLibrary("QtCore"); @@ -787,7 +787,7 @@ - + @@ -814,7 +814,7 @@ - + @@ -882,7 +882,7 @@ - + @@ -897,7 +897,7 @@ - + @@ -1067,7 +1067,7 @@ - + @@ -1091,7 +1091,7 @@ - + @@ -1194,13 +1194,13 @@ - + - + @@ -1738,7 +1738,7 @@ - + @@ -1759,11 +1759,11 @@ - + - + @@ -2025,7 +2025,7 @@ - + @@ -2116,7 +2116,7 @@ - + @@ -2200,7 +2200,7 @@ - + @@ -2269,7 +2269,7 @@ - + @@ -2316,7 +2316,7 @@ - + @@ -2361,6 +2361,59 @@ + + +#ifdef CPP_SHARED +QTD_EXPORT_VAR(qtd_delete_d_qobject); + +extern "C" DLL_PUBLIC void qtd_QObjectEntity_initCallBacks(pfunc_abstr del_d_qobj) +{ + QTD_EXPORT_VAR_SET(qtd_delete_d_qobject, del_d_qobj); +} +#endif + + +extern "C" DLL_PUBLIC void* qtd_get_d_qobject(void *nativeId) +{ + QtD_QObjectEntity *entity = QtD_QObjectEntity::getQObjectEntity((QObject*)nativeId); + return entity ? entity->dId : NULL; +} + +extern "C" DLL_PUBLIC void qtd_delete_qobject(void *nativeId) +{ + delete (QObject*)nativeId; +} + +extern "C" DLL_PUBLIC void qtd_create_qobject_entity(void* nativeId, void *dId) +{ + new QtD_QObjectEntity((QObject*)nativeId, dId); +} + +extern "C" DLL_PUBLIC void* qtd_QObject_metaObject(void* nativeId) +{ + return (void*)((QObject*)nativeId)->metaObject(); +} + + + +extern(C) void* qtd_get_d_qobject(void* nativeId); +extern(C) void qtd_delete_qobject(void* nativeId); +extern(C) void* qtd_create_qobject_entity(void* nativeId, void* dId); +extern(C) void* qtd_QObject_metaObject(void* nativeId); + +extern(C) void qtd_delete_d_qobject(void* dId) +{ + auto obj = cast(QObject)dId; + + if (!(obj.__flags & QtdObjectFlags.dOwnership)) + { + // Avoid deleting native object twice + obj.__setFlags(QtdObjectFlags.nativeOwnership, true); + delete obj; + } +} + + @@ -2401,6 +2454,7 @@ __gc_managed = false; } --> + @@ -2424,11 +2478,9 @@ - - - - - + + + @@ -2480,7 +2532,7 @@ - + // qtjambi_register_variant_handler(); @@ -2527,7 +2579,7 @@ - + @@ -2557,7 +2609,7 @@ - +