diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2020-04-15 20:23:28 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2020-04-30 19:39:25 +0200 |
commit | 3d7265db9075db7b22b241b659f23d392d62d804 (patch) | |
tree | 902bb831d91f39b89d4481dca9381a18abb5dac3 /src/tools/moc/generator.cpp | |
parent | b480acb3720c0d61c5c69a2b861af63b9d7c9f86 (diff) |
Provide a way of exposing private QProperties with a fake API
The API reduces the amount of manual plumbing required to offer a
conceptual property through the traditional setter/getter API as well as
through QProperty<T> API. Since the latter would require inlining the
type and thus making it impossible to add new properties without
breaking binary compatibility, this patch introduces a fake API that
behaves similar but does not contain the property by value.
Change-Id: Ib9bccd867f0e4e36a520e5583ba348e728284253
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/tools/moc/generator.cpp')
-rw-r--r-- | src/tools/moc/generator.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index acb7cdffe9..976d49ad20 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -616,6 +616,11 @@ void Generator::generateCode() generateSignal(&cdef->signalList[signalindex], signalindex); // +// Generate QProperty forwarding API +// + generateQPropertyApi(); + +// // Generate plugin meta data // generatePluginMetaData(); @@ -1621,6 +1626,106 @@ void Generator::generateSignal(FunctionDef *def,int index) fprintf(out, "}\n"); } +void Generator::generateQPropertyApi() +{ + for (const PrivateQPropertyDef &property: cdef->privateQProperties) { + auto printAccessor = [this, property](bool constAccessor = false) { + const char *constOrNot = constAccessor ? "const " : " "; + fprintf(out, " const size_t propertyMemberOffset = reinterpret_cast<size_t>(&(static_cast<%s *>(nullptr)->%s));\n", cdef->qualified.constData(), property.name.constData()); + fprintf(out, " %sauto *thisPtr = reinterpret_cast<%s%s *>(reinterpret_cast<%schar *>(this) - propertyMemberOffset);\n", constOrNot, constOrNot, cdef->qualified.constData(), constOrNot); + }; + + // property accessor + fprintf(out, "\n%s %s::_qt_property_api_%s::value() const\n{\n", + property.type.name.constData(), + cdef->qualified.constData(), + property.name.constData()); + printAccessor(/*const*/true); + fprintf(out, " return thisPtr->%s->%s.value();\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // property value setter + fprintf(out, "\nvoid %s::_qt_property_api_%s::setValue(const %s &value)\n{\n", + cdef->qualified.constData(), + property.name.constData(), + property.type.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.setValue(value);\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // property value move setter + fprintf(out, "\nvoid %s::_qt_property_api_%s::setValue(%s &&value)\n{\n", + cdef->qualified.constData(), + property.name.constData(), + property.type.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.setValue(std::move(value));\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // binding setter + fprintf(out, "\nQPropertyBinding<%s> %s::_qt_property_api_%s::setBinding(const QPropertyBinding<%s> &binding)\n{\n", + property.type.name.constData(), + cdef->qualified.constData(), + property.name.constData(), + property.type.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.setBinding(binding);\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // binding move setter + fprintf(out, "\nQPropertyBinding<%s> %s::_qt_property_api_%s::setBinding(QPropertyBinding<%s> &&binding)\n{\n", + property.type.name.constData(), + cdef->qualified.constData(), + property.name.constData(), + property.type.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.setBinding(std::move(binding));\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // untyped binding setter + fprintf(out, "\nbool %s::_qt_property_api_%s::setBinding(const QUntypedPropertyBinding &binding)\n{\n", + cdef->qualified.constData(), + property.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.setBinding(binding);\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // binding bool getter + fprintf(out, "\nbool %s::_qt_property_api_%s::hasBinding() const\n{\n", + cdef->qualified.constData(), + property.name.constData()); + printAccessor(/*const*/true); + fprintf(out, " return thisPtr->%s->%s.hasBinding();\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // binding getter + fprintf(out, "\nQPropertyBinding<%s> %s::_qt_property_api_%s::binding() const\n{\n", + property.type.name.constData(), + cdef->qualified.constData(), + property.name.constData()); + printAccessor(/*const*/true); + fprintf(out, " return thisPtr->%s->%s.binding();\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // binding taker + fprintf(out, "\nQPropertyBinding<%s> %s::_qt_property_api_%s::takeBinding()\n{\n", + property.type.name.constData(), + cdef->qualified.constData(), + property.name.constData()); + printAccessor(); + fprintf(out, " return thisPtr->%s->%s.takeBinding();\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n"); + + // property setter function + fprintf(out, "\nvoid %s::%s(const %s &value)\n{\n", + cdef->qualified.constData(), + property.setter.constData(), + property.type.name.constData()); + fprintf(out, " %s->%s.setValue(value);\n", property.accessor.constData(), property.name.constData()); + fprintf(out, "}\n\n"); + } +} + static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v); static CborError jsonObjectToCbor(CborEncoder *parent, const QJsonObject &o) { |