# HG changeset patch # User eldar # Date 1243899177 0 # Node ID 136c9ee83ee53e3d24f078285682d8a9ba42ddf3 # Parent 08135aa00cc9a2c54f6758a50a29e35166f1c38a put conversion code in separate functions diff -r 08135aa00cc9 -r 136c9ee83ee5 generator/abstractmetalang.h --- 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; diff -r 08135aa00cc9 -r 136c9ee83ee5 generator/containergenerator.cpp --- 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"; } diff -r 08135aa00cc9 -r 136c9ee83ee5 generator/dgenerator.cpp --- 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(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; itype(); + if (!f_type) + continue; + if (f_type->isQObject() || f_type->isObject()) { + const ComplexTypeEntry* cte = static_cast(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; + } } + diff -r 08135aa00cc9 -r 136c9ee83ee5 generator/dgenerator.h --- 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 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 diff -r 08135aa00cc9 -r 136c9ee83ee5 generator/generatorsetd.cpp --- 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; diff -r 08135aa00cc9 -r 136c9ee83ee5 qt/QGlobal.d --- 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;