changeset 110:136c9ee83ee5

put conversion code in separate functions
author eldar
date Mon, 01 Jun 2009 23:32:57 +0000
parents 08135aa00cc9
children 2a85b786fa3a
files generator/abstractmetalang.h generator/containergenerator.cpp generator/dgenerator.cpp generator/dgenerator.h generator/generatorsetd.cpp qt/QGlobal.d
diffstat 6 files changed, 132 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/generator/abstractmetalang.h	Mon Jun 01 07:15:52 2009 +0000
+++ b/generator/abstractmetalang.h	Mon Jun 01 23:32:57 2009 +0000
@@ -695,7 +695,8 @@
           m_extracted_interface(0),
           m_primary_interface_implementor(0),
           m_type_entry(0),
-          m_qDebug_stream_function(0)
+          m_qDebug_stream_function(0),
+          needsConversionFunc(false)
     {
     }
 
@@ -844,6 +845,8 @@
     bool isTypeAlias() const { return m_is_type_alias; }
 
     const QStringList &depends() { return m_type_entry->depends(); }
+
+    bool needsConversionFunc;
 private:
     uint m_namespace : 1;
     uint m_qobject : 1;
--- a/generator/containergenerator.cpp	Mon Jun 01 07:15:52 2009 +0000
+++ b/generator/containergenerator.cpp	Mon Jun 01 23:32:57 2009 +0000
@@ -370,6 +370,8 @@
         cpp_type = "void*";
         cpp_assign_type = cpp_type + "*";
         d_type = cls_name;
+        if (centry->designatedInterface())
+            d_type = centry->designatedInterface()->name();
         nativeId = ".nativeId";
     }
 
--- a/generator/dgenerator.cpp	Mon Jun 01 07:15:52 2009 +0000
+++ b/generator/dgenerator.cpp	Mon Jun 01 23:32:57 2009 +0000
@@ -848,38 +848,9 @@
 
     // return value marschalling
     if(return_type) {
-        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();
-            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
-                    << INDENT << "if (d_obj is null) {" << endl
-                    << INDENT << "    auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl
-                    << INDENT << "    new_obj.__no_real_delete = true;" << endl
-                    << 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;
-
-        }
-
+        if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd
+            if(return_type->isQObject())
+                s << INDENT << "return qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
 
         if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
             s << INDENT << "return new " << return_type->name() << "(__qt_return_value, false);" << endl;
@@ -905,14 +876,6 @@
                     return_type_name = return_type->typeEntry()->designatedInterface()->name();
 
                 AbstractMetaClass *classForTypeEntry = NULL;
-                // search in AbstractMetaClass list for return type
-                // find a better way to perform TypeEntry -> AbstractMetaClass lookup, maybe create hash before generation
-                // qtd2
-                /*foreach (AbstractMetaClass *cls, m_classes) {
-                    if ( cls->name() == d_function->type()->name() )
-                        classForTypeEntry = cls;
-                }*/
-
                 classForTypeEntry = ClassFromEntry::get(return_type->typeEntry());
 
                 // if class has virtual functions then it has classname_entity function so
@@ -2516,15 +2479,12 @@
         s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl;
     }
 
-    if (d_class->isQObject()) {
+    if (d_class->isQObject())
         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
-          << "}" << endl;
-    }
+
+    if (d_class->needsConversionFunc)
+        writeConversionFunction(s, d_class);
 
     if (d_class->hasConstructors())
         s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl;
@@ -2636,10 +2596,68 @@
     }
 }
 
+void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class)
+{
+    const ComplexTypeEntry *ctype = d_class->typeEntry();
+    QString class_name = ctype->name();
+
+    if(ctype->isQObject()) {
+s << class_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl;
+        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, 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;
+s << "}" << endl << endl;
+
+    } /* else if (ctype->isObject()) {
+        QString type_name = class_name;
+        if(ctype->isAbstract())
+            type_name = type_name + "_ConcreteWrapper";
+
+        QString return_type_name = ctype->name();
+        if(ctype->designatedInterface())
+            return_type_name = ctype->designatedInterface()->name();
+
+        // 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->name() << "_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 << "}";
+        } 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;
+        }
+    }*/
+}
+
+
 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
+      << "    delete d_ref;" << endl
+      << "}" << endl << endl;
 }
 
 /*
@@ -2972,7 +2990,6 @@
 
         if (!cls->isInterface() && cls->isAbstract()) {
             ComplexTypeEntry *ctype_m = (ComplexTypeEntry *)ctype;
-
             ctype_m->setAbstract(true);
         }
 
@@ -2983,9 +3000,22 @@
 
         foreach (AbstractMetaFunction *function, cls->functions())
             function->checkStoreResult();
+
+        // generate QObject conversion functions only those that are required
+        AbstractMetaFunctionList d_funcs = cls->functionsInTargetLang();
+        for (int i=0; i<d_funcs.size(); ++i) {
+            AbstractMetaType *f_type = d_funcs.at(i)->type();
+            if (!f_type)
+                continue;
+            if (f_type->isQObject() || f_type->isObject()) {
+                const ComplexTypeEntry* cte = static_cast<const ComplexTypeEntry *>(f_type->typeEntry());
+                AbstractMetaClass* d_class = ClassFromEntry::get(cte);
+                if (d_class)
+                    d_class->needsConversionFunc = true;
+            }
+        }
     }
 
-
     Generator::generate();
 
     {
@@ -3353,16 +3383,38 @@
 
 ClassFromEntry::ClassFromEntry()
 {
+}
+
+AbstractMetaClass* ClassFromEntry::get(const TypeEntry *ctype)
+{
+    if(!m_instance)
+        return NULL;
+
+    return m_instance->classFromEntry[ctype];
+}
+
+void ClassFromEntry::construct(const AbstractMetaClassList &classes)
+{
+    if(!m_instance) {
+        m_instance = new ClassFromEntry;
+        m_instance->setClasses(classes);
+        m_instance->buildHash();
+    }
+}
+
+void ClassFromEntry::buildHash()
+{
     foreach (AbstractMetaClass *cls, m_classes) {
         const ComplexTypeEntry *ctype = cls->typeEntry();
         classFromEntry[ctype] = cls;
     }
 }
 
-AbstractMetaClass* ClassFromEntry::get(const TypeEntry *ctype)
+void ClassFromEntry::print(QTextStream &s)
 {
-    if(!m_instance)
-        m_instance = new ClassFromEntry;
-
-    return m_instance->classFromEntry[ctype];
+    s << "_fuck_" << m_instance->m_classes.size();
+    foreach (AbstractMetaClass *cls, m_instance->m_classes) {
+        s << cls->name() << endl;
+    }
 }
+
--- a/generator/dgenerator.h	Mon Jun 01 07:15:52 2009 +0000
+++ b/generator/dgenerator.h	Mon Jun 01 23:32:57 2009 +0000
@@ -155,6 +155,7 @@
     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 writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class);
 
 //    void writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class);
 
@@ -184,10 +185,14 @@
 
 private:
     ClassFromEntry();
+    void buildHash();
     QHash<const TypeEntry *, AbstractMetaClass *> classFromEntry;
     static ClassFromEntry* m_instance;
 
 public:
     static AbstractMetaClass* get(const TypeEntry *te);
+    static void print(QTextStream &s);
+    static void construct(const AbstractMetaClassList &classes);
+
 };
 #endif // DGENERATOR_H
--- a/generator/generatorsetd.cpp	Mon Jun 01 07:15:52 2009 +0000
+++ b/generator/generatorsetd.cpp	Mon Jun 01 23:32:57 2009 +0000
@@ -155,6 +155,8 @@
     JumpTablePreprocessor *jumpTablePreprocessor = 0;
     JumpTableGenerator *jumpTableGenerator = 0;
 
+    ClassFromEntry::construct(builder.classes());
+
     QStringList contexts;
     if (build_qdoc_japi) {
         generators << new QDocGenerator;
--- a/qt/QGlobal.d	Mon Jun 01 07:15:52 2009 +0000
+++ b/qt/QGlobal.d	Mon Jun 01 23:32:57 2009 +0000
@@ -582,5 +582,18 @@
 const ushort QT_EDITION_EDUCATIONAL = QT_EDITION_DESKTOP;
 const ushort QT_EDITION_EVALUATION =  QT_EDITION_DESKTOP;
 
+T qObjectFromPtr(T)(void *__qt_return_value) {
+    if (__qt_return_value is null)
+        return null;
+    mixin("void* d_obj = qtd_" ~ T.stringof ~ "_d_pointer(__qt_return_value);");
+    if (d_obj is null) {
+        T new_obj = new T(__qt_return_value, true);
+        mixin("qtd_" ~ T.stringof ~ "_create_link(new_obj.nativeId, cast(void*) new_obj);");
+        new_obj.__no_real_delete = true;
+        return new_obj;
+    } else
+        return cast(T) d_obj;
+}
+
 mixin QT_END_NAMESPACE;
 mixin QT_END_HEADER;