diff options
author | Gerhard Gappmeier <gerhard.gappmeier@ascolab.com> | 2012-07-02 13:01:32 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-01-19 17:36:55 +0100 |
commit | 9bbebb914422262b7b585b6d1dab9d21c4238c44 (patch) | |
tree | 65a87988bb8d2d8bae3e81bbff2dce480f436435 /src/tools/moc/generator.cpp | |
parent | 6f225b0b5d774828df310948435f1cc3a4720104 (diff) |
Add support for defining properties from member variables.
This associates properties with member variables and
avoids writing getter and setter methods manually.
The metaCall() method directly accesses the member variable,
so additional method calls can be avoided.
The metaCall() setter code also supports NOTIFY signals,
which means the according signal is emitted when the property
gets written.
Task-number: QTBUG-16852
Change-Id: I88a1f237ea53a1e9cf65fc9ef2e207718eb8b6c3
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/tools/moc/generator.cpp')
-rw-r--r-- | src/tools/moc/generator.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 06efd77adc..083b095094 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -719,7 +719,9 @@ void Generator::generateProperties() uint flags = Invalid; if (!isBuiltinType(p.type)) flags |= EnumOrFlag; - if (!p.read.isEmpty()) + if (!p.member.isEmpty() && !p.constant) + flags |= Writable; + if (!p.read.isEmpty() || !p.member.isEmpty()) flags |= Readable; if (!p.write.isEmpty()) { flags |= Writable; @@ -893,12 +895,12 @@ void Generator::generateMetacall() bool needUser = false; for (int i = 0; i < cdef->propertyList.size(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); - needGet |= !p.read.isEmpty(); + needGet |= !p.read.isEmpty() || !p.member.isEmpty(); if (!p.read.isEmpty()) needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec && p.gspec != PropertyDef::ReferenceSpec); - needSet |= !p.write.isEmpty(); + needSet |= !p.write.isEmpty() || (!p.member.isEmpty() && !p.constant); needReset |= !p.reset.isEmpty(); needDesignable |= p.designable.endsWith(')'); needScriptable |= p.scriptable.endsWith(')'); @@ -917,7 +919,7 @@ void Generator::generateMetacall() fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); - if (p.read.isEmpty()) + if (p.read.isEmpty() && p.member.isEmpty()) continue; QByteArray prefix; if (p.inPrivateClass.size()) { @@ -933,9 +935,12 @@ void Generator::generateMetacall() else if (cdef->enumDeclarations.value(p.type, false)) fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n", propindex, prefix.constData(), p.read.constData()); - else + else if (!p.read.isEmpty()) fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n", propindex, p.type.constData(), prefix.constData(), p.read.constData()); + else + fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n", + propindex, p.type.constData(), prefix.constData(), p.member.constData()); } fprintf(out, " }\n"); } @@ -952,7 +957,9 @@ void Generator::generateMetacall() fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); - if (p.write.isEmpty()) + if (p.constant) + continue; + if (p.write.isEmpty() && p.member.isEmpty()) continue; QByteArray prefix; if (p.inPrivateClass.size()) { @@ -962,9 +969,25 @@ void Generator::generateMetacall() if (cdef->enumDeclarations.value(p.type, false)) { fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n", propindex, prefix.constData(), p.write.constData()); - } else { + } else if (!p.write.isEmpty()) { fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n", propindex, prefix.constData(), p.write.constData(), p.type.constData()); + } else { + fprintf(out, " case %d:\n", propindex); + fprintf(out, " if (%s%s != *reinterpret_cast< %s*>(_v)) {\n", + prefix.constData(), p.member.constData(), p.type.constData()); + fprintf(out, " %s%s = *reinterpret_cast< %s*>(_v);\n", + prefix.constData(), p.member.constData(), p.type.constData()); + if (!p.notify.isEmpty() && p.notifyId != -1) { + const FunctionDef &f = cdef->signalList.at(p.notifyId); + if (f.arguments.size() == 0) + fprintf(out, " emit %s();\n", p.notify.constData()); + else if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type) + fprintf(out, " emit %s(%s%s);\n", + p.notify.constData(), prefix.constData(), p.member.constData()); + } + fprintf(out, " }\n"); + fprintf(out, " break;\n"); } } fprintf(out, " }\n"); |