changeset 105:3aa118a9ae71

each QObject now has associated child QObject for handling signals. fixes #15
author eldar
date Sun, 31 May 2009 01:38:39 +0000
parents 64b874c86f9b
children 0a0a0b63e473
files generator/cppheadergenerator.cpp generator/cppimplgenerator.cpp generator/cppimplgenerator.h generator/dgenerator.cpp generator/dgenerator.h include/qtd_core.h tools/drcc/rcc.pro
diffstat 7 files changed, 117 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/generator/cppheadergenerator.cpp	Sat May 30 13:07:26 2009 +0000
+++ b/generator/cppheadergenerator.cpp	Sun May 31 01:38:39 2009 +0000
@@ -191,11 +191,11 @@
           s << "  mutable QHash<int,int> m_map;" << endl;
       }
 */
-      s // << "  const QMetaObject *metaObject() const;" << endl
+//      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
-        << "private:" << endl;
+//        << "  virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl
+      s << "private:" << endl;
     }
 
 
--- a/generator/cppimplgenerator.cpp	Sat May 30 13:07:26 2009 +0000
+++ b/generator/cppimplgenerator.cpp	Sun May 31 01:38:39 2009 +0000
@@ -608,9 +608,9 @@
     writeDefaultConstructedValues(s, java_class);
 
     if (hasCustomDestructor(java_class)) */
-        writeFinalDestructor(s, java_class);
-
-   if (shellClass) {
+    writeFinalDestructor(s, java_class);
+
+    if (shellClass) {
         foreach (AbstractMetaFunction *function, java_class->functions()) {
             if (function->isConstructor() && !function->isPrivate())
                 writeShellConstructor(s, function);
@@ -627,7 +627,7 @@
         AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions();
         for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
             const AbstractMetaFunction *function = virtualFunctions.at(pos);
-// qtd            writeShellFunction(s, function, java_class, pos);
+            // qtd            writeShellFunction(s, function, java_class, pos);
             writeShellVirtualFunction(s, function, java_class, pos);
         }
 
@@ -639,7 +639,7 @@
         AbstractMetaFunctionList shellFunctions = java_class->nonVirtualShellFunctions();
         for (int i=0; i<shellFunctions.size(); ++i) {
             const AbstractMetaFunction *function = shellFunctions.at(i);
-                writeShellFunction(s, function, java_class, -1);
+            writeShellFunction(s, function, java_class, -1);
         }
 
         // Write public overrides for functions that are protected in the base class
@@ -660,9 +660,11 @@
                 continue;
             writeVirtualFunctionOverride(s, function, java_class);
         }
-
     }
 
+    if (java_class->isQObject())
+        writeSignalsHandling(s, java_class);
+
     writeExtraFunctions(s, java_class);
 /* qtd2
     writeToStringFunction(s, java_class);
@@ -1258,19 +1260,20 @@
       << "}" << endl << endl;
 */
 
-    writeSignalsHandling(s, java_class);
-
-    // QObject::qt_metacall()
+//    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
-      << "   return -1;" << 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 -1;" << endl
       << "}" << endl << endl;
+*/
 }
 
 void CppImplGenerator::writeSignalHandler(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunction *function)
@@ -1315,6 +1318,57 @@
 
 }
 
+void CppImplGenerator::writeQObjectLink(QTextStream &s, const AbstractMetaClass *java_class)
+{
+    QString linkName = java_class->name() + "_Link";
+    QString className = java_class->name();
+    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
+      << "    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;
@@ -1340,6 +1394,8 @@
         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);
@@ -1348,17 +1404,19 @@
         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 = " << shellClassName(java_class) << "::staticMetaObject;" << 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, qobj, mo.methodCount() + " << i << ");" << 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, qobj, mo.methodCount() + " << i << ");" << endl
+          << "    mo.disconnect(qobj, signalId, get_" << java_class->name() << "_link(qobj), mo2.methodCount() + " << i << ");" << endl
           << "}" << endl << endl;
     }
 }
--- a/generator/cppimplgenerator.h	Sat May 30 13:07:26 2009 +0000
+++ b/generator/cppimplgenerator.h	Sun May 31 01:38:39 2009 +0000
@@ -209,6 +209,7 @@
     static void writeVirtualDispatchFunction(QTextStream &s, const AbstractMetaFunction *function, bool d_export = false);
     static void writeInterfaceCasts(QTextStream &s, const AbstractMetaClass *java_class);
     void writeSignalsHandling(QTextStream &s, const AbstractMetaClass *java_class);
+    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);
     void writeRefArguments(QTextStream &s, const AbstractMetaFunction *java_function);
--- a/generator/dgenerator.cpp	Sat May 30 13:07:26 2009 +0000
+++ b/generator/dgenerator.cpp	Sun May 31 01:38:39 2009 +0000
@@ -851,11 +851,12 @@
         if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )/* || d_function->isConstructor()*/) // qtd
             if(return_type->isQObject()) {
 
+            const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(return_type->typeEntry());
             QString type_name = return_type->name();
-            const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry());
+            QString class_name = ctype->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 = __QObject_entity(__qt_return_value);" << endl
@@ -865,6 +866,18 @@
                     << INDENT << "    return new_obj;" << endl
                     << INDENT << "} else" << endl
                     << INDENT << "    return cast(" << return_type->name() << ") d_obj;" << endl;
+                    */
+            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, true);" << 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;
+
         }
 
 
@@ -2399,7 +2412,7 @@
             snip.formattedCode(s, INDENT); 
         } 
     } 
-	/* --------------------------------------------------- */ 
+    /* --------------------------------------------------- */
 
     interfaces = d_class->interfaces();
     if (!interfaces.isEmpty()) {
@@ -2413,10 +2426,7 @@
 
     if (!d_class->isInterface() && d_class->isAbstract()) {
         s << endl;
-/* qtd
-        if (TypeDatabase::instance()->includeEclipseWarnings())
-            s << INDENT << "@SuppressWarnings(\"unused\")" << endl;
-*/
+
         s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl;
 
         {
@@ -2505,8 +2515,11 @@
             && (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()) {
-        s<< "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl
+        writeQObjectFunctions(s, d_class);
+
+        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
           << "    delete d_ref;" << endl
@@ -2623,6 +2636,12 @@
     }
 }
 
+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;
+}
+
 /*
 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class)
 {
@@ -3233,6 +3252,9 @@
             } 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;
--- a/generator/dgenerator.h	Sat May 30 13:07:26 2009 +0000
+++ b/generator/dgenerator.h	Sun May 31 01:38:39 2009 +0000
@@ -154,6 +154,8 @@
     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);
+    void writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class);
+
 //    void writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class);
 
     int m_recursive;
--- a/include/qtd_core.h	Sat May 30 13:07:26 2009 +0000
+++ b/include/qtd_core.h	Sun May 31 01:38:39 2009 +0000
@@ -46,6 +46,8 @@
     void* ptr;
 };
 
+const uint USER_DATA_ID = 0;
+
 #define Array DArray
 
 #ifdef CPP_SHARED
--- a/tools/drcc/rcc.pro	Sat May 30 13:07:26 2009 +0000
+++ b/tools/drcc/rcc.pro	Sun May 31 01:38:39 2009 +0000
@@ -1,3 +1,6 @@
+CONFIG += debug
+CONFIG -= release
+    
 TEMPLATE = app
 TARGET = drcc