Browse Source

Fix repeated field update signals

- Add update signals for repeated fields when move semantics is used

Fixes: #48
Alexey Edelev 5 years ago
parent
commit
c70fb33100

+ 1 - 1
src/generator/protobufsourcegenerator.cpp

@@ -291,7 +291,7 @@ void ProtobufSourceGenerator::printMoveSemantic()
             if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
                 printField(mMessage, field, Templates::MoveMessageFieldTemplate);
             } else {
-                printField(mMessage, field, Templates::MoveComplexFieldTemplate);
+                printField(mMessage, field, Templates::MoveComplexFieldConstructorTemplate);
             }
         } else {
             if (field->type() != FieldDescriptor::TYPE_ENUM) {

+ 12 - 1
src/generator/templates.cpp

@@ -108,7 +108,18 @@ const char *Templates::DeletedMoveConstructorTemplate = "$classname$($classname$
 const char *Templates::CopyFieldTemplate = "set$property_name_cap$(other.m_$property_name$);\n";
 const char *Templates::CopyComplexFieldTemplate = "set$property_name_cap$(*other.m_$property_name$);\n";
 const char *Templates::MoveMessageFieldTemplate = "*m_$property_name$ = std::move(*other.m_$property_name$);\n";
-const char *Templates::MoveComplexFieldTemplate = "m_$property_name$ = std::move(other.m_$property_name$);\n";
+const char *Templates::MoveComplexFieldTemplate = "if (m_$property_name$ != other.m_$property_name$) {\n"
+                                                  "    m_$property_name$ = std::move(other.m_$property_name$);\n"
+                                                  "    $property_name$Changed();\n"
+                                                  "    other.$property_name$Changed();\n"
+                                                  "} else {\n"
+                                                  "    m_$property_name$ = std::move(other.m_$property_name$);\n"
+                                                  "    other.$property_name$Changed();\n"
+                                                  "}\n";
+
+const char *Templates::MoveComplexFieldConstructorTemplate = "m_$property_name$ = std::move(other.m_$property_name$);\n"
+                                                             "other.$property_name$Changed();\n";
+
 const char *Templates::MoveFieldTemplate = "set$property_name_cap$(std::exchange(other.m_$property_name$, 0));\n"
                                            "other.$property_name$Changed();\n";
 const char *Templates::EnumMoveFieldTemplate = "m_$property_name$ = other.m_$property_name$;\n";

+ 1 - 0
src/generator/templates.h

@@ -90,6 +90,7 @@ public:
     static const char *CopyComplexFieldTemplate;
     static const char *MoveMessageFieldTemplate;
     static const char *MoveComplexFieldTemplate;
+    static const char *MoveComplexFieldConstructorTemplate;
     static const char *MoveFieldTemplate;
     static const char *EnumMoveFieldTemplate;
     static const char *AssignmentOperatorDeclarationTemplate;

+ 21 - 0
tests/test_protobuf/simpletest.cpp.inc

@@ -751,6 +751,27 @@ TEST_F(SimpleTest, MoveOperatorTest)
     ASSERT_EQ(3, movedUpdateSpy.count());
 }
 
+TEST_F(SimpleTest, MoveOperatorRepeatedTest)
+{
+    const char *propertyName = "testRepeatedInt";
+    RepeatedIntMessage test;
+    RepeatedIntMessage test2{{55,44,11,33}};
+
+    QSignalSpy updateSpy(&test, &RepeatedIntMessage::testRepeatedIntChanged);
+    QSignalSpy movedUpdateSpy(&test2, &RepeatedIntMessage::testRepeatedIntChanged);
+
+    RepeatedIntMessage test3(std::move(test2));
+    test2.setTestRepeatedInt({55,44,11,35});
+
+    test.setProperty(propertyName, QVariant::fromValue<QtProtobuf::int32List>({55}));
+    test.setTestRepeatedInt({44});
+    test = std::move(test2);
+    ASSERT_EQ(QtProtobuf::int32List({55,44,11,35}), test.testRepeatedInt());
+    ASSERT_TRUE(test2.testRepeatedInt().isEmpty());
+    ASSERT_EQ(3, updateSpy.count());
+    ASSERT_EQ(3, movedUpdateSpy.count());
+}
+
 TEST_F(SimpleTest, UnderscoresTest)
 {
     //Sanity compilation checks