Radium Engine  1.5.20
Loading...
Searching...
No Matches
Attribs.hpp
1#pragma once
2#include <map>
3
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>
9
10namespace Ra {
11namespace Core {
12
13namespace Geometry {
14// need forward declarations for friend classes outside of Utils namespace
15class TopologicalMesh;
16} // namespace Geometry
17
18namespace Utils {
19
20template <typename T>
21class Attrib;
22
26class RA_CORE_API AttribBase : public ObservableVoid, public ContainerIntrospectionInterface
27{
28 public:
29 inline explicit AttribBase( const std::string& name );
30 virtual ~AttribBase();
31 AttribBase( const AttribBase& ) = delete;
32 AttribBase& operator=( const AttribBase& ) = delete;
33
35 inline std::string getName() const;
36
38 inline void setName( const std::string& name );
39
41 virtual void resize( size_t s ) = 0;
42
44 bool inline operator==( const AttribBase& rhs );
45
47 template <typename T>
48 inline Attrib<T>& cast();
49
51 template <typename T>
52 inline const Attrib<T>& cast() const;
53
55 virtual bool isFloat() const = 0;
56
58 virtual bool isVector2() const = 0;
59
61 virtual bool isVector3() const = 0;
62
64 virtual bool isVector4() const = 0;
65
69 bool inline isLocked() const;
70
72 void inline unlock();
73
74 virtual std::unique_ptr<AttribBase> clone() = 0;
75
76 protected:
77 void inline lock( bool isLocked = true );
78
79 private:
81 std::string m_name;
82
84 bool m_isLocked { false };
85};
86
90template <typename T>
91class Attrib : public AttribBase
92{
93 public:
94 using value_type = T;
96
97 explicit Attrib( const std::string& name );
98 virtual ~Attrib();
99
101 void resize( size_t s ) override;
102
105 inline Container& getDataWithLock();
106
109 size_t getSize() const override;
110 size_t getNumberOfComponents() const override;
111 int getStride() const override;
112 size_t getBufferSize() const override;
113 const void* dataPtr() const override;
115
118 void setData( const Container& data );
119 void setData( Container&& data );
121
123 inline const Container& data() const;
124 bool isFloat() const override;
125 bool isVector2() const override;
126 bool isVector3() const override;
127 bool isVector4() const override;
128
130 template <typename U>
131 bool isType();
132
133 std::unique_ptr<AttribBase> clone() override {
134 auto ptr = std::make_unique<Attrib<T>>( getName() );
135 ptr->m_data = m_data;
136 return ptr;
137 }
138
139 private:
140 Container m_data;
141};
142
144template <typename T>
146{
147 public:
148 using value_type = T;
149 using AttribType = Attrib<T>;
150 using Container = typename Attrib<T>::Container;
153 template <typename U>
154 bool operator==( const AttribHandle<U>& lhs ) const {
155 return std::is_same<T, U>::value && m_idx == lhs.idx();
156 }
157
159 Index idx() const { return m_idx; }
160
163 std::string attribName() const { return m_name; }
164
165 private:
166 Index m_idx = Index::Invalid();
167 std::string m_name = "";
168
169 friend class AttribManager;
170};
171
203class RA_CORE_API AttribManager : public Observable<const std::string&>
204{
205 public:
206 using value_type = AttribBase;
207 using pointer_type = value_type*;
210
211 inline AttribManager();
212
214 AttribManager( const AttribManager& m ) = delete;
215 AttribManager& operator=( const AttribManager& m ) = delete;
216
217 inline AttribManager( AttribManager&& m );
218
219 inline AttribManager& operator=( AttribManager&& m );
220 ~AttribManager() override;
221
223 inline void copyAttributes( const AttribManager& m );
224
228 template <class T, class... Handle>
229 void copyAttributes( const AttribManager& m, const AttribHandle<T>& attr, Handle... attribs );
230
234 void copyAllAttributes( const AttribManager& m );
235
237 void clear();
238
240 template <typename T>
241 bool isValid( const AttribHandle<T>& h ) const;
242
249 inline bool contains( const std::string& name ) const;
250
258 template <typename T>
259 inline AttribHandle<T> findAttrib( const std::string& name ) const;
260
267 template <typename T>
268 typename Attrib<T>::Container& getDataWithLock( const AttribHandle<T>& h );
269
276 template <typename T>
277 const typename Attrib<T>::Container& getData( const AttribHandle<T>& h );
278
284 template <typename T>
285 void unlock( const AttribHandle<T>& h );
286
293 template <typename T>
294 inline Attrib<T>& getAttrib( const AttribHandle<T>& h );
295 template <typename T>
296 inline const Attrib<T>& getAttrib( const AttribHandle<T>& h ) const;
297 template <typename T>
298 inline Attrib<T>* getAttribPtr( const AttribHandle<T>& h );
299 template <typename T>
300 inline const Attrib<T>* getAttribPtr( const AttribHandle<T>& h ) const;
302
308 template <typename T>
309 inline Attrib<T>& getAttrib( const std::string& name );
310 template <typename T>
311 inline const Attrib<T>& getAttrib( const std::string& name ) const;
313
318 inline AttribBase* getAttribBase( const std::string& name );
319 inline const AttribBase* getAttribBase( const std::string& name ) const;
320 inline AttribBase* getAttribBase( const Index& idx );
321 inline const AttribBase* getAttribBase( const Index& idx ) const;
323
327 template <typename T>
328 inline void setAttrib( const AttribHandle<T>& h,
329 const typename AttribHandle<T>::Container& data );
330
332 template <typename T>
333 inline void setAttrib( const AttribHandle<T>& h, typename AttribHandle<T>::Container&& data );
335
341 template <typename T>
342 AttribHandle<T> addAttrib( const std::string& name );
343
349 template <typename T>
350 void removeAttrib( AttribHandle<T>& h );
354 bool hasSameAttribs( const AttribManager& other );
355
358 // This is needed by the user to avoid caring about removed attributes (nullptr)
359 // \todo reimplement as range for
360 template <typename F>
361 void for_each_attrib( const F& func ) const;
362
363 // \todo keep non const version private
364 template <typename F>
365 void for_each_attrib( const F& func );
367
369 inline int getNumAttribs() const;
370
403 {
404 public:
410 a->for_each_attrib( [this]( const auto& attr ) {
411 return ( v.push_back( std::make_pair( attr, attr->isLocked() ) ) );
412 } );
413 }
419 for ( auto& p : v ) {
420 if ( !p.second && p.first->isLocked() ) { p.first->unlock(); }
421 }
422 }
423
424 private:
426 };
427
430
431 private:
433 Container m_attribs;
434
437 std::map<std::string, Index> m_attribsIndex;
438
439 // Ease wrapper
440 friend class ::Ra::Core::Geometry::TopologicalMesh;
441
443 int m_numAttribs { 0 };
444};
445
446AttribBase::AttribBase( const std::string& name ) : m_name { name } {}
447
449 return m_name;
450}
451
452void AttribBase::setName( const std::string& name ) {
453 m_name = name;
454}
455
456bool inline AttribBase::operator==( const AttribBase & rhs ) {
457 return m_name == rhs.getName();
458}
459
460template <typename T>
462 return static_cast<Attrib<T>&>( *this );
463}
464
465template <typename T>
467 return static_cast<const Attrib<T>&>( *this );
468}
469
471 return m_isLocked;
472}
473
475 lock( false );
476}
477
478void AttribBase::lock( bool isLocked ) {
479 CORE_ASSERT( isLocked != m_isLocked, "double (un)lock" );
480 m_isLocked = isLocked;
481 if ( !m_isLocked ) notify();
482}
483
485
486template <typename T>
487Attrib<T>::Attrib( const std::string& name ) : AttribBase( name ) {}
488
489template <typename T>
490
492 m_data.clear();
493}
494template <typename T>
495void Attrib<T>::resize( size_t s ) {
496 m_data.resize( s );
497}
498template <typename T>
500 lock();
501 return m_data;
502}
503
504template <typename T>
505const void* Attrib<T>::dataPtr() const {
506 return m_data.dataPtr();
507}
508
509template <typename T>
510void Attrib<T>::setData( const Container& data ) {
511 CORE_ASSERT( !isLocked(), "try to set onto locked data" );
512 m_data = data;
513 notify();
514}
515
516template <typename T>
517void Attrib<T>::setData( Container&& data ) {
518 CORE_ASSERT( !isLocked(), "try to set onto locked data" );
519 m_data = std::move( data );
520 notify();
521}
522
523template <typename T>
524const typename Attrib<T>::Container& Attrib<T>::data() const {
525 return m_data;
526}
527
528template <typename T>
529size_t Attrib<T>::getSize() const {
530 return m_data.getSize();
531}
532
533template <typename T>
535 return m_data.getStride();
536}
537
538template <typename T>
540 return m_data.getBufferSize();
541}
542
543template <typename T>
547
548template <typename T>
551}
552
553template <typename T>
556}
557
558template <typename T>
561}
562
563template <typename T>
564template <typename U>
568
569// Defer computation to VectorArrayTypeHelper
570template <typename T>
572 return m_data.getNumberOfComponents();
573}
574
576
577AttribManager::AttribManager() {}
578
579AttribManager::AttribManager( AttribManager&& m ) :
580 m_attribs( std::move( m.m_attribs ) ),
581 m_attribsIndex( std::move( m.m_attribsIndex ) ),
582 m_numAttribs( std::move( m.m_numAttribs ) ) {}
583
584AttribManager& AttribManager::operator=( AttribManager&& m ) {
585 m_attribs = std::move( m.m_attribs );
586 m_attribsIndex = std::move( m.m_attribsIndex );
587 m_numAttribs = std::move( m.m_numAttribs );
588 return *this;
589}
590
592 m_numAttribs = m.m_numAttribs;
593}
594
595template <class T, class... Handle>
597 const AttribHandle<T>& attr,
598 Handle... attribs ) {
599 if ( m.isValid( attr ) ) {
600 // get attrib to copy
601 auto& a = m.getAttrib( attr );
602 // add new attrib
603 auto h = addAttrib<T>( a.getName() );
604 // copy attrib data
605 getAttrib( h ).setData( a.data() );
606 }
607 // deal with other attribs
608 copyAttributes( m, attribs... );
609}
610
611template <typename T>
613 auto itr = m_attribsIndex.find( h.attribName() );
614 return h.m_idx != Index::Invalid() && itr != m_attribsIndex.end() && itr->second == h.m_idx;
615}
616
617inline bool AttribManager::contains( const std::string& name ) const {
618 return m_attribsIndex.find( name ) != m_attribsIndex.end();
619}
620
621template <typename T>
623 auto c = m_attribsIndex.find( name );
624 AttribHandle<T> handle;
625 if ( c != m_attribsIndex.end() ) {
626 handle.m_idx = c->second;
627 handle.m_name = c->first;
628 }
629 return handle;
630}
631
632template <typename T>
634 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->getDataWithLock();
635}
636
637template <typename T>
639 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->data();
640}
641
642template <typename T>
644 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->unlock();
645}
646
647template <typename T>
649 return *static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
650}
651
652template <typename T>
653inline const Attrib<T>& AttribManager::getAttrib( const AttribHandle<T>& h ) const {
654 return *static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
655}
656template <typename T>
658 return getAttrib( findAttrib<T>( name ) );
659}
660
661template <typename T>
662inline const Attrib<T>& AttribManager::getAttrib( const std::string& name ) const {
663 return getAttrib( findAttrib<T>( name ) );
664}
665
666template <typename T>
667inline Attrib<T>* AttribManager::getAttribPtr( const AttribHandle<T>& h ) {
668 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
669}
670
671template <typename T>
672inline const Attrib<T>* AttribManager::getAttribPtr( const AttribHandle<T>& h ) const {
673 return static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() );
674}
675
676template <typename T>
678 const typename AttribHandle<T>::Container& data ) {
679 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->setData( data );
680}
681
682template <typename T>
684 typename AttribHandle<T>::Container&& data ) {
685 static_cast<Attrib<T>*>( m_attribs.at( h.m_idx ).get() )->setData( data );
686}
687
689 auto c = m_attribsIndex.find( name );
690 if ( c != m_attribsIndex.end() ) return m_attribs[c->second].get();
691 return nullptr;
692}
693
694inline const AttribBase* AttribManager::getAttribBase( const std::string& name ) const {
695 auto c = m_attribsIndex.find( name );
696 if ( c != m_attribsIndex.end() ) return m_attribs[c->second].get();
697 return nullptr;
698}
699
700inline AttribBase* AttribManager::getAttribBase( const Index& idx ) {
701 if ( idx.isValid() ) return m_attribs[idx].get();
702 return nullptr;
703}
704
705inline const AttribBase* AttribManager::getAttribBase( const Index& idx ) const {
706 if ( idx.isValid() ) return m_attribs[idx].get();
707 return nullptr;
708}
709
710template <typename T>
712 // does the attrib already exist?
713 AttribHandle<T> h = findAttrib<T>( name );
714 if ( isValid( h ) ) return h;
715
716 // create the attrib
717 smart_pointer_type attrib = std::make_unique<Attrib<T>>( name );
718
719 // look for a free slot
720 auto it = std::find_if(
721 m_attribs.begin(), m_attribs.end(), []( const auto& attr ) { return !attr; } );
722 if ( it != m_attribs.end() ) {
723 it->swap( attrib );
724 h.m_idx = std::distance( m_attribs.begin(), it );
725 }
726 else {
727 m_attribs.push_back( std::move( attrib ) );
728 h.m_idx = m_attribs.size() - 1;
729 }
730 m_attribsIndex[name] = h.m_idx;
731 h.m_name = name;
732 ++m_numAttribs;
733
734 notify( name );
735 return h;
736}
737
738template <typename T>
740 auto c = m_attribsIndex.find( h.m_name );
741 if ( c != m_attribsIndex.end() ) {
742 Index idx = c->second;
743 m_attribs[idx].reset( nullptr );
744 m_attribsIndex.erase( c );
745 }
746 h.m_idx = Index::Invalid(); // invalidate whatever!
747 auto name = h.m_name;
748 h.m_name = ""; // invalidate whatever!
749 --m_numAttribs;
750 notify( name );
751}
752
753template <typename F>
754void AttribManager::for_each_attrib( const F& func ) const {
755 for ( const auto& attr : m_attribs )
756 if ( attr != nullptr ) func( attr.get() );
757}
758
759template <typename F>
760void AttribManager::for_each_attrib( const F& func ) {
761 for ( auto& attr : m_attribs )
762 if ( attr != nullptr ) func( attr.get() );
763}
764
766 return m_numAttribs;
767}
768
769} // namespace Utils
770} // namespace Core
771} // namespace Ra
T at(T... args)
T begin(T... args)
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.
Definition Attribs.hpp:474
Attrib< T > & cast()
Downcast from AttribBase to Attrib<T>.
Definition Attribs.hpp:461
bool operator==(const AttribBase &rhs)
Return true if *this and rhs have the same name.
Definition Attribs.hpp:456
std::string getName() const
Return the attribute's name.
Definition Attribs.hpp:448
void setName(const std::string &name)
Set the attribute's name.
Definition Attribs.hpp:452
An attrib handle basically store an Index and a name.
Definition Attribs.hpp:146
std::string attribName() const
Definition Attribs.hpp:163
bool operator==(const AttribHandle< U > &lhs) const
Definition Attribs.hpp:154
Index idx() const
return the index of the attrib.
Definition Attribs.hpp:159
Scope lock state management for attributes.
Definition Attribs.hpp:403
ScopedLockState(AttribManager *a)
Constructor, save lock state of all attribs from attribManager.
Definition Attribs.hpp:409
~ScopedLockState()
Destructor, unlock all attribs whose have been locked after the initialization of the Unlocker.
Definition Attribs.hpp:418
The AttribManager provides attributes management by handles.
Definition Attribs.hpp:204
void setAttrib(const AttribHandle< T > &h, const typename AttribHandle< T >::Container &data)
Definition Attribs.hpp:677
AttribBase * getAttribBase(const std::string &name)
Definition Attribs.hpp:688
int getNumAttribs() const
Return the number of attributes.
Definition Attribs.hpp:765
ScopedLockState getScopedLockState()
Returns a scope unlocker for managed attribs.
Definition Attribs.hpp:429
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.
Definition Attribs.hpp:633
void unlock(const AttribHandle< T > &h)
Unlock the handle data.
Definition Attribs.hpp:643
AttribHandle< T > addAttrib(const std::string &name)
Definition Attribs.hpp:711
void copyAttributes(const AttribManager &m)
Base copy, does nothing.
Definition Attribs.hpp:591
bool contains(const std::string &name) const
contains Check if an attribute with the given name exists.
Definition Attribs.hpp:617
Attrib< T > & getAttrib(const AttribHandle< T > &h)
Definition Attribs.hpp:648
bool isValid(const AttribHandle< T > &h) const
Return true if h correspond to an existing attribute in *this.
Definition Attribs.hpp:612
void removeAttrib(AttribHandle< T > &h)
Definition Attribs.hpp:739
void for_each_attrib(const F &func) const
Definition Attribs.hpp:754
const Attrib< T >::Container & getData(const AttribHandle< T > &h)
Get read access to the data container from the attrib handle.
Definition Attribs.hpp:638
AttribHandle< T > findAttrib(const std::string &name) const
findAttrib Grab an attribute handler by name.
Definition Attribs.hpp:622
size_t getSize() const override
Definition Attribs.hpp:529
void setData(const Container &data)
Definition Attribs.hpp:510
size_t getNumberOfComponents() const override
Definition Attribs.hpp:571
bool isType()
check if attrib is a given type, as in attr.isType<MyMatrix>()
Definition Attribs.hpp:565
bool isVector4() const override
Return true if the attribute content is of Vector4 type, false otherwise.
Definition Attribs.hpp:559
const void * dataPtr() const override
Definition Attribs.hpp:505
Container & getDataWithLock()
Definition Attribs.hpp:499
const Container & data() const
Read-only acccess to the attribute content.
Definition Attribs.hpp:524
bool isVector2() const override
Return true if the attribute content is of Vector2 type, false otherwise.
Definition Attribs.hpp:549
bool isVector3() const override
Return true if the attribute content is of Vector3 type, false otherwise.
Definition Attribs.hpp:554
size_t getBufferSize() const override
Definition Attribs.hpp:539
int getStride() const override
Definition Attribs.hpp:534
void resize(size_t s) override
Resize the container (value_type must have a default ctor).
Definition Attribs.hpp:495
bool isFloat() const override
Return true if the attribute content is of Scalar type, false otherwise.
Definition Attribs.hpp:544
This class defines the introspection interface a container need to implement.
void notify(Args... p) const
T distance(T... args)
T end(T... args)
T erase(T... args)
T find(T... args)
T get(T... args)
T make_pair(T... args)
T move(T... args)
@ Geometry
"Geometry" render objects are those loaded using Radium::IO and generated by GeometrySystem
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
STL namespace.
T push_back(T... args)
T size(T... args)