diff options
-rw-r--r-- | generator/cppgenerator.cpp | 41 | ||||
-rw-r--r-- | generator/cppgenerator.h | 1 | ||||
-rw-r--r-- | generator/headergenerator.cpp | 6 | ||||
-rw-r--r-- | libshiboken/conversions.h | 4 |
4 files changed, 48 insertions, 4 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 15f30afad..1c3201847 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -123,6 +123,23 @@ QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(con return results.values(); } +void CppGenerator::writeToPythonFunction(QTextStream& s, const AbstractMetaClass* metaClass) +{ + s << "PyObject* SbkToPythonFunc(PyObject* self)" << endl; + s << "{" << endl; + s << INDENT << metaClass->qualifiedCppName() << "* cppSelf = Shiboken::Converter<" << metaClass->qualifiedCppName() << "* >::toCpp(self);" << endl; + s << INDENT << "PyObject* pyResult = Shiboken::PythonConverter<" << metaClass->qualifiedCppName() << " >::transformToPython(cppSelf);" << endl; + s << INDENT << "if (PyErr_Occurred() || !pyResult) {" << endl; + { + Indentation indentation(INDENT); + s << INDENT << INDENT << "Py_XDECREF(pyResult);" << endl; + s << INDENT << INDENT << "return 0;" << endl; + } + s << INDENT << "}" << endl; + s << INDENT << "return pyResult;" << endl; + s << "}" << endl; +} + /*! Function used to write the class generated binding code on the buffer \param s the output buffer @@ -211,6 +228,12 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << endl; } + // python conversion rules + if (metaClass->typeEntry()->hasTargetConversionRule()) { + s << "// Python Conversion" << endl; + s << metaClass->typeEntry()->conversionRule() << endl; + } + if (shouldGenerateCppWrapper(metaClass)) { s << "// Native ---------------------------------------------------------" << endl; s << endl; @@ -289,6 +312,12 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl } } + //ToPython used by Python Conversion + if (metaClass->typeEntry()->hasTargetConversionRule()) { + writeToPythonFunction(s, metaClass); + md << INDENT << "{\"toPython\", (PyCFunction)SbkToPythonFunc, METH_NOARGS}," << endl; + } + QString className = cpythonTypeName(metaClass).replace(QRegExp("_Type$"), ""); // Write single method definitions @@ -806,7 +835,6 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun s << INDENT << "const QMetaObject* metaObject;" << endl; } - s << INDENT << "SbkBaseWrapper* sbkSelf = reinterpret_cast<SbkBaseWrapper*>(self);" << endl; if (metaClass->isAbstract() || metaClass->baseClassNames().size() > 1) { @@ -852,12 +880,22 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun writeArgumentsInitializer(s, overloadData); } + bool hasPythonConvertion = metaClass->typeEntry()->hasTargetConversionRule(); + if (hasPythonConvertion) { + s << INDENT << "// Try python conversion rules" << endl; + s << INDENT << "cptr = Shiboken::PythonConverter< " << metaClass->qualifiedCppName() << " >::transformFromPython(pyargs[0]);" << endl; + s << INDENT << "if (!cptr) {" << endl; + } + if (needsOverloadId) writeOverloadedFunctionDecisor(s, overloadData); writeFunctionCalls(s, overloadData); s << endl; + if (hasPythonConvertion) + s << INDENT << "}" << endl; + s << INDENT << "if (PyErr_Occurred() || !Shiboken::setCppPointer(sbkSelf, Shiboken::SbkType<" << metaClass->qualifiedCppName() << " >(), cptr)) {" << endl; { Indentation indent(INDENT); @@ -3524,6 +3562,7 @@ void CppGenerator::finishGeneration() writeMethodDefinition(s_globalFunctionDef, overloads); } + foreach (const AbstractMetaClass* cls, classes()) { if (!shouldGenerate(cls)) continue; diff --git a/generator/cppgenerator.h b/generator/cppgenerator.h index 3869b1bc1..55591c598 100644 --- a/generator/cppgenerator.h +++ b/generator/cppgenerator.h @@ -141,6 +141,7 @@ private: void writeSetterFunction(QTextStream& s, const AbstractMetaField* metaField); void writeRichCompareFunction(QTextStream& s, const AbstractMetaClass* metaClass); + void writeToPythonFunction(QTextStream& s, const AbstractMetaClass* metaClass); void writeEnumNewMethod(QTextStream& s, const AbstractMetaEnum* cppEnum); void writeEnumDefinition(QTextStream& s, const AbstractMetaEnum* metaEnum); diff --git a/generator/headergenerator.cpp b/generator/headergenerator.cpp index f9384d58e..39db3c6ed 100644 --- a/generator/headergenerator.cpp +++ b/generator/headergenerator.cpp @@ -214,7 +214,7 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty implicitConvs << func; } bool isValueTypeWithImplConversions = type->isValue() && !implicitConvs.isEmpty(); - bool hasCustomConversion = type->hasConversionRule(); + bool hasCustomConversion = type->hasNativeConversionRule(); QString typeT = type->name() + (isAbstractOrObjectType ? "*" : ""); QString typeName = type->name(); @@ -450,7 +450,7 @@ void HeaderGenerator::finishGeneration() s << "// User defined converters --------------------------------------------" << endl; foreach (TypeEntry* typeEntry, TypeDatabase::instance()->entries()) { - if (typeEntry->hasConversionRule()) { + if (typeEntry->hasNativeConversionRule()) { s << "// Conversion rule for: " << typeEntry->name() << endl; s << typeEntry->conversionRule(); } @@ -503,7 +503,7 @@ void HeaderGenerator::writeSbkCopyCppObjectFunction(QTextStream& s, const Abstra void HeaderGenerator::writeTypeConverterImpl(QTextStream& s, const TypeEntry* type) { - if (type->hasConversionRule()) + if (type->hasNativeConversionRule()) return; QString pyTypeName = cpythonTypeName(type); diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index 142fad009..376b1aca5 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -711,6 +711,10 @@ struct StdMapConverter } }; + +// class used to translate python objects to another type +template <typename T> struct PythonConverter {}; + } // namespace Shiboken #endif // CONVERSIONS_H |