#ifndef IOBJECTCLOUD_H #define IOBJECTCLOUD_H #include #include #include /** * @brief Class that can modify multiple element instead of one. Useful when an object is defined by multiple colors/infos */ template class ElementModifier { public: ElementModifier(T* first, const quint8& size) : firstT(first), m_size(size) {} virtual ~ElementModifier() {} ElementModifier& operator=(const T& newValue) { for(int i=0; i class AbstractObjectCloud { public: typedef valueT value_type; typedef ElementModifier return_type; virtual ~AbstractObjectCloud() {} virtual size_t size() const = 0; virtual ElementModifier operator[](const size_t& objectIndex) const = 0; }; /** * @brief Concrete class to access element like colors, infos, etc... of objects */ template class ObjectCloud : public AbstractObjectCloud< typename arrayT::value_type > { public: typedef typename arrayT::value_type value_type; ObjectCloud(arrayT &array, const quint8& nElementByObject) : m_array(array), m_nElementByObject(nElementByObject) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&m_array[ objectIndex*m_nElementByObject ], m_nElementByObject); } inline quint8 getNumberOfElementPerObject() const { return m_nElementByObject; } size_t size() const { return m_array.size(); } protected: arrayT& m_array; quint8 m_nElementByObject; }; /** * @brief Represent a cloud that can access element like colors, infos, etc... for object */ template class ObjectCloudIndexed : public ObjectCloud { public: ObjectCloudIndexed(arrayT &array, const int& nElementByObject, IndexCollection& indexes) : ObjectCloud(array, nElementByObject), m_indexes(indexes) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&this->m_array[ m_indexes[objectIndex*this->m_nElementByObject] ], this->m_nElementByObject); } size_t size() const { return m_indexes.size(); } private: IndexCollection& m_indexes; }; /** * @brief Concrete class to access element like colors, infos, etc... of objects */ template class ObjectPointerCloud : public AbstractObjectCloud< valueT > { public: typedef valueT value_type; ObjectPointerCloud(valueT* array, const size_t& size, const quint8& nElementByObject) : m_array(array), m_size(size), m_nElementByObject(nElementByObject) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&m_array[ objectIndex*m_nElementByObject ], m_nElementByObject); } inline quint8 getNumberOfElementPerObject() const { return m_nElementByObject; } size_t size() const { return m_size; } protected: quint8 m_nElementByObject; valueT* m_array; size_t m_size; }; /** * @brief Same as class ObjectPointerCloud but use a collection of index */ template class ObjectPointerCloudIndexed : public ObjectPointerCloud { public: ObjectPointerCloudIndexed(valueT* array, const int& nElementByObject, IndexCollection& indexes) : ObjectPointerCloud(array, indexes.size(), nElementByObject), m_indexes(indexes) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&this->m_array[ m_indexes[objectIndex*this->m_nElementByObject] ], this->m_nElementByObject); } private: IndexCollection& m_indexes; }; /** * @brief Concrete class to access element like colors, infos, etc... of objects with use of a function that get the first value in the array */ template class ObjectFuncPointerCloud : public AbstractObjectCloud< valueT > { public: typedef valueT value_type; typedef std::function funcGetFirstValue; ObjectFuncPointerCloud(funcGetFirstValue func, void* context, const size_t& size, const quint8& nElementByObject) : m_func(func), m_context(context), m_size(size), m_nElementByObject(nElementByObject) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&m_func(m_context)[ objectIndex*m_nElementByObject ], m_nElementByObject); } inline quint8 getNumberOfElementPerObject() const { return m_nElementByObject; } size_t size() const { return m_size; } protected: funcGetFirstValue m_func; void* m_context; size_t m_size; quint8 m_nElementByObject; }; /** * @brief Same as class ObjectFuncPointerCloud but use a collection of index */ template class ObjectFuncPointerCloudIndexed : public ObjectFuncPointerCloud { public: ObjectFuncPointerCloudIndexed(typename ObjectFuncPointerCloud::funcGetFirstValue func, void* context, const int& nElementByObject, IndexCollection& indexes) : ObjectFuncPointerCloud(func, context, indexes.size(), nElementByObject), m_indexes(indexes) {} virtual ElementModifier operator[](const size_t& objectIndex) const { return ElementModifier(&this->m_func(this->m_context)[ m_indexes[objectIndex*this->m_nElementByObject] ], this->m_nElementByObject); } private: IndexCollection& m_indexes; }; #endif // IOBJECTCLOUD_H