Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Sofa/framework/Core/src/sofa/core/objectmodel/Data.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,14 +409,27 @@ class WriteAccessor< core::objectmodel::Data<T> > : public WriteAccessor<T>

protected:
data_container_type& data;
bool m_moved = false;

/// @internal used by WriteOnlyAccessor
WriteAccessor( container_type* c, data_container_type& d) : Inherit(*c), data(d) {}

public:
WriteAccessor(WriteAccessor&& other) noexcept : Inherit(std::move(other)), data(other.data)
{
other.m_moved = true;
}

WriteAccessor(data_container_type& d) : Inherit(*d.beginEdit()), data(d) {}
WriteAccessor(data_container_type* d) : Inherit(*d->beginEdit()), data(*d) {}
~WriteAccessor() { data.endEdit(); }

~WriteAccessor()
{
if (!m_moved)
{
data.endEdit();
}
}
};


Expand Down
4 changes: 2 additions & 2 deletions Sofa/framework/Core/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.22)
project(Sofa.Core_test)

set(SOURCE_FILES
accessor/ReadAccessor.cpp
accessor/WriteAccessor.cpp
accessor/ReadAccessor_test.cpp
accessor/WriteAccessor_test.cpp
collision/NarrowPhaseDetection_test.cpp
loader/MeshLoader_test.cpp
objectmodel/AspectPool_test.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <gtest/gtest.h>

#include <sofa/core/objectmodel/Data.h>
#include <sofa/core/objectmodel/DataCallback.h>
#include <sofa/type/vector.h>

namespace sofa
Expand Down Expand Up @@ -79,5 +80,74 @@ TEST(WriteAccessor, VectorTypes)
EXPECT_FLOAT_EQ(vector.getValue()[3], 6.f);
}

TEST(WriteAccessor, MoveConstructor)
{
Data<float> floatValue { 12.f };
int initialCounter = floatValue.getCounter();

{
sofa::helper::WriteAccessor floatAccessor(floatValue);
EXPECT_EQ(floatValue.getCounter(), initialCounter + 1);
EXPECT_FLOAT_EQ(floatAccessor.ref(), 12.f);

sofa::helper::WriteAccessor floatAccessorMoved(std::move(floatAccessor));
EXPECT_EQ(floatValue.getCounter(), initialCounter + 1);
EXPECT_FLOAT_EQ(floatAccessorMoved.ref(), 12.f);

// Even if we moved from it, we can still call ref() and wref()
// but it is not recommended as it doesn't hold the responsibility of endEdit anymore.
EXPECT_FLOAT_EQ(floatAccessor.ref(), 12.f);

floatAccessorMoved.wref() = 14.f;
EXPECT_FLOAT_EQ(floatValue.getValue(), 14.f);
}

Data<float> data { 1.f };
int endEditCount = 0;
sofa::core::objectmodel::DataCallback cb;
cb.addInput(&data);
cb.addCallback([&endEditCount](){
endEditCount++;
});

{
sofa::helper::WriteAccessor acc1(data);
EXPECT_EQ(endEditCount, 0); // beginEdit doesn't trigger callback
{
sofa::helper::WriteAccessor acc2(std::move(acc1));
EXPECT_EQ(endEditCount, 0);
}
// acc2 out of scope, endEdit called
EXPECT_EQ(endEditCount, 1);
}
// acc1 out of scope, if move constructor worked correctly, endEdit should NOT be called again.
EXPECT_EQ(endEditCount, 1);
}

TEST(WriteAccessor, MoveConstructorVector)
{
Data<sofa::type::vector<float>> vector { sofa::type::vector<float> { 0.f, 1.f, 2.f, 3.f, 4.f} };
int endEditCount = 0;
sofa::core::objectmodel::DataCallback cb;
cb.addInput(&vector);
cb.addCallback([&endEditCount](){
endEditCount++;
});

{
sofa::helper::WriteAccessor acc1(vector);
EXPECT_EQ(acc1.size(), 5);
{
sofa::helper::WriteAccessor acc2(std::move(acc1));
EXPECT_EQ(acc2.size(), 5);
EXPECT_EQ(acc1.size(), 5); // Still valid but no longer responsible for endEdit
acc2[0] = 10.f;
}
EXPECT_EQ(endEditCount, 1);
}
EXPECT_EQ(endEditCount, 1);
EXPECT_FLOAT_EQ(vector.getValue()[0], 10.f);
}


}
4 changes: 2 additions & 2 deletions Sofa/framework/Helper/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ set(SOURCE_FILES
StringUtils_test.cpp
TagFactory_test.cpp
Utils_test.cpp
accessor/ReadAccessor.cpp
accessor/WriteAccessor.cpp
accessor/ReadAccessor_test.cpp
accessor/WriteAccessor_test.cpp
io/MeshOBJ_test.cpp
io/STBImage_test.cpp
io/XspLoader_test.cpp
Expand Down
Loading