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

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 { ...@@ -55,16 +55,10 @@ class BaseProperty {
public: public:
friend class ResourceManager; friend class ResourceManager;
BaseProperty(ResourceManager& _resMan) : resMan_(_resMan) {} BaseProperty(ResourceManager& _resMan) : resMan_(_resMan), lock_(false) {}
BaseProperty(const BaseProperty& _cpy) : resMan_(_cpy.resMan_) {}
virtual ~BaseProperty() {} virtual ~BaseProperty() {}
virtual BaseProperty& operator= (const BaseProperty& _rhs);
virtual BaseProperty& operator= (BaseProperty& _rhs);
virtual const std::string& name() const = 0; virtual const std::string& name() const = 0;
virtual void delete_element(size_t _idx) = 0; virtual void delete_element(size_t _idx) = 0;
...@@ -73,16 +67,24 @@ public: ...@@ -73,16 +67,24 @@ public:
virtual std::istream& deserialize(std::istream& _istr) = 0; virtual std::istream& deserialize(std::istream& _istr) = 0;
virtual OpenVolumeMeshHandle handle() const = 0;
virtual bool persistent() const = 0;
protected: protected:
virtual void resize(unsigned int /*_size*/) = 0; virtual void resize(unsigned int /*_size*/) = 0;
virtual const void* ptr() const = 0;
virtual void set_handle(const OpenVolumeMeshHandle& /*_handle*/) = 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_; ResourceManager& resMan_;
bool lock_;
}; };
} // Namespace OpenVolumeMesh } // Namespace OpenVolumeMesh
......
...@@ -34,26 +34,41 @@ ...@@ -34,26 +34,41 @@
/*===========================================================================*\ /*===========================================================================*\
* * * *
* $Revision$ * * $Revision: 36 $ *
* $Date$ * * $Date: 2012-01-10 18:00:06 +0100 (Di, 10 Jan 2012) $ *
* $LastChangedBy$ * * $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 { #endif /* MEMORYINCLUDE_HH_ */
BaseProperty& BaseProperty::operator= (const BaseProperty& _rhs) {
resMan_ = _rhs.resMan_;
return *this;
}
BaseProperty& BaseProperty::operator= (BaseProperty& _rhs) {
resMan_ = _rhs.resMan_;
return *this;
}
} // Namespace OpenVolumeMesh
...@@ -57,13 +57,13 @@ VertexPropertyT<T>::VertexPropertyT(const std::string& _name, ResourceManager& _ ...@@ -57,13 +57,13 @@ VertexPropertyT<T>::VertexPropertyT(const std::string& _name, ResourceManager& _
template<class T> template<class T>
std::ostream& VertexPropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& VertexPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "VProp" << std::endl; _ostr << "VProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, VertexPropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& VertexPropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -76,13 +76,13 @@ EdgePropertyT<T>::EdgePropertyT(const std::string& _name, ResourceManager& _resM ...@@ -76,13 +76,13 @@ EdgePropertyT<T>::EdgePropertyT(const std::string& _name, ResourceManager& _resM
template<class T> template<class T>
std::ostream& EdgePropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& EdgePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "EProp" << std::endl; _ostr << "EProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, EdgePropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& EdgePropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -95,13 +95,13 @@ HalfEdgePropertyT<T>::HalfEdgePropertyT(const std::string& _name, ResourceManage ...@@ -95,13 +95,13 @@ HalfEdgePropertyT<T>::HalfEdgePropertyT(const std::string& _name, ResourceManage
template<class T> template<class T>
std::ostream& HalfEdgePropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& HalfEdgePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "HEProp" << std::endl; _ostr << "HEProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfEdgePropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& HalfEdgePropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -114,13 +114,13 @@ FacePropertyT<T>::FacePropertyT(const std::string& _name, ResourceManager& _resM ...@@ -114,13 +114,13 @@ FacePropertyT<T>::FacePropertyT(const std::string& _name, ResourceManager& _resM
template<class T> template<class T>
std::ostream& FacePropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& FacePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "FProp" << std::endl; _ostr << "FProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, FacePropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& FacePropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -133,13 +133,13 @@ HalfFacePropertyT<T>::HalfFacePropertyT(const std::string& _name, ResourceManage ...@@ -133,13 +133,13 @@ HalfFacePropertyT<T>::HalfFacePropertyT(const std::string& _name, ResourceManage
template<class T> template<class T>
std::ostream& HalfFacePropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& HalfFacePropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "HFProp" << std::endl; _ostr << "HFProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, HalfFacePropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& HalfFacePropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -152,13 +152,13 @@ CellPropertyT<T>::CellPropertyT(const std::string& _name, ResourceManager& _resM ...@@ -152,13 +152,13 @@ CellPropertyT<T>::CellPropertyT(const std::string& _name, ResourceManager& _resM
template<class T> template<class T>
std::ostream& CellPropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& CellPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "CProp" << std::endl; _ostr << "CProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, CellPropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& CellPropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
...@@ -171,13 +171,13 @@ MeshPropertyT<T>::MeshPropertyT(const std::string& _name, ResourceManager& _resM ...@@ -171,13 +171,13 @@ MeshPropertyT<T>::MeshPropertyT(const std::string& _name, ResourceManager& _resM
template<class T> template<class T>
std::ostream& MeshPropertyT<T>::serialize(std::ostream& _ostr) const { std::ostream& MeshPropertyT<T>::serialize(std::ostream& _ostr) const {
_ostr << "MProp" << std::endl; _ostr << "MProp" << std::endl;
_ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::h_->ptr_->serialize(_ostr); _ostr << PropertyPtr<OpenVolumeMeshPropertyT<T>, MeshPropHandle>::get()->serialize(_ostr);
return _ostr; return _ostr;
} }
template<class T> template<class T>
std::istream& MeshPropertyT<T>::deserialize(std::istream& _istr) { 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; return _istr;
} }
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
#include "BaseProperty.hh" #include "BaseProperty.hh"
#include "PropertyHandles.hh" #include "PropertyHandles.hh"
#include "MemoryInclude.hh"
namespace OpenVolumeMesh { namespace OpenVolumeMesh {
class ResourceManager; class ResourceManager;
...@@ -63,31 +65,7 @@ class ResourceManager; ...@@ -63,31 +65,7 @@ class ResourceManager;
*/ */
template <class PropT, class HandleT> template <class PropT, class HandleT>
class PropertyPtr : public BaseProperty { class PropertyPtr : public ptr::shared_ptr<PropT>, 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_;
public: public:
friend class ResourceManager; friend class ResourceManager;
...@@ -96,56 +74,38 @@ public: ...@@ -96,56 +74,38 @@ public:
typedef typename PropT::vector_type::const_iterator const_iterator; typedef typename PropT::vector_type::const_iterator const_iterator;
typedef typename PropT::vector_type::iterator iterator; typedef typename PropT::vector_type::iterator iterator;
typedef typename PropT::reference reference;
typedef typename PropT::const_reference const_reference;
/// Constructor /// Constructor
PropertyPtr(PropT* _ptr, ResourceManager& _resMan, Handle _handle); PropertyPtr(PropT* _ptr, ResourceManager& _resMan, Handle _handle);
/// Copy Constructor
PropertyPtr(const PropertyPtr<PropT,HandleT>& _cpy);
/// Destructor /// Destructor
virtual ~PropertyPtr(); 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; 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); 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: protected:
virtual void resize(unsigned int _size); virtual void resize(unsigned int _size);
virtual const void* ptr() const { return h_->ptr_; }
virtual void set_handle(const OpenVolumeMeshHandle& _handle); virtual void set_handle(const OpenVolumeMeshHandle& _handle);
virtual OpenVolumeMeshHandle handle() const;
private: private:
Handle handle_; Handle handle_;
......
...@@ -49,85 +49,37 @@ ...@@ -49,85 +49,37 @@
namespace OpenVolumeMesh { namespace OpenVolumeMesh {
template <class PropT, class HandleT> template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>::PropertyPtr(PropT* _ptr, ResourceManager& _resMan, Handle _handle) : PropertyPtr<PropT,HandleT>::PropertyPtr(PropT* _ptr, ResourceManager& _resMan, HandleT _handle) :
BaseProperty(_resMan), h_(new Holder(_ptr)), handle_(_handle) { ptr::shared_ptr<PropT>(_ptr), BaseProperty(_resMan), 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_;
} }
template <class PropT, class HandleT> template <class PropT, class HandleT>
PropertyPtr<PropT,HandleT>::~PropertyPtr() { 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_; * If use count is 2 and prop is not set persistent,
* remove it, since the resource manager is the
return *this; * only one who stores the property.
} */
if(!locked() && !persistent() && ptr::shared_ptr<PropT>::use_count() == 2) {
template <class PropT, class HandleT> resMan_.release_property(handle_);
const typename PropT::const_reference unlock();
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];
} }
template <class PropT, class HandleT> template <class PropT, class HandleT>
void PropertyPtr<PropT,HandleT>::resize(unsigned int _size) { void PropertyPtr<PropT,HandleT>::resize(unsigned int _size) {
h_->ptr_->resize(_size); ptr::shared_ptr<PropT>::get()->resize(_size);
} }
template <class PropT, class HandleT> template <class PropT, class HandleT>
const std::string& PropertyPtr<PropT,HandleT>::name() const { const std::string& PropertyPtr<PropT,HandleT>::name() const {
return h_->ptr_->name(); return ptr::shared_ptr<PropT>::get()->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_;
} }
template <class PropT, class HandleT> template <class PropT, class HandleT>
void PropertyPtr<PropT,HandleT>::delete_element(size_t _idx) { 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> template <class PropT, class HandleT>
......
...@@ -50,201 +50,95 @@ ResourceManager::ResourceManager() { ...@@ -50,201 +50,95 @@ ResourceManager::ResourceManager() {
ResourceManager::~ResourceManager() { ResourceManager::~ResourceManager() {
// Delete all persistent properties // Delete persistent props
for(std::vector<BaseProperty*>::iterator it = persistent_vprops_.begin(); clearVec(vertex_props_);
it != persistent_vprops_.end(); ++it) { clearVec(edge_props_);
delete *it; clearVec(halfedge_props_);
} clearVec(face_props_);
persistent_vprops_.clear(); clearVec(halfface_props_);
for(std::vector<BaseProperty*>::iterator it = persistent_eprops_.begin(); clearVec(cell_props_);
it != persistent_eprops_.end(); ++it) { clearVec(mesh_props_);
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;