Commit 5346f0f0 authored by Mike Kremer's avatar Mike Kremer

Refactored property system to be based on tr1::shared_pointer. The...

Refactored property system to be based on tr1::shared_pointer. The implementation has become way more straightforward.

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@124 66977474-1d4b-4f09-8fe9-267525286df2
parent adb07893
......@@ -55,16 +55,10 @@ class BaseProperty {
public:
friend class ResourceManager;
BaseProperty(ResourceManager& _resMan) : resMan_(_resMan) {}
BaseProperty(const BaseProperty& _cpy) : resMan_(_cpy.resMan_) {}
BaseProperty(ResourceManager& _resMan) : resMan_(_resMan), lock_(false) {}
virtual ~BaseProperty() {}
virtual BaseProperty& operator= (const BaseProperty& _rhs);
virtual BaseProperty& operator= (BaseProperty& _rhs);
virtual const std::string& name() const = 0;
virtual void delete_element(size_t _idx) = 0;
......@@ -73,16 +67,24 @@ public:
virtual std::istream& deserialize(std::istream& _istr) = 0;
virtual OpenVolumeMeshHandle handle() const = 0;
virtual bool persistent() const = 0;
protected:
virtual void resize(unsigned int /*_size*/) = 0;
virtual const void* ptr() const = 0;
virtual void set_handle(const OpenVolumeMeshHandle& /*_handle*/) = 0;
virtual OpenVolumeMeshHandle handle() const = 0;
void lock() { lock_ = true; }
void unlock() { lock_ = false; }
bool locked() const { return lock_; }
ResourceManager& resMan_;
bool lock_;
};
} // Namespace OpenVolumeMesh
......
......@@ -34,26 +34,41 @@
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* $Revision: 36 $ *
* $Date: 2012-01-10 18:00:06 +0100 (Di, 10 Jan 2012) $ *
* $LastChangedBy: kremer $ *
* *
\*===========================================================================*/
#include "BaseProperty.hh"
#ifndef MEMORYINCLUDE_HH_
#define MEMORYINCLUDE_HH_
#include "ResourceManager.hh"
/** This set of defines maps the pointer namespaces to the namespace ptr depending on
* the current architecture and compilers.
*/
#if (__cplusplus >= 201103L)
// C++11:
#include <memory>
namespace ptr = std;
#define ACG_UNIQUE_POINTER_SUPPORTED 1
#elif defined(__GXX_EXPERIMENTAL_CXX0X__)
// C++11 via -std=c++0x on gcc:
#include <memory>
namespace ptr = std;
#define ACG_UNIQUE_POINTER_SUPPORTED 1
#else
// C++98 and TR1:
#if (_MSC_VER >= 1600)
// VStudio 2010 supports some C++11 features
#include <memory>
namespace ptr = std;
#define ACG_UNIQUE_POINTER_SUPPORTED 1
#else
// hope for TR1 equivalents
#include <tr1/memory>
namespace ptr = std::tr1;
#define ACG_UNIQUE_POINTER_SUPPORTED 0
#endif
#endif
namespace OpenVolumeMesh {
BaseProperty& BaseProperty::operator= (const BaseProperty& _rhs) {
resMan_ = _rhs.resMan_;
return *this;
}
BaseProperty& BaseProperty::operator= (BaseProperty& _rhs) {
resMan_ = _rhs.resMan_;
return *this;
}
} // Namespace OpenVolumeMesh
#endif /* MEMORYINCLUDE_HH_ */
......@@ -57,13 +57,13 @@ VertexPropertyT<T>::VertexPropertyT(const std::string& _name, ResourceManager& _
template<class T>
std::ostream& VertexPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "VProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& VertexPropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -76,13 +76,13 @@ EdgePropertyT<T>::EdgePropertyT(const std::string& _name, ResourceManager& _resM
template<class T>
std::ostream& EdgePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "EProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& EdgePropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -95,13 +95,13 @@ HalfEdgePropertyT<T>::HalfEdgePropertyT(const std::string& _name, ResourceManage
template<class T>
std::ostream& HalfEdgePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "HEProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& HalfEdgePropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -114,13 +114,13 @@ FacePropertyT<T>::FacePropertyT(const std::string& _name, ResourceManager& _resM
template<class T>
std::ostream& FacePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "FProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& FacePropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -133,13 +133,13 @@ HalfFacePropertyT<T>::HalfFacePropertyT(const std::string& _name, ResourceManage
template<class T>
std::ostream& HalfFacePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "HFProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& HalfFacePropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -152,13 +152,13 @@ CellPropertyT<T>::CellPropertyT(const std::string& _name, ResourceManager& _resM
template<class T>
std::ostream& CellPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "CProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& CellPropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::get()->deserialize(_istr);
return _istr;
}
......@@ -171,13 +171,13 @@ MeshPropertyT<T>::MeshPropertyT(const std::string& _name, ResourceManager& _resM
template<class T>
std::ostream& MeshPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "MProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::h_->ptr_->serialize(_ostr);
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::get()->serialize(_ostr);
return _ostr;
}
template<class T>
std::istream& MeshPropertyT<T>::deserialize(std::istream& _istr) {
PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::h_->ptr_->deserialize(_istr);
PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::get()->deserialize(_istr);
return _istr;
}
......
......@@ -50,6 +50,8 @@
#include "BaseProperty.hh"
#include "PropertyHandles.hh"
#include "MemoryInclude.hh"
namespace OpenVolumeMesh {
class ResourceManager;
......@@ -63,31 +65,7 @@ class ResourceManager;
*/
template <class PropT, class HandleT>
class PropertyPtr : public BaseProperty {
protected:
/**
* \class Holder
* A helper class that encapsulates a pointer
* to an object and counts its number of references.
*/
class Holder {
public:
Holder(PropT* _ptr) : ptr_(_ptr), count_(1u), persistent_(false) {}
~Holder() {
if(ptr_ != NULL) {
delete ptr_;
ptr_ = NULL;
}
}
PropT* ptr_;
unsigned int count_;
bool persistent_;
};
Holder* h_;
class PropertyPtr : public ptr::shared_ptr<PropT>, public BaseProperty {
public:
friend class ResourceManager;
......@@ -96,56 +74,38 @@ public:
typedef typename PropT::vector_type::const_iterator const_iterator;
typedef typename PropT::vector_type::iterator iterator;
typedef typename PropT::reference reference;
typedef typename PropT::const_reference const_reference;
/// Constructor
PropertyPtr(PropT* _ptr, ResourceManager& _resMan, Handle _handle);
/// Copy Constructor
PropertyPtr(const PropertyPtr<PropT,HandleT>& _cpy);
/// Destructor
virtual ~PropertyPtr();
/// Assignment operator with const reference
PropertyPtr<PropT,HandleT>& operator= (const PropertyPtr<PropT,HandleT>& _rhs);
/// Assignment operator with non-const reference
PropertyPtr<PropT,HandleT>& operator= (PropertyPtr<PropT,HandleT>& _rhs);
const typename PropT::const_reference operator[](size_t _idx) const;
typename PropT::reference operator[](size_t _idx);
virtual const std::string& name() const;
/// Access the encapsulated pointer
PropT* operator->();
/// Access the encapsulated dereferenced pointer
PropT& operator*();
virtual void delete_element(size_t _idx);
unsigned int counter() const { return h_->count_; }
const_iterator begin() const { return ptr::shared_ptr<PropT>::get()->begin(); }
iterator begin() { return ptr::shared_ptr<PropT>::get()->begin(); }
const_iterator begin() const { return h_->ptr_->begin(); }
const_iterator end() const { return ptr::shared_ptr<PropT>::get()->end(); }
iterator end() { return ptr::shared_ptr<PropT>::get()->end(); }
iterator begin() { return h_->ptr_->begin(); }
reference operator[](size_t _idx) { return (*ptr::shared_ptr<PropT>::get())[_idx]; }
const_reference operator[](size_t _idx) const { return (*ptr::shared_ptr<PropT>::get())[_idx]; }
const_iterator end() const { return h_->ptr_->end(); }
virtual OpenVolumeMeshHandle handle() const;
iterator end() { return h_->ptr_->end(); }
virtual bool persistent() const { return ptr::shared_ptr<PropT>::get()->persistent(); }
protected:
virtual void resize(unsigned int _size);
virtual const void* ptr() const { return h_->ptr_; }
virtual void set_handle(const OpenVolumeMeshHandle& _handle);
virtual OpenVolumeMeshHandle handle() const;
private:
Handle handle_;
......
......@@ -49,85 +49,37 @@
namespace OpenVolumeMesh {
template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>::PropertyPtr(PropT* _ptr, ResourceManager& _resMan, Handle _handle) :
BaseProperty(_resMan), h_(new Holder(_ptr)), handle_(_handle) {
}
template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>::PropertyPtr(const PropertyPtr<PropT,HandleT>& _cpy) :
BaseProperty(_cpy), h_(_cpy.h_), handle_(_cpy.handle_) {
++h_->count_;
PropertyPtr<PropT,HandleT>::PropertyPtr(PropT* _ptr, ResourceManager& _resMan, HandleT _handle) :
ptr::shared_ptr<PropT>(_ptr), BaseProperty(_resMan), handle_(_handle) {
}
template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>::~PropertyPtr() {
if(--h_->count_ == 0) {
resMan_.released_property(handle_);
delete h_;
}
}
template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>&
PropertyPtr<PropT,HandleT>::operator= (const PropertyPtr<PropT,HandleT>& _rhs) {
if(--h_->count_ == 0) delete h_;
h_ = _rhs.h_;
++h_->count_;
return *this;
}
template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>&
PropertyPtr<PropT,HandleT>::operator= (PropertyPtr<PropT,HandleT>& _rhs) {
if(--h_->count_ == 0) delete h_;
h_ = _rhs.h_;
++h_->count_;
return *this;
}
template <class PropT, class HandleT>
const typename PropT::const_reference
PropertyPtr<PropT,HandleT>::operator[](size_t _idx) const {
assert(h_->ptr_->n_elements() > _idx);
return (*h_->ptr_)[_idx];
}
template <class PropT, class HandleT>
typename PropT::reference
PropertyPtr<PropT,HandleT>::operator[](size_t _idx) {
assert(h_->ptr_->n_elements() > _idx);
return (*h_->ptr_)[_idx];
/*
* If use count is 2 and prop is not set persistent,
* remove it, since the resource manager is the
* only one who stores the property.
*/
if(!locked() && !persistent() && ptr::shared_ptr<PropT>::use_count() == 2) {
resMan_.release_property(handle_);
unlock();
}
}
template <class PropT, class HandleT>
void PropertyPtr<PropT,HandleT>::resize(unsigned int _size) {
h_->ptr_->resize(_size);
ptr::shared_ptr<PropT>::get()->resize(_size);
}
template <class PropT, class HandleT>
const std::string& PropertyPtr<PropT,HandleT>::name() const {
return h_->ptr_->name();
}
template <class PropT, class HandleT>
PropT* PropertyPtr<PropT,HandleT>::operator->() {
return h_->ptr_;
}
template <class PropT, class HandleT>
PropT& PropertyPtr<PropT,HandleT>::operator*() {
return *h_->ptr_;
return ptr::shared_ptr<PropT>::get()->name();
}
template <class PropT, class HandleT>
void PropertyPtr<PropT,HandleT>::delete_element(size_t _idx) {
h_->ptr_->delete_element(_idx);
ptr::shared_ptr<PropT>::get()->delete_element(_idx);
}
template <class PropT, class HandleT>
......
......@@ -50,201 +50,95 @@ ResourceManager::ResourceManager() {
ResourceManager::~ResourceManager() {
// Delete all persistent properties
for(std::vector<BaseProperty*>::iterator it = persistent_vprops_.begin();
it != persistent_vprops_.end(); ++it) {
delete *it;
}
persistent_vprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_eprops_.begin();
it != persistent_eprops_.end(); ++it) {
delete *it;
}
persistent_eprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_heprops_.begin();
it != persistent_heprops_.end(); ++it) {
delete *it;
}
persistent_heprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_fprops_.begin();
it != persistent_fprops_.end(); ++it) {
delete *it;
}
persistent_fprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_hfprops_.begin();
it != persistent_hfprops_.end(); ++it) {
delete *it;
}
persistent_hfprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_cprops_.begin();
it != persistent_cprops_.end(); ++it) {
delete *it;
}
persistent_cprops_.clear();
for(std::vector<BaseProperty*>::iterator it = persistent_mprops_.begin();
it != persistent_mprops_.end(); ++it) {
delete *it;
}
persistent_mprops_.clear();
// Delete persistent props
clearVec(vertex_props_);
clearVec(edge_props_);
clearVec(halfedge_props_);
clearVec(face_props_);
clearVec(halfface_props_);
clearVec(cell_props_);
clearVec(mesh_props_);
}
void ResourceManager::resize_vprops(unsigned int _nv) {
for(std::vector<BaseProperty*>::iterator it = vertex_props_.begin();
it != vertex_props_.end(); ++it) {
(*it)->resize(_nv);
}
resize_props(vertex_props_, _nv);
}
void ResourceManager::resize_eprops(unsigned int _ne) {
for(std::vector<BaseProperty*>::iterator it = edge_props_.begin();
it != edge_props_.end(); ++it) {
(*it)->resize(_ne);
}
for(std::vector<BaseProperty*>::iterator it = halfedge_props_.begin();
it != halfedge_props_.end(); ++it) {
(*it)->resize(2u*_ne);
}
resize_props(edge_props_, _ne);
resize_props(halfedge_props_, _ne*2u);
}
void ResourceManager::resize_fprops(unsigned int _nf) {
for(std::vector<BaseProperty*>::iterator it = face_props_.begin();
it != face_props_.end(); ++it) {
(*it)->resize(_nf);
}
for(std::vector<BaseProperty*>::iterator it = halfface_props_.begin();
it != halfface_props_.end(); ++it) {
(*it)->resize(2u*_nf);
}
resize_props(face_props_, _nf);
resize_props(halfface_props_, _nf*2u);
}
void ResourceManager::resize_cprops(unsigned int _nc) {
for(std::vector<BaseProperty*>::iterator it = cell_props_.begin();
it != cell_props_.end(); ++it) {
(*it)->resize(_nc);
}
resize_props(cell_props_, _nc);
}
void ResourceManager::vertex_deleted(const VertexHandle& _h) {
for(std::vector<BaseProperty*>::iterator it = vertex_props_.begin();
it != vertex_props_.end(); ++it) {
(*it)->delete_element(_h.idx());
}
entity_deleted(vertex_props_, _h);
}
void ResourceManager::edge_deleted(const EdgeHandle& _h) {
for(std::vector<BaseProperty*>::iterator it = edge_props_.begin();
it != edge_props_.end(); ++it) {
(*it)->delete_element(_h.idx());
}
for(std::vector<BaseProperty*>::iterator it = halfedge_props_.begin();
it != halfedge_props_.end(); ++it) {
(*it)->delete_element(_h.idx()*2 + 1);
(*it)->delete_element(_h.idx()*2);
}
entity_deleted(edge_props_, _h);
entity_deleted(halfedge_props_, OpenVolumeMeshHandle(_h.idx()*2 + 1));
entity_deleted(halfedge_props_, OpenVolumeMeshHandle(_h.idx()*2));
}
void ResourceManager::face_deleted(const FaceHandle& _h) {
for(std::vector<BaseProperty*>::iterator it = face_props_.begin();
it != face_props_.end(); ++it) {
(*it)->delete_element(_h.idx());
}
for(std::vector<BaseProperty*>::iterator it = halfface_props_.begin();
it != halfface_props_.end(); ++it) {
(*it)->delete_element(_h.idx()*2 + 1);
(*it)->delete_element(_h.idx()*2);
}
entity_deleted(face_props_, _h);
entity_deleted(halfface_props_, OpenVolumeMeshHandle(_h.idx()*2 + 1));
entity_deleted(halfface_props_, OpenVolumeMeshHandle(_h.idx()*2));
}
void ResourceManager::cell_deleted(const CellHandle& _h) {
for(std::vector<BaseProperty*>::iterator it = cell_props_.begin();
it != cell_props_.end(); ++it) {
(*it)->delete_element(_h.idx());
}
entity_deleted(cell_props_, _h);
}
void ResourceManager::released_property(VertexPropHandle _handle) {
void ResourceManager::release_property(VertexPropHandle _handle) {
delete (*(vertex_props_.begin() + _handle.idx()));
std::vector<BaseProperty*>::iterator it = vertex_props_.erase(vertex_props_.begin() + _handle.idx());
VertexPropHandle decrHandle(_handle.idx());
for(; it < vertex_props_.end(); ++it) {
(*it)->set_handle(decrHandle);
decrHandle.idx(decrHandle.idx()+1);
}
remove_property(vertex_props_, _handle.idx());
}
void ResourceManager::released_property(EdgePropHandle _handle) {
void ResourceManager::release_property(EdgePropHandle _handle) {
delete (*(edge_props_.begin() + _handle.idx()));
std::vector<BaseProperty*>::iterator it = edge_props_.erase(edge_props_.begin() + _handle.idx());
EdgePropHandle decrHandle(_handle.idx());
for(; it < edge_props_.end(); ++it) {
(*it)->set_handle(decrHandle);
decrHandle.idx(decrHandle.idx()+1);
}
remove_property(edge_props_, _handle.idx());
}
void ResourceManager::released_property(HalfEdgePropHandle _handle) {
void ResourceManager::release_property(HalfEdgePropHandle _handle) {
delete (*(halfedge_props_.begin() + _handle.idx()));
std::vector<BaseProperty*>::iterator it = halfedge_props_.erase(halfedge_props_.begin() + _handle.idx());
HalfEdgePropHandle decrHandle(_handle.idx());
for(; it < halfedge_props_.end(); ++it) {
(*it)->set_handle(decrHandle);
decrHandle.idx(decrHandle.idx()+1);
}
remove_property(halfedge_props_, _handle.idx());
}
void ResourceManager::released_property(FacePropHandle _handle) {
void ResourceManager