4 #include <Core/Containers/VectorArray.hpp>
5 #include <Core/RaCore.hpp>
6 #include <Core/Utils/ContainerIntrospectionInterface.hpp>
7 #include <Core/Utils/Index.hpp>
8 #include <Core/Utils/Observable.hpp>
15 class TopologicalMesh;
29 inline explicit AttribBase(
const std::string& name );
35 inline std::string getName()
const;
38 inline void setName(
const std::string& name );
44 bool inline operator==(
const AttribBase& rhs );
69 bool inline isLocked()
const;
74 virtual std::unique_ptr<AttribBase> clone() = 0;
77 void inline lock(
bool isLocked =
true );
84 bool m_isLocked {
false };
97 explicit Attrib(
const std::string& name );
101 void resize(
size_t s )
override;
109 size_t getSize()
const override;
113 const void*
dataPtr()
const override;
130 template <
typename U>
133 std::unique_ptr<AttribBase> clone()
override {
134 auto ptr = std::make_unique<Attrib<T>>(
getName() );
135 ptr->m_data = m_data;
144 template <
typename T>
148 using value_type = T;
153 template <
typename U>
155 return std::is_same<T, U>::value && m_idx == lhs.
idx();
159 Index
idx()
const {
return m_idx; }
166 Index m_idx = Index::Invalid();
167 std::string m_name =
"";
208 using smart_pointer_type = std::unique_ptr<value_type>;
209 using Container = std::vector<smart_pointer_type>;
228 template <
class T,
class... Handle>
240 template <
typename T>
249 inline bool contains(
const std::string& name )
const;
258 template <
typename T>
267 template <
typename T>
276 template <
typename T>
285 template <
typename T>
294 template <
typename T>
296 template <
typename T>
298 template <
typename T>
300 template <
typename T>
309 template <
typename T>
310 inline Attrib<T>& getAttrib(
const std::string& name );
311 template <
typename T>
312 inline const Attrib<T>& getAttrib(
const std::string& name )
const;
319 inline AttribBase* getAttribBase(
const std::string& name );
320 inline const AttribBase* getAttribBase(
const std::string& name )
const;
321 inline AttribBase* getAttribBase(
const Index& idx );
322 inline const AttribBase* getAttribBase(
const Index& idx )
const;
328 template <
typename T>
330 const typename AttribHandle<T>::Container& data );
333 template <
typename T>
334 inline void setAttrib(
const AttribHandle<T>& h,
typename AttribHandle<T>::Container&& data );
342 template <
typename T>
350 template <
typename T>
361 template <
typename F>
362 void for_each_attrib(
const F& func )
const;
365 template <
typename F>
366 void for_each_attrib(
const F& func );
370 inline int getNumAttribs()
const;
412 return ( v.push_back( std::make_pair( attr, attr->isLocked() ) ) );
420 for (
auto& p : v ) {
421 if ( !p.second && p.first->isLocked() ) { p.first->unlock(); }
426 std::vector<std::pair<AttribBase*, bool>> v;
438 std::map<std::string, Index> m_attribsIndex;
441 friend class ::Ra::Core::Geometry::TopologicalMesh;
444 int m_numAttribs { 0 };
447 AttribBase::AttribBase(
const std::string& name ) : m_name { name } {}
458 return m_name == rhs.
getName();
461 template <
typename T>
466 template <
typename T>
468 return static_cast<const Attrib<T>&
>( *this );
479 void AttribBase::lock(
bool isLocked ) {
480 CORE_ASSERT(
isLocked != m_isLocked,
"double (un)lock" );
482 if ( !m_isLocked )
notify();
487 template <
typename T>
490 template <
typename T>
495 template <
typename T>
499 template <
typename T>
505 template <
typename T>
507 return m_data.dataPtr();
510 template <
typename T>
512 CORE_ASSERT( !isLocked(),
"try to set onto locked data" );
517 template <
typename T>
519 CORE_ASSERT( !isLocked(),
"try to set onto locked data" );
520 m_data = std::move( data );
524 template <
typename T>
529 template <
typename T>
531 return m_data.getSize();
534 template <
typename T>
536 return m_data.getStride();
539 template <
typename T>
541 return m_data.getBufferSize();
544 template <
typename T>
546 return std::is_same<Scalar, T>::value;
549 template <
typename T>
551 return std::is_same<Eigen::Matrix<Scalar, 2, 1>, T>::value;
554 template <
typename T>
556 return std::is_same<Eigen::Matrix<Scalar, 3, 1>, T>::value;
559 template <
typename T>
561 return std::is_same<Eigen::Matrix<Scalar, 4, 1>, T>::value;
564 template <
typename T>
565 template <
typename U>
567 return std::is_same<U, T>::value;
571 template <
typename T>
573 return m_data.getNumberOfComponents();
578 AttribManager::AttribManager() {}
581 m_attribs( std::move( m.m_attribs ) ),
582 m_attribsIndex( std::move( m.m_attribsIndex ) ),
583 m_numAttribs( std::move( m.m_numAttribs ) ) {}
586 m_attribs = std::move( m.m_attribs );
587 m_attribsIndex = std::move( m.m_attribsIndex );
588 m_numAttribs = std::move( m.m_numAttribs );
593 m_numAttribs = m.m_numAttribs;
596 template <
class T,
class... Handle>
599 Handle... attribs ) {
604 auto h = addAttrib<T>( a.getName() );
612 template <
typename T>
614 auto itr = m_attribsIndex.find( h.
attribName() );
615 return h.m_idx != Index::Invalid() && itr != m_attribsIndex.end() && itr->second == h.m_idx;
619 return m_attribsIndex.find( name ) != m_attribsIndex.end();
622 template <
typename T>
624 auto c = m_attribsIndex.find( name );
626 if ( c != m_attribsIndex.end() ) {
627 handle.m_idx = c->second;
628 handle.m_name = c->first;
633 template <
typename T>
638 template <
typename T>
640 return static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() )->data();
643 template <
typename T>
648 template <
typename T>
650 return *
static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() );
653 template <
typename T>
655 return *
static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() );
657 template <
typename T>
659 return getAttrib( findAttrib<T>( name ) );
662 template <
typename T>
664 return getAttrib( findAttrib<T>( name ) );
667 template <
typename T>
669 return static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() );
672 template <
typename T>
674 return static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() );
677 template <
typename T>
679 const typename AttribHandle<T>::Container& data ) {
680 static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() )->setData( data );
683 template <
typename T>
685 typename AttribHandle<T>::Container&& data ) {
686 static_cast<Attrib<T>*
>( m_attribs.at( h.m_idx ).get() )->setData( data );
690 auto c = m_attribsIndex.find( name );
691 if ( c != m_attribsIndex.end() )
return m_attribs[c->second].get();
696 auto c = m_attribsIndex.find( name );
697 if ( c != m_attribsIndex.end() )
return m_attribs[c->second].get();
702 if ( idx.isValid() )
return m_attribs[idx].get();
707 if ( idx.isValid() )
return m_attribs[idx].get();
711 template <
typename T>
718 smart_pointer_type attrib = std::make_unique<Attrib<T>>( name );
721 auto it = std::find_if(
722 m_attribs.begin(), m_attribs.end(), [](
const auto& attr ) { return !attr; } );
723 if ( it != m_attribs.end() ) {
725 h.m_idx = std::distance( m_attribs.begin(), it );
728 m_attribs.push_back( std::move( attrib ) );
729 h.m_idx = m_attribs.size() - 1;
731 m_attribsIndex[name] = h.m_idx;
739 template <
typename T>
741 auto c = m_attribsIndex.find( h.m_name );
742 if ( c != m_attribsIndex.end() ) {
743 Index idx = c->second;
744 m_attribs[idx].reset(
nullptr );
745 m_attribsIndex.erase( c );
747 h.m_idx = Index::Invalid();
748 auto name = h.m_name;
754 template <
typename F>
756 for (
const auto& attr : m_attribs )
757 if ( attr !=
nullptr ) func( attr.get() );
760 template <
typename F>
762 for (
auto& attr : m_attribs )
763 if ( attr !=
nullptr ) func( attr.get() );
virtual bool isFloat() const =0
Return true if the attribute content is of Scalar type, false otherwise.
virtual bool isVector3() const =0
Return true if the attribute content is of Vector3 type, false otherwise.
virtual bool isVector4() const =0
Return true if the attribute content is of Vector4 type, false otherwise.
virtual bool isVector2() const =0
Return true if the attribute content is of Vector2 type, false otherwise.
virtual void resize(size_t s)=0
Resize the attribute's array.
void unlock()
Unlock data so another one can gain write access.
Attrib< T > & cast()
Downcast from AttribBase to Attrib<T>.
bool operator==(const AttribBase &rhs)
Return true if *this and rhs have the same name.
std::string getName() const
Return the attribute's name.
void setName(const std::string &name)
Set the attribute's name.
An attrib handle basically store an Index and a name.
std::string attribName() const
bool operator==(const AttribHandle< U > &lhs) const
Index idx() const
return the index of the attrib.
Scope lock state management for attributes.
ScopedLockState(AttribManager *a)
Constructor, save lock state of all attribs from attribManager.
~ScopedLockState()
Destructor, unlock all attribs whose have been locked after the initialization of the Unlocker.
The AttribManager provides attributes management by handles.
void setAttrib(const AttribHandle< T > &h, const typename AttribHandle< T >::Container &data)
AttribBase * getAttribBase(const std::string &name)
int getNumAttribs() const
Return the number of attributes.
ScopedLockState getScopedLockState()
Returns a scope unlocker for managed attribs.
AttribManager(const AttribManager &m)=delete
Copy constructor and assignment operator are forbidden.
Attrib< T >::Container & getDataWithLock(const AttribHandle< T > &h)
Get the locked data container from the attrib handle.
void unlock(const AttribHandle< T > &h)
Unlock the handle data.
AttribHandle< T > addAttrib(const std::string &name)
void copyAttributes(const AttribManager &m)
Base copy, does nothing.
bool contains(const std::string &name) const
contains Check if an attribute with the given name exists.
Attrib< T > & getAttrib(const AttribHandle< T > &h)
bool isValid(const AttribHandle< T > &h) const
Return true if h correspond to an existing attribute in *this.
void removeAttrib(AttribHandle< T > &h)
void for_each_attrib(const F &func) const
const Attrib< T >::Container & getData(const AttribHandle< T > &h)
Get read access to the data container from the attrib handle.
AttribHandle< T > findAttrib(const std::string &name) const
findAttrib Grab an attribute handler by name.
size_t getSize() const override
void setData(const Container &data)
size_t getNumberOfComponents() const override
bool isType()
check if attrib is a given type, as in attr.isType<MyMatrix>()
bool isVector4() const override
Return true if the attribute content is of Vector4 type, false otherwise.
const void * dataPtr() const override
Container & getDataWithLock()
const Container & data() const
Read-only acccess to the attribute content.
bool isVector2() const override
Return true if the attribute content is of Vector2 type, false otherwise.
bool isVector3() const override
Return true if the attribute content is of Vector3 type, false otherwise.
size_t getBufferSize() const override
int getStride() const override
void resize(size_t s) override
Resize the container (value_type must have a default ctor).
bool isFloat() const override
Return true if the attribute content is of Scalar type, false otherwise.
This class defines the introspection interface a container need to implement.
void notify(Args... p) const
Notify (i.e. call) each attached observer with argument p.