Commit c296f245 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'dev-mh-prop' into 'master'

Properties: Store and compare type names instead of relying on dynamic_cast

See merge request !57
parents b8e6f3d7 435cf124
Pipeline #10506 failed with stage
in 4 minutes and 48 seconds
......@@ -32,14 +32,6 @@
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef BASEPROPERTY_HH_
#define BASEPROPERTY_HH_
......@@ -93,6 +85,8 @@ public:
protected:
virtual const std::string &internal_type_name() const = 0;
/// Copy data from other property. `other` MUST point to an object with the same type as `this`!
/// Currently no type check is performed.
virtual void assign_values_from(const BaseProperty *other) = 0;
......
......@@ -32,15 +32,6 @@
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* $LastChangedBy$ *
* *
\*===========================================================================*/
#ifndef OPENVOLUMEMESHBASEPROPERTY_HH
#define OPENVOLUMEMESHBASEPROPERTY_HH
......@@ -71,9 +62,14 @@ public:
public:
explicit OpenVolumeMeshBaseProperty(const std::string& _name = "<unknown>") :
name_(_name), persistent_(false), handle_(-1) {
}
explicit OpenVolumeMeshBaseProperty(
const std::string& _name = "<unknown>",
const std::string& _internal_type_name = "<unknown>")
: name_(_name),
internal_type_name_(_internal_type_name),
persistent_(false),
handle_(-1)
{}
OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) = default;
......@@ -107,6 +103,10 @@ public:
return name_;
}
const std::string& internal_type_name() const {
return internal_type_name_;
}
// Function to serialize a property
virtual void serialize(std::ostream& /*_ostr*/) const {}
......@@ -148,6 +148,7 @@ protected:
private:
std::string name_;
std::string internal_type_name_;
bool persistent_;
......
......@@ -62,7 +62,7 @@ template<class T>
class OpenVolumeMeshPropertyT: public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
template <class PropT, class Entity> friend class PropertyPtr;
typedef T Value;
typedef std::vector<T> vector_type;
......@@ -72,10 +72,13 @@ public:
public:
OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const T &_def = T()) :
OpenVolumeMeshBaseProperty(_name),
def_(_def) {
}
explicit OpenVolumeMeshPropertyT(
const std::string& _name = "<unknown>",
const std::string& _internal_type_name = "<unknown>",
const T &_def = T())
: OpenVolumeMeshBaseProperty(_name, _internal_type_name),
def_(_def)
{}
OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
......
......@@ -89,7 +89,7 @@ public:
: PropertyTT(std::move(mesh->template request_property<T, Entity>(_name, _def)))
{}
using PropertyHandleT = OpenVolumeMesh::PropHandleT<Entity>;
PropertyTT(const std::string& _name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def = T());
PropertyTT(const std::string& _name, const std::string& _internal_type_name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def = T());
virtual ~PropertyTT() = default;
virtual BaseProperty* clone(ResourceManager &_resMan, OpenVolumeMeshHandle _handle) const;
virtual const std::string entityType() const { return entityTypeName<Entity>(); }
......
......@@ -42,8 +42,8 @@
namespace OpenVolumeMesh {
template<typename T, typename Entity>
PropertyTT<T,Entity>::PropertyTT(const std::string& _name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def) :
PropertyPtr<OpenVolumeMeshPropertyT<T>, Entity>(new OpenVolumeMeshPropertyT<T>(_name, _def), _resMan, _handle) {
PropertyTT<T,Entity>::PropertyTT(const std::string& _name, const std::string& _internal_type_name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def) :
PropertyPtr<OpenVolumeMeshPropertyT<T>, Entity>(new OpenVolumeMeshPropertyT<T>(_name, _internal_type_name, _def), _resMan, _handle) {
}
......
......@@ -114,6 +114,7 @@ public:
virtual bool anonymous() const { return ptr::shared_ptr<PropT>::get()->name().empty(); }
protected:
virtual const std::string &internal_type_name() const { return ptr::shared_ptr<PropT>::get()->internal_type_name(); }
void assign_values_from(const BaseProperty *other) override;
void move_values_from(BaseProperty *other) override;
......
......@@ -309,7 +309,7 @@ private:
void remove_property(StdVecT& _vec, size_t _idx);
template<class StdVecT, class PropT, class HandleT, class T>
PropT request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def = T());
PropT internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def = T());
template<class StdVecT>
void clearVec(StdVecT& _vec);
......
......@@ -44,71 +44,72 @@
#include "ResourceManager.hh"
#include "PropertyDefines.hh"
#include "TypeName.hh"
namespace OpenVolumeMesh {
template<class T>
VertexPropertyT<T> ResourceManager::request_vertex_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,VertexPropertyT<T>,VertexPropHandle,T>(vertex_props_, _name, n_vertices(), _def);
return internal_request_property<std::vector<BaseProperty*>,VertexPropertyT<T>,VertexPropHandle,T>(vertex_props_, _name, n_vertices(), _def);
}
template<class T>
EdgePropertyT<T> ResourceManager::request_edge_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,EdgePropertyT<T>,EdgePropHandle,T>(edge_props_, _name, n_edges(), _def);
return internal_request_property<std::vector<BaseProperty*>,EdgePropertyT<T>,EdgePropHandle,T>(edge_props_, _name, n_edges(), _def);
}
template<class T>
HalfEdgePropertyT<T> ResourceManager::request_halfedge_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,HalfEdgePropertyT<T>,HalfEdgePropHandle,T>(halfedge_props_, _name, n_edges()*2u, _def);
return internal_request_property<std::vector<BaseProperty*>,HalfEdgePropertyT<T>,HalfEdgePropHandle,T>(halfedge_props_, _name, n_edges()*2u, _def);
}
template<class T>
FacePropertyT<T> ResourceManager::request_face_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,FacePropertyT<T>,FacePropHandle,T>(face_props_, _name, n_faces(), _def);
return internal_request_property<std::vector<BaseProperty*>,FacePropertyT<T>,FacePropHandle,T>(face_props_, _name, n_faces(), _def);
}
template<class T>
HalfFacePropertyT<T> ResourceManager::request_halfface_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,HalfFacePropertyT<T>,HalfFacePropHandle,T>(halfface_props_, _name, n_faces()*2u, _def);
return internal_request_property<std::vector<BaseProperty*>,HalfFacePropertyT<T>,HalfFacePropHandle,T>(halfface_props_, _name, n_faces()*2u, _def);
}
template<class T>
CellPropertyT<T> ResourceManager::request_cell_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,CellPropertyT<T>,CellPropHandle,T>(cell_props_, _name, n_cells(), _def);
return internal_request_property<std::vector<BaseProperty*>,CellPropertyT<T>,CellPropHandle,T>(cell_props_, _name, n_cells(), _def);
}
template<class T>
MeshPropertyT<T> ResourceManager::request_mesh_property(const std::string& _name, const T _def) {
return request_property<std::vector<BaseProperty*>,MeshPropertyT<T>,MeshPropHandle,T>(mesh_props_, _name, 1, _def);
return internal_request_property<std::vector<BaseProperty*>,MeshPropertyT<T>,MeshPropHandle,T>(mesh_props_, _name, 1, _def);
}
template<class StdVecT, class PropT, class HandleT, class T>
PropT ResourceManager::request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def) {
PropT ResourceManager::internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def)
{
auto type_name = get_type_name<T>();
if(!_name.empty()) {
for(typename StdVecT::iterator it = _vec.begin();
it != _vec.end(); ++it) {
if((*it)->name() == _name) {
#if OVM_FORCE_STATIC_CAST
if((*it)->name() == _name
&& (*it)->internal_type_name() == type_name)
{
return *static_cast<PropT*>(*it);
#else
PropT* prop = dynamic_cast<PropT*>(*it);
if(prop != NULL) return *prop;
#endif
}
}
}
HandleT handle((int)_vec.size());
PropT* prop = new PropT(_name, *this, handle, _def);
PropT* prop = new PropT(_name, type_name, *this, handle, _def);
prop->resize(_size);
// Store property pointer
......
#include <string>
#include <typeinfo>
/// Get an internal name for a type. Important: this differs between
/// compilers and versions, do NOT use in file formats!
/// We need this in order to provide property type safety when
/// only limited RTTI support is available.
template<typename T>
std::string get_type_name()
{
#ifdef _MSC_VER
// MSVC's type_name only returns a friendly name with .name(),
// get the more unique mangled name using .raw_name():
return typeid(T).raw_name();
#else
// GCC and clang currently return the mangled name as .name(),
// there is no .raw_name()
return typeid(T).name();
#endif
}
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