changeset 183:d3f4f14d43a5

fixes with QObjects
author eldar
date Fri, 03 Jul 2009 20:53:07 +0000
parents 973564c7e388
children 7d9db724ee1d
files build/posix.makefile generator/cppimplgenerator.cpp generator/dgenerator.cpp generator/typesystem_core-java.java generator/typesystem_core.xml qt/QGlobal.d
diffstat 6 files changed, 111 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/build/posix.makefile	Fri Jul 03 16:07:26 2009 +0000
+++ b/build/posix.makefile	Fri Jul 03 20:53:07 2009 +0000
@@ -1,6 +1,6 @@
 SYSTEM = posix
 ifndef QTDIR
-#QTDIR = /usr/share/qt4
+QTDIR = /usr/share/qt4
 ifndef QTDIR_INC
 QTDIR_INC = /usr/include/qt4
 endif
--- a/generator/cppimplgenerator.cpp	Fri Jul 03 16:07:26 2009 +0000
+++ b/generator/cppimplgenerator.cpp	Fri Jul 03 20:53:07 2009 +0000
@@ -1321,6 +1321,13 @@
 {
     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
@@ -1328,6 +1335,7 @@
       << "    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
@@ -1463,24 +1471,13 @@
 
 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class)
 {
-
-    if (java_class->isQObject())
-    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 << shellClassName(java_class) << "::~"
       << shellClassName(java_class) << "()" << endl
       << "{" << endl;
     {
+/* qtd
         Indentation indent(INDENT);
-        if (java_class->isQObject())
-            s << INDENT << "if (QObject::parent())" << endl
-              << INDENT << "    qtd_D_" << java_class->name() << "_delete(this->d_entity());" << endl;
-
-/* qtd
+
         s << "#ifdef QT_DEBUG" << endl
           << INDENT << "if (m_vtable)" << endl
           << INDENT << "    m_vtable->deref();" << endl
--- a/generator/dgenerator.cpp	Fri Jul 03 16:07:26 2009 +0000
+++ b/generator/dgenerator.cpp	Fri Jul 03 20:53:07 2009 +0000
@@ -1671,11 +1671,21 @@
         {
             Indentation indent(INDENT);
 
+/*            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;*/
+
             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 << "    __free_native_resources();" << 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;
             else
                 s << INDENT << "if(!__no_real_delete)" << endl
                   << INDENT << "    __free_native_resources();" << endl;
@@ -2612,7 +2622,7 @@
           << 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 << "    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
@@ -2652,7 +2662,8 @@
     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
+      << "    if(!d_ref.__qobject_is_deleting)"
+      << "        delete d_ref;" << endl
       << "}" << endl << endl;
 }
 
@@ -2834,7 +2845,11 @@
                     const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
                     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;";
                 }
--- a/generator/typesystem_core-java.java	Fri Jul 03 16:07:26 2009 +0000
+++ b/generator/typesystem_core-java.java	Fri Jul 03 20:53:07 2009 +0000
@@ -45,15 +45,37 @@
 import qt.core.*;
 
 class QObject___ extends QObject {
-	
-	// list of QObjects references to prevent them from garbage collecting if they are managed by Qt
-	private static QObject[] __gc_ref_list;
+    
+    public bool __stackAllocated = false;
+    
+    public bool __qobject_is_deleting = false;
+/*    
+    new(uint size, void* p = null)
+    {
+        if (!p)
+        {
+            p = malloc(size);
+            if (!p)
+                assert(false, "Out of memory");
+        }
+
+        return p;
+    }
+
+    delete(void* p)
+    {
+        if (!(cast(typeof(this))p).__stackAllocated)
+            free(p);
+    }
+*/    
+    // list of QObjects references to prevent them from garbage collecting if they are managed by Qt
+    private static QObject[] __gc_ref_list;
     
     // this flag controls whether QObject is managed by D's GC, or it has a parent and therefore managed by Qt
     private bool __gc_managed = true;
-	
-	// 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;
+    
+    // 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;
 }// class
 
 abstract class QAbstractItemModel___ extends QAbstractItemModel {
--- a/generator/typesystem_core.xml	Fri Jul 03 16:07:26 2009 +0000
+++ b/generator/typesystem_core.xml	Fri Jul 03 20:53:07 2009 +0000
@@ -2391,7 +2391,7 @@
         <modify-argument index="1">
             <reference-count action="ignore"/>
         </modify-argument>
-        <inject-code class="java" position="beginning">
+<!--        <inject-code class="java" position="beginning">
             <argument-map index="1" meta-name="%1"/>
             if (%1 is null &amp;&amp; !__gc_managed) {
                 remove(__gc_ref_list, this);
@@ -2400,7 +2400,7 @@
                 __gc_ref_list ~= this;
                 __gc_managed = false;
             }
-        </inject-code>
+        </inject-code> -->
     </modify-function>
 
     <modify-function signature="deleteLater()">
--- a/qt/QGlobal.d	Fri Jul 03 16:07:26 2009 +0000
+++ b/qt/QGlobal.d	Fri Jul 03 20:53:07 2009 +0000
@@ -585,4 +585,53 @@
 const ushort QT_EDITION_EVALUATION =  QT_EDITION_DESKTOP;
 
 mixin QT_END_NAMESPACE;
+
+package import tango.stdc.stdlib;
+
+template sizeOf(C : Object)
+{
+    const sizeOf = sizeOfImpl!(C);
+}
+
+size_t sizeOfImpl(C)()
+{
+    size_t size;
+
+    foreach (i, _; typeof(C.tupleof))
+    {
+        auto newSize = C.tupleof[i].offsetof + C.tupleof[i].sizeof;
+        if (newSize > size)
+            size = newSize;
+    }
+
+    return size;
+}
+
+scope class StackObject(C)
+{
+    byte[sizeOf!(C)] data;
+    bool constructed;
+
+    C opCall(A...)(A args)
+    {
+        assert(!constructed);
+
+        auto r = new(&data)C(args);
+        r.__stackAllocated = true;
+        constructed = true;
+
+        return r;
+    }
+
+    ~this()
+    {
+        if (constructed)
+        {
+            auto obj = cast(C)&data;
+            delete obj;
+        }
+    }
+}
+
 mixin QT_END_HEADER;
+