1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/************************************************************************
*
* Copyright (C) 2009-2024 IRCAD France
* Copyright (C) 2012-2016 IHU Strasbourg
*
* This file is part of Sight.
*
* Sight is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sight. If not, see <https://www.gnu.org/licenses/>.
*
***********************************************************************/
#pragma once
#include <sight/data/config.hpp>
#include "data/timeline/buffer.hpp"
namespace sight::data::timeline
{
/**
* @brief This class is the non-template part of the class generic_object. It is used to store groups of objects
* inside a timeline. The maximum number of elements inside an object is fixed, however some elements
* can be missing. A mask is provided to test the presence of a given element.
* Note that the size of an element is not determined by dividing the size of the buffer by the maximum
* number of elements. Thus it is possible to have objects bigger
*/
class SIGHT_DATA_CLASS_API generic_object_base : public data::timeline::buffer
{
public:
/// Destructor
SIGHT_DATA_API ~generic_object_base() override;
/// Return the number of elements present in the object
[[nodiscard]] SIGHT_DATA_API unsigned int get_present_element_num() const;
/// Tell if an element is present at the given index
[[nodiscard]] SIGHT_DATA_API bool is_present(unsigned int _index) const;
/// Return the raw presence mask
[[nodiscard]] SIGHT_DATA_API uint64_t get_mask() const;
/// Return the maximum number of elements in the buffer
[[nodiscard]] SIGHT_DATA_API unsigned int get_max_element_num() const;
/// Return the size of element in the buffer
[[nodiscard]] SIGHT_DATA_API std::size_t get_element_size() const;
/// Make a copy of this buffer
SIGHT_DATA_API void deep_copy(const data::timeline::object& _other) override;
protected:
/// Constructor
SIGHT_DATA_API generic_object_base(
unsigned int _max_element_num,
core::clock::type _timestamp = 0,
buffer_data_t _buffer = nullptr,
std::size_t _size = 0,
deleter_t _d = nullptr
);
/// Number of elements that are actually set
unsigned int m_num_present {0};
/// Binary mask that indicates which element are set
uint64_t m_presence_mask {0};
/// Maximum number of elements in an object
unsigned int m_max_element_num;
};
/**
* @brief This timeline is used to store a group of objects of a given type. The maximum number of elements inside an
* object is fixed, however some elements can be missing. A mask is provided to test the presence of a given
* element.
*/
template<typename TYPE>
class generic_object : public generic_object_base
{
public:
/// Type of the elements inside the buffer
using element_t = TYPE;
class iterator
{
public:
/// Go to the next element
void operator++();
/// True if the current element is valid.
[[nodiscard]] bool is_valid() const
{
return m_current_index < m_max_element;
}
/// Get the current element
const element_t& operator*() const;
private:
/// Constructor
iterator(const generic_object_base& _object);
/// Pointer on the buffer object
const generic_object_base* m_object;
/// Current element
unsigned int m_current_index {0};
/// Maximum number of elements in the buffer
unsigned int m_max_element;
friend class generic_object<element_t>;
};
friend class iterator;
/// Constructor
generic_object(
unsigned int _m_max_element_num,
core::clock::type _timestamp = 0,
buffer_data_t _buffer = nullptr,
std::size_t _size = 0,
deleter_t _d = nullptr
);
/// Destructor
~generic_object() override;
/// Return the nth element in the buffer
[[nodiscard]] const TYPE& get_element(unsigned int _index) const;
/// Set the nth element in the buffer. Element in parameter will be copied at the given index. The method is
/// disabled if TYPE isn't TriviallyCopyable because setElement internally uses memcpy.
void set_element(const element_t& _element, unsigned int _index);
/// Add an element and return a pointer on the newly added element
TYPE* add_element(unsigned int _index);
/// Return an iterator on the elements present in the object
[[nodiscard]] iterator get_presence_iterator() const;
};
} // namespace sight::data::timeline
|