Commit 49766ee0 authored by Martin Heistermann's avatar Martin Heistermann

Refactor ResourceManager property requests, much simpler now.

parent 2b9d0a80
......@@ -300,4 +300,87 @@ void ResourceManager::assignAllPropertiesFrom(typename std::conditional<Move, Re
assignProperties<Move>(other->mesh_props_, mesh_props_);
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::Vertex>()
{
return vertex_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::Edge>()
{
return edge_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::HalfEdge>()
{
return halfedge_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::Face>()
{
return face_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::HalfFace>()
{
return halfface_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::Cell>()
{
return cell_props_;
}
template<>
ResourceManager::Properties&
ResourceManager::entity_props<Entity::Mesh>()
{
return mesh_props_;
}
template<>
size_t ResourceManager::n<Entity::Vertex>()
{
return n_vertices();
}
template<>
size_t ResourceManager::n<Entity::Edge>()
{
return n_edges();
}
template<>
size_t ResourceManager::n<Entity::HalfEdge>()
{
return n_halfedges();
}
template<>
size_t ResourceManager::n<Entity::Face>()
{
return n_faces();
}
template<>
size_t ResourceManager::n<Entity::HalfFace>()
{
return n_halffaces();
}
template<>
size_t ResourceManager::n<Entity::Cell>()
{
return n_cells();
}
template<>
size_t ResourceManager::n<Entity::Mesh>()
{
return 1;
}
} // Namespace OpenVolumeMesh
......@@ -136,9 +136,9 @@ public:
virtual size_t n_cells() const = 0;
template<typename T,
typename EntityTag
>
/** Get or create property: if the property does not exist yet, create it.
*/
template<typename T, typename EntityTag>
PropertyTT<T, EntityTag> request_property(const std::string& _name = std::string(), const T _def = T());
template<class T> VertexPropertyT<T> request_vertex_property(const std::string& _name = std::string(), const T _def = T());
......@@ -306,8 +306,11 @@ private:
template<class StdVecT>
void remove_property(StdVecT& _vec, size_t _idx);
template<class StdVecT, class PropT, class HandleT, class T>
PropT internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def = T());
template<typename T, typename EntityTag>
PropertyTT<T, EntityTag> *internal_find_property(const std::string& _name);
template<typename T, typename EntityTag>
PropertyTT<T, EntityTag> internal_create_property(const std::string& _name, const T _def = T());
template<class StdVecT>
void clearVec(StdVecT& _vec);
......@@ -334,6 +337,12 @@ private:
Properties cell_props_;
Properties mesh_props_;
template<typename Entity>
Properties &entity_props();
template<typename Entity>
size_t n();
};
}
......
......@@ -44,123 +44,87 @@ namespace OpenVolumeMesh {
template<class T>
VertexPropertyT<T> ResourceManager::request_vertex_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,VertexPropertyT<T>,VertexPropHandle,T>(vertex_props_, _name, n_vertices(), _def);
return request_property<T, Entity::Vertex>(_name, _def);
}
template<class T>
EdgePropertyT<T> ResourceManager::request_edge_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,EdgePropertyT<T>,EdgePropHandle,T>(edge_props_, _name, n_edges(), _def);
return request_property<T, Entity::Edge>(_name, _def);
}
template<class T>
HalfEdgePropertyT<T> ResourceManager::request_halfedge_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,HalfEdgePropertyT<T>,HalfEdgePropHandle,T>(halfedge_props_, _name, n_edges()*2u, _def);
return request_property<T, Entity::HalfEdge>(_name, _def);
}
template<class T>
FacePropertyT<T> ResourceManager::request_face_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,FacePropertyT<T>,FacePropHandle,T>(face_props_, _name, n_faces(), _def);
return request_property<T, Entity::Face>(_name, _def);
}
template<class T>
HalfFacePropertyT<T> ResourceManager::request_halfface_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,HalfFacePropertyT<T>,HalfFacePropHandle,T>(halfface_props_, _name, n_faces()*2u, _def);
return request_property<T, Entity::HalfFace>(_name, _def);
}
template<class T>
CellPropertyT<T> ResourceManager::request_cell_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,CellPropertyT<T>,CellPropHandle,T>(cell_props_, _name, n_cells(), _def);
return request_property<T, Entity::Cell>(_name, _def);
}
template<class T>
MeshPropertyT<T> ResourceManager::request_mesh_property(const std::string& _name, const T _def) {
return internal_request_property<std::vector<BaseProperty*>,MeshPropertyT<T>,MeshPropHandle,T>(mesh_props_, _name, 1, _def);
return request_property<T, Entity::Mesh>(_name, _def);
}
template<class StdVecT, class PropT, class HandleT, class T>
PropT ResourceManager::internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def)
template<typename T, typename EntityTag>
PropertyTT<T, EntityTag>* ResourceManager::internal_find_property(const std::string& _name)
{
using PropT = PropertyTT<T, EntityTag>;
auto type_name = get_type_name<T>();
auto &propVec = entity_props<EntityTag>();
if(!_name.empty()) {
for(typename StdVecT::iterator it = _vec.begin();
it != _vec.end(); ++it) {
if((*it)->name() == _name
&& (*it)->internal_type_name() == type_name)
for(auto &prop: propVec)
{
if(prop->name() == _name
&& prop->internal_type_name() == type_name)
{
return *static_cast<PropT*>(*it);
return static_cast<PropT*>(prop);
}
}
}
return nullptr;
}
auto handle = HandleT::from_unsigned(_vec.size());
PropT* prop = new PropT(_name, type_name, *this, handle, _def);
prop->resize(_size);
// Store property pointer
_vec.push_back(prop);
template<class T, class EntityTag>
PropertyTT<T, EntityTag> ResourceManager::internal_create_property(const std::string& _name, const T _def)
{
auto type_name = get_type_name<T>();
auto &propVec = entity_props<EntityTag>();
auto handle = PropHandleT<EntityTag>::from_unsigned(propVec.size());
auto prop = new PropertyTT<T, EntityTag>(_name, type_name, *this, handle, _def);
prop->resize(n<EntityTag>());
propVec.push_back(prop);
return *prop;
}
// request_property: work around C++ currently not allowing partial specialisation on functions by using structs:
template<class T, typename EntityTag>
struct request_property_impl {
static PropertyTT<T, EntityTag> _(ResourceManager* /*resman*/, const std::string& /*_name*/, const T /*_def*/);
};
template<class T>
struct request_property_impl<T, Entity::Vertex>{
static PropertyTT<T, Entity::Vertex> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_vertex_property<T>(_name, _def);
}
};
template<class T>
struct request_property_impl<T, Entity::Edge>{
static PropertyTT<T, Entity::Edge> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_edge_property<T>(_name, _def);
}
};
template<class T>
struct request_property_impl<T, Entity::HalfEdge>{
static PropertyTT<T, Entity::HalfEdge> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_halfedge_property<T>(_name, _def);
}
};
template<class T>
struct request_property_impl<T, Entity::Face>{
static PropertyTT<T, Entity::Face> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_face_property<T>(_name, _def);
}
};
template<class T>
struct request_property_impl<T, Entity::HalfFace>{
static PropertyTT<T, Entity::HalfFace> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_halfface_property<T>(_name, _def);
}
};
template<class T>
struct request_property_impl<T, Entity::Cell>{
static PropertyTT<T, Entity::Cell> _(ResourceManager *resman, const std::string &_name, const T _def) {
return resman->request_cell_property<T>(_name, _def);
}
};
template<typename T, typename EntityTag>
PropertyTT<T, EntityTag> ResourceManager::request_property(const std::string& _name, const T _def)
{
return request_property_impl<T, EntityTag>::_(this, _name, _def);
auto *prop = internal_find_property<T, EntityTag>(_name);
if (prop)
return *prop;
return internal_create_property<T, EntityTag>(_name, _def);
}
template<typename T, class EntityTag>
void ResourceManager::set_persistent(PropertyTT<T, EntityTag>& _prop, bool _flag)
{
......
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