Commit b94ca35b authored by Martin Heistermann's avatar Martin Heistermann

implement assigning and moving properties; make ResourceManager move...

implement assigning and moving properties; make ResourceManager move assignment consistent with copy assignment
parent ba19b93a
Pipeline #10419 passed with stage
in 4 minutes and 19 seconds
......@@ -97,6 +97,10 @@ protected:
/// Currently no type check is performed.
virtual void assign_values_from(const BaseProperty *other) = 0;
/// Move data from other property. `other` MUST point to an object with the same type as `this`!
/// Currently no type check is performed.
virtual void move_values_from(BaseProperty *other) = 0;
virtual void delete_multiple_entries(const std::vector<bool>& _tags) = 0;
virtual void resize(size_t /*_size*/) = 0;
......
......@@ -116,6 +116,7 @@ public:
protected:
void assign_values_from(const BaseProperty *other) override;
void move_values_from(BaseProperty *other) override;
virtual void delete_multiple_entries(const std::vector<bool>& _tags);
......
......@@ -66,6 +66,13 @@ void PropertyPtr<PropT,Entity>::assign_values_from(const BaseProperty *other) {
ptr::shared_ptr<PropT>::get()->data_vector() = _other->get()->data_vector();
}
template <class PropT, typename Entity>
void PropertyPtr<PropT,Entity>::move_values_from(BaseProperty *other) {
auto _other = static_cast<PropertyPtr<PropT,Entity>*>(other);
// FIXME: would be nice to perform a type check here
ptr::shared_ptr<PropT>::get()->data_vector() = std::move(_other->get()->data_vector());
}
template <class PropT, typename Entity>
void PropertyPtr<PropT,Entity>::resize(size_t _size) {
ptr::shared_ptr<PropT>::get()->resize(_size);
......
......@@ -51,42 +51,8 @@ ResourceManager& ResourceManager::operator=(const ResourceManager &other)
if (this == &other)
return *this;
auto cloneProps = [this](const Properties &src, Properties &dest)
{
// If possible, re-use existing properties instead of copying
// everything blindly.
// This way, references to properties of `this` do not expire
// if a corresponding property exists in `other`, e.g. attributes.
Properties out;
out.reserve(src.size());
for (BaseProperty *srcprop: src) {
bool found = false;
for (auto it = dest.begin(); it != dest.end(); ++it) {
auto dstprop = *it;
if (dstprop->name() == srcprop->name())
{
// TODO: type check
out.push_back(dstprop);
dest.erase(it);
dstprop->assign_values_from(srcprop);
found = true;
break;
}
}
if (!found) {
out.push_back(srcprop->clone(*this, OpenVolumeMeshHandle(-1)));
}
}
updatePropHandles(out);
dest = std::move(out);
};
cloneProps(other.vertex_props_, vertex_props_);
cloneProps(other.edge_props_, edge_props_);
cloneProps(other.halfedge_props_, halfedge_props_);
cloneProps(other.face_props_, face_props_);
cloneProps(other.halfface_props_, halfface_props_);
cloneProps(other.cell_props_, cell_props_);
cloneProps(other.mesh_props_, mesh_props_);
assignAllPropertiesFrom<false>(&other);
return *this;
}
......@@ -95,20 +61,8 @@ ResourceManager& ResourceManager::operator=(ResourceManager &&other)
if (this == &other)
return *this;
auto moveProps = [this](Properties &&src, Properties &dest){
// TODO: check for existing properties and move data contents instead of Property classes
dest = std::move(src);
for (auto prop: dest) {
prop->setResMan(this);
}
};
moveProps(std::move(other.vertex_props_), vertex_props_);
moveProps(std::move(other.edge_props_), edge_props_);
moveProps(std::move(other.halfedge_props_), halfedge_props_);
moveProps(std::move(other.face_props_), face_props_);
moveProps(std::move(other.halfface_props_), halfface_props_);
moveProps(std::move(other.cell_props_), cell_props_);
moveProps(std::move(other.mesh_props_), mesh_props_);
assignAllPropertiesFrom<true>(&other);
return *this;
}
......@@ -295,4 +249,54 @@ void ResourceManager::delete_multiple_cell_props(const std::vector<bool>& _tags)
}
}
template<bool Move>
void ResourceManager::assignProperties(typename std::conditional<Move, Properties&, const Properties&>::type src,
Properties &dest)
{
// If possible, re-use existing properties instead of copying
// everything blindly.
Properties out;
out.reserve(src.size());
for (BaseProperty *srcprop: src) {
bool found = false;
for (auto it = dest.begin(); it != dest.end(); ++it) {
auto dstprop = *it;
if (dstprop->name() == srcprop->name())
{
// TODO: type check
out.push_back(dstprop);
dest.erase(it);
if (Move) {
dstprop->move_values_from(srcprop);
} else {
dstprop->assign_values_from(srcprop);
}
found = true;
break;
}
}
if (!found) {
if (Move) {
out.push_back(srcprop);
} else {
out.push_back(srcprop->clone(*this, OpenVolumeMeshHandle(-1)));
}
}
}
updatePropHandles(out);
dest = std::move(out);
}
template<bool Move>
void ResourceManager::assignAllPropertiesFrom(typename std::conditional<Move, ResourceManager*, const ResourceManager*>::type other)
{
assignProperties<Move>(other->vertex_props_, vertex_props_);
assignProperties<Move>(other->edge_props_, edge_props_);
assignProperties<Move>(other->halfedge_props_, halfedge_props_);
assignProperties<Move>(other->face_props_, face_props_);
assignProperties<Move>(other->halfface_props_, halfface_props_);
assignProperties<Move>(other->cell_props_, cell_props_);
assignProperties<Move>(other->mesh_props_, mesh_props_);
}
} // Namespace OpenVolumeMesh
......@@ -39,6 +39,7 @@
#endif
#include <string>
#include <vector>
#include <type_traits>
#include "OpenVolumeMeshProperty.hh"
#include "PropertyHandles.hh"
......@@ -316,6 +317,12 @@ private:
template<class StdVecT>
void updatePropHandles(StdVecT& _vec);
template<bool Move>
void assignProperties(typename std::conditional<Move, Properties&, const Properties&>::type src,
Properties &dest);
template<bool Move>
void assignAllPropertiesFrom(typename std::conditional<Move, ResourceManager*, const ResourceManager*>::type src);
Properties vertex_props_;
Properties edge_props_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment