|
22 | 22 | #include <gtest/gtest.h> |
23 | 23 |
|
24 | 24 | #include <sofa/core/objectmodel/Data.h> |
| 25 | +#include <sofa/core/objectmodel/DataCallback.h> |
25 | 26 | #include <sofa/type/vector.h> |
26 | 27 |
|
27 | 28 | namespace sofa |
@@ -79,5 +80,74 @@ TEST(WriteAccessor, VectorTypes) |
79 | 80 | EXPECT_FLOAT_EQ(vector.getValue()[3], 6.f); |
80 | 81 | } |
81 | 82 |
|
| 83 | +TEST(WriteAccessor, MoveConstructor) |
| 84 | +{ |
| 85 | + Data<float> floatValue { 12.f }; |
| 86 | + int initialCounter = floatValue.getCounter(); |
| 87 | + |
| 88 | + { |
| 89 | + sofa::helper::WriteAccessor floatAccessor(floatValue); |
| 90 | + EXPECT_EQ(floatValue.getCounter(), initialCounter + 1); |
| 91 | + EXPECT_FLOAT_EQ(floatAccessor.ref(), 12.f); |
| 92 | + |
| 93 | + sofa::helper::WriteAccessor floatAccessorMoved(std::move(floatAccessor)); |
| 94 | + EXPECT_EQ(floatValue.getCounter(), initialCounter + 1); |
| 95 | + EXPECT_FLOAT_EQ(floatAccessorMoved.ref(), 12.f); |
| 96 | + |
| 97 | + // Even if we moved from it, we can still call ref() and wref() |
| 98 | + // but it is not recommended as it doesn't hold the responsibility of endEdit anymore. |
| 99 | + EXPECT_FLOAT_EQ(floatAccessor.ref(), 12.f); |
| 100 | + |
| 101 | + floatAccessorMoved.wref() = 14.f; |
| 102 | + EXPECT_FLOAT_EQ(floatValue.getValue(), 14.f); |
| 103 | + } |
| 104 | + |
| 105 | + Data<float> data { 1.f }; |
| 106 | + int endEditCount = 0; |
| 107 | + sofa::core::objectmodel::DataCallback cb; |
| 108 | + cb.addInput(&data); |
| 109 | + cb.addCallback([&endEditCount](){ |
| 110 | + endEditCount++; |
| 111 | + }); |
| 112 | + |
| 113 | + { |
| 114 | + sofa::helper::WriteAccessor acc1(data); |
| 115 | + EXPECT_EQ(endEditCount, 0); // beginEdit doesn't trigger callback |
| 116 | + { |
| 117 | + sofa::helper::WriteAccessor acc2(std::move(acc1)); |
| 118 | + EXPECT_EQ(endEditCount, 0); |
| 119 | + } |
| 120 | + // acc2 out of scope, endEdit called |
| 121 | + EXPECT_EQ(endEditCount, 1); |
| 122 | + } |
| 123 | + // acc1 out of scope, if move constructor worked correctly, endEdit should NOT be called again. |
| 124 | + EXPECT_EQ(endEditCount, 1); |
| 125 | +} |
| 126 | + |
| 127 | +TEST(WriteAccessor, MoveConstructorVector) |
| 128 | +{ |
| 129 | + Data<sofa::type::vector<float>> vector { sofa::type::vector<float> { 0.f, 1.f, 2.f, 3.f, 4.f} }; |
| 130 | + int endEditCount = 0; |
| 131 | + sofa::core::objectmodel::DataCallback cb; |
| 132 | + cb.addInput(&vector); |
| 133 | + cb.addCallback([&endEditCount](){ |
| 134 | + endEditCount++; |
| 135 | + }); |
| 136 | + |
| 137 | + { |
| 138 | + sofa::helper::WriteAccessor acc1(vector); |
| 139 | + EXPECT_EQ(acc1.size(), 5); |
| 140 | + { |
| 141 | + sofa::helper::WriteAccessor acc2(std::move(acc1)); |
| 142 | + EXPECT_EQ(acc2.size(), 5); |
| 143 | + EXPECT_EQ(acc1.size(), 5); // Still valid but no longer responsible for endEdit |
| 144 | + acc2[0] = 10.f; |
| 145 | + } |
| 146 | + EXPECT_EQ(endEditCount, 1); |
| 147 | + } |
| 148 | + EXPECT_EQ(endEditCount, 1); |
| 149 | + EXPECT_FLOAT_EQ(vector.getValue()[0], 10.f); |
| 150 | +} |
| 151 | + |
82 | 152 |
|
83 | 153 | } |
0 commit comments