Made assets::data_stores thread safe.

This commit is contained in:
zy4n
2025-03-31 20:13:26 +02:00
parent 144126ee7a
commit 0acfe36118
39 changed files with 1772 additions and 1069 deletions

View File

@@ -3,61 +3,288 @@
#endif
#include <algorithm>
#include <mutex>
template<typename T>
typename generic_basic_store<T>::id_type generic_basic_store<T>::add(const T& data)
{
auto id = id_type{ m_next_data_id.index++ };
m_data.emplace_back(data);
m_ids.emplace_back(id);
return id;
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>::generic_basic_store_iterator(
id_iterator_type ids,
data_iterator_type data,
const size_type index
) :
m_ids{ ids },
m_data{ data },
m_index{ index } {}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference assets::detail::generic_basic_store_iterator<ID, T>::operator*() const {
return dereference();
}
template<typename T>
std::pair<typename generic_basic_store<T>::iterator_type, bool> generic_basic_store<T>::find(id_type id)
{
const auto it = std::ranges::upper_bound(m_ids, id);
const auto found = it != m_ids.begin() and *std::prev(it) == id;
const auto index = it - m_ids.begin() - found;
return { m_data.begin() + index, found };
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator++() {
++m_index;
return *this;
}
template<typename T>
std::pair<typename generic_basic_store<T>::const_iterator, bool> generic_basic_store<T>::find(id_type id) const
{
const auto it = std::ranges::upper_bound(m_ids, id);
const auto found = it != m_ids.begin() and *std::prev(it) == id;
const auto index = it - m_ids.begin() - found;
return { m_data.begin() + index, found };
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator++(int) {
generic_basic_store_iterator tmp = *this;
++(*this);
return tmp;
}
template<typename T>
void generic_basic_store<T>::remove(iterator_type it)
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator--() {
--m_index;
return *this;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator--(int) {
auto tmp = *this;
--(*this);
return tmp;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator+=(const difference_type n)
{
const auto index = it - m_data.begin();
m_data.erase(it);
m_index += n;
return *this;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator-=(const difference_type n)
{
return (*this) += -n;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator+(const difference_type n) const
{
auto tmp = *this;
return tmp += n; // TODO clion says n is unused
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator-(const difference_type n) const
{
auto tmp = *this;
return tmp -= n; // TODO clion says n is unused
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::difference_type
assets::detail::generic_basic_store_iterator<ID, T>::operator-(const generic_basic_store_iterator& other) const
{
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference assets::detail::generic_basic_store_iterator<ID, T>::operator[](
const difference_type n
) const {
return *(*this + n);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator==(const generic_basic_store_iterator& other) const
{
return m_ids == other.m_ids and m_index == other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator!=(const generic_basic_store_iterator& other) const
{
return not (*this == other);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator<(const generic_basic_store_iterator& other) const
{
return m_index < other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator<=(const generic_basic_store_iterator& other) const
{
return m_index <= other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator>(const generic_basic_store_iterator& other) const
{
return m_index > other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator>=(const generic_basic_store_iterator& other) const
{
return m_index >= other.m_index;
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference
assets::detail::generic_basic_store_iterator<ID, T>::dereference() const
{
return {
m_ids[m_index],
m_data[m_index]
};
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::insert(const ID id, const T& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto result = unsafe_find(id);
return unsafe_insert(result.first, id, data);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::insert(iterator it, const ID id, const T& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::iterator, bool> assets::detail::generic_basic_store<ID, T>::find(ID id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::const_iterator, bool> assets::detail::generic_basic_store<ID, T>::find(ID id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::unsafe_insert(iterator it, const ID id, const T& data)
{
const auto index = it.m_index;
if (index != m_ids.size() and m_ids[index] == id)
{
m_data[index] = data;
return false;
}
m_ids.insert(m_ids.begin() + index, id);
m_data.insert(m_data.begin() + index, data);
return true;
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::iterator, bool> assets::detail::generic_basic_store<ID, T>::unsafe_find(ID id)
{
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::const_iterator, bool> assets::detail::generic_basic_store<ID, T>::unsafe_find(ID id) const
{
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
template<typename ID, typename T>
void assets::detail::generic_basic_store<ID, T>::remove(iterator it)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
m_data.erase(m_data.begin() + index);
m_ids.erase(m_ids.begin() + index);
}
template<typename T>
void generic_basic_store<T>::clear()
template<typename ID, typename T>
void assets::detail::generic_basic_store<ID, T>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_data.clear();
m_ids.clear();
}
template<typename T>
std::span<T> generic_basic_store<T>::data()
{
return m_data;
template<typename ID, typename T>
std::shared_lock<std::shared_mutex> assets::detail::generic_basic_store<ID, T>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename T>
std::span<const T> generic_basic_store<T>::data() const
{
return m_data;
template<typename ID, typename T>
std::unique_lock<std::shared_mutex> assets::detail::generic_basic_store<ID, T>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::iterator assets::detail::generic_basic_store<ID, T>::begin()
{
return iterator{
m_ids.data(),
m_data.begin(),
0
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::iterator assets::detail::generic_basic_store<ID, T>::end()
{
return iterator{
m_ids.data(),
m_data.begin(),
m_ids.size()
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::begin() const
{
return const_iterator{
m_ids.data(),
m_data.begin(),
0
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::end() const
{
return const_iterator{
m_ids.data(),
m_data.begin(),
m_ids.size()
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::cbegin() const
{
return this->begin();
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::cend() const
{
return this->end();
}

View File

@@ -3,7 +3,7 @@
#endif
#include <vector>
#include <span>
#include <mutex>
#include <tuple>
#include <cstddef>
#include <type_traits>
@@ -14,7 +14,7 @@ assets::detail::generic_material_store_iterator<Ts...>::generic_material_store_i
id_iterator_type ids,
const component_iterator_type& components,
flag_count_iterator_type flag_counts,
std::size_t index,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -195,7 +195,7 @@ assets::detail::generic_material_store_iterator<Ts...>::dereference(std::index_s
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -205,7 +205,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts.
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -215,8 +215,8 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
template<typename... Ts>
std::array<typename assets::detail::generic_material_store<Ts...>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_material_store<Ts...>::array_counts() const
std::array<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_material_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -228,84 +228,139 @@ assets::detail::generic_material_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::id_type assets::detail::generic_material_store<Ts...>::add(
const component_set& material
) {
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto id = id_type{ m_next_data_id.index++ };
m_ids.push_back(id);
const auto result = unsafe_find(id);
auto component_flags = component_flag_type{};
return unsafe_insert(result.first, id, data);
}
template<typename... Ts>
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
if (new_entry)
{
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(m_component_flag_counts.begin() + index, src_component_flags);
}
auto& dst_component_flags = m_component_flag_counts[index];
[&]<auto... Is>(std::integer_sequence<Is...>)
{
if (const auto& component_opt = std::get<Is>(material.data))
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
const auto& src_component = std::get<Is>(data.components);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
if (is_component_enabled)
{
std::get<Is>(material.data).push_back(*component_opt);
component_flags |= component_flag_type{ 1 } << Is;
if (was_component_enabled)
{
*dst_component_it = *src_component;
}
else
{
dst_component_array.insert(dst_component_it, *src_component);
}
}
else if (was_component_enabled)
{
dst_component_array.erase(dst_component_it);
}
}
(std::index_sequence_for<Ts...>{});
m_component_flag_counts.push_back(component_flags);
dst_component_flags = src_component_flags;
return id;
return new_entry;
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<Ts...>::iterator_type, bool> assets::detail::generic_material_store<Ts...>::find(id_type id)
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
return { begin() + index, found };
auto it = begin();
it += index;
return { it, match };
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<Ts...>::const_iterator, bool> assets::detail::generic_material_store<Ts...>::find(id_type id) const
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_material_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_material_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.erase(m_ids.begin() + it.m_index);
return [&]<auto... Is>(std::index_sequence<Is>)
{
auto& component_vector = std::get<Is>(m_component_arrays);
(component_vector.erase(component_vector.begin() + it.m_offsets[Is]), ...);
auto& component_array = std::get<Is>(m_component_arrays);
(component_array.erase(component_array.begin() + it.m_offsets[Is]), ...);
} (std::index_sequence_for<Ts...>{});
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
}
template<typename... Ts>
void assets::detail::generic_material_store<Ts...>::clear()
void assets::detail::generic_material_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
@@ -315,9 +370,19 @@ void assets::detail::generic_material_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_material_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_material_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -327,9 +392,9 @@ typename assets::detail::generic_material_store<Ts...>::iterator_type assets::de
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::end()
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -339,7 +404,7 @@ typename assets::detail::generic_material_store<Ts...>::iterator_type assets::de
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::begin() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
@@ -351,7 +416,7 @@ typename assets::detail::generic_material_store<Ts...>::const_iterator assets::d
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::end() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
@@ -363,24 +428,13 @@ typename assets::detail::generic_material_store<Ts...>::const_iterator assets::d
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cbegin() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::cbegin() const
{
return const_cast<const generic_material_store*>(this)->begin();
return this->begin();
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cend() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::cend() const
{
return const_cast<const generic_material_store*>(this)->end();
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::view_type assets::detail::generic_material_store<Ts...>::view()
{
return { begin(), end() };
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_view_type assets::detail::generic_material_store<Ts...>::view() const
{
return { begin(), end() };
return this->end();
}

View File

@@ -8,6 +8,8 @@
#include <cstddef>
#include <type_traits>
#include <algorithm>
#include <mutex>
#include "util/vector_replace_range.hpp"
template<typename... Ts>
assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
@@ -16,7 +18,7 @@ assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
const component_iterator_type& components,
material_id_iterator_type material_ids,
flag_count_iterator_type flag_counts,
std::size_t index,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -162,14 +164,14 @@ void assets::detail::generic_mesh_store_iterator<Ts...>::calc_offsets(
while (n--)
{
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
const auto& [ flags, triangle_count, component_count ] = m_flag_counts[m_index];
std::get<0>(m_offsets) += step * index_count;
std::get<0>(m_offsets) += step * difference_type{ triangle_count };
([&] {
if (is_component_enabled<Is>(flags))
{
std::get<1 + Is>(m_offsets) += step * component_count;
std::get<1 + Is>(m_offsets) += step * difference_type{ component_count };
}
}(), ...);
@@ -182,15 +184,15 @@ template<std::size_t... Is>
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference
assets::detail::generic_mesh_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
{
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
const auto& [ flags, triangle_count, component_count ] = m_flag_counts[m_index];
return std::make_pair(
m_ids[m_index],
mesh_view{
.component_flags = flags,
.indices = std::span(
m_indices[m_offsets[0]],
index_count
.triangles = std::span(
&m_triangles[m_offsets[0]],
triangle_count
),
.vertex_component_arrays = std::make_tuple(
std::span(
@@ -205,7 +207,7 @@ assets::detail::generic_mesh_store_iterator<Ts...>::dereference(std::index_seque
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -215,7 +217,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>:
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -225,13 +227,13 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
template<typename... Ts>
std::array<typename assets::detail::generic_mesh_store<Ts...>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_mesh_store<Ts...>::array_counts() const
std::array<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_mesh_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
return std::array{
m_indices.size(),
m_triangles.size(),
std::get<Is>(m_component_arrays).size()...
};
}
@@ -239,129 +241,191 @@ assets::detail::generic_mesh_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::id_type assets::detail::generic_mesh_store<Ts...>::add(
const mesh_data& mesh
) {
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto id = id_type{ m_next_data_id.index++ };
m_ids.push_back(id);
const auto result = unsafe_find(id);
const auto& vertices = mesh.vertices;
const auto& triangles = mesh.triangles();
const auto indices = std::span(triangles.front().data(), triangles.size() * 3);
return unsafe_insert(result.first, id, data);
}
auto component_flags = component_flag_type{};
auto min_component_count = count_type{};
template<typename... Ts>
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
auto vertex_count = (
data.component_flags == component_flag_type{}
? count_type{}
: std::numeric_limits<count_type>::max()
);
// finding out correct component flags and count
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& component_array = std::get<Is>(vertices);
const auto& component_array = std::get<Is>(data.component_arrays);
if (not component_array.empty())
{
// TODO check count
const auto component_count = static_cast<count_type>(component_array.size());
if (min_component_count != 0 and component_count < min_component_count)
if (component_count != 0 and component_count < vertex_count)
{
min_component_count = component_count;
vertex_count = component_count;
}
component_flags |= component_flag_type{ 1 } << Is;
}
}
(std::index_sequence_for<Ts...>{});
// Insert indices
m_indices.insert(m_indices.end(), indices.begin(), indices.end());
auto dst_component_flags = component_flag_type{};
auto dst_index_count = count_type{};
auto dst_vertex_count = count_type{};
const auto src_component_flag_count = std::tuple<component_flag_type, count_type, count_type>{
src_component_flags,
data.triangles().size(),
vertex_count
};
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(
m_component_flag_counts.begin() + index,
src_component_flag_count
);
m_material_ids.insert(m_material_ids.begin() + index, data.material());
}
else
{
std::tie(dst_component_flags, dst_index_count, dst_vertex_count) = m_component_flag_counts[index];
m_component_flag_counts[index] = src_component_flag_count;
m_material_ids[index] = data.material();
}
// TODO check
const auto dst_triangle_it = m_triangles.begin() + it.m_offsets.front();
ztu::replace_range(
m_triangles,
dst_triangle_it,
dst_triangle_it + dst_index_count,
data.triangles().begin(),
data.triangles().end()
);
// Insert vertex components
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& src_array = std::get<Is>(vertices);
auto& dst_array = std::get<Is>(m_component_arrays);
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
if (not src_array.empty())
{
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
}
const auto& src_component_array = std::get<Is>(data.component_arrays);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[1 + Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
ztu::replace_range(
dst_component_array,
dst_component_it,
dst_component_it + dst_vertex_count,
src_component_array.begin(),
src_component_array.begin() + vertex_count
);
}
(std::index_sequence_for<Ts...>{});
// Insert material
m_material_ids.emplace_back(mesh.material_id());
// TODO check count
m_component_flag_counts.emplace_back(
mesh.component_flags,
static_cast<count_type>(indices.size()),
min_component_count
);
return id;
return new_entry;
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<Ts...>::iterator_type, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id)
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<Ts...>::const_iterator, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id) const
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_mesh_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_mesh_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
m_ids.erase(m_ids.begin() + it.m_index);
auto lock = std::unique_lock{ m_mutex };
m_indices.erase(m_indices.begin() + it.m_offsets[0]);
const auto index = it.m_index;
const auto [ component_flags, triangle_count, vertex_count ] = m_component_flag_counts[index];
m_ids.erase(m_ids.begin() + index);
m_triangles.erase(m_triangles.begin() + it.m_offsets[0], triangle_count);
m_component_flag_counts.erase(m_component_flag_counts.begin() + index);
[&]<auto... Is>(std::index_sequence<Is>)
{
([&]{
auto& component_vector = std::get<Is>(m_component_arrays);
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
const auto end = begin + it.m_flag_counts[it.m_index];
component_vector.erase(begin, end);
if ( component_flags & component_flag_type{ 1 } << Is)
{
auto& component_array = std::get<Is>(m_component_arrays);
const auto component_it = component_array.begin() + it.m_offsets[1 + Is];
component_array.erase(component_it, component_it + vertex_count);
}
}(), ...);
} (std::index_sequence_for<Ts...>{});
m_material_ids.erase(m_material_ids.begin() + it.m_index);
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
m_material_ids.erase(m_material_ids.begin() + index);
}
template<typename... Ts>
void assets::detail::generic_mesh_store<Ts...>::clear()
void assets::detail::generic_mesh_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
m_indices.clear();
m_triangles.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
std::get<Is>(m_component_arrays).clear();
@@ -371,11 +435,21 @@ void assets::detail::generic_mesh_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -385,25 +459,25 @@ typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::end()
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
m_component_flag_counts.size(),
m_ids.size(),
array_counts()
};
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::begin() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -413,11 +487,11 @@ typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detai
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::end() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -427,24 +501,13 @@ typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detai
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cbegin() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::cbegin() const
{
return const_cast<const generic_mesh_store*>(this)->begin();
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cend() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::cend() const
{
return const_cast<const generic_mesh_store*>(this)->end();
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::view_type assets::detail::generic_mesh_store<Ts...>::view()
{
return { begin(), end() };
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_view_type assets::detail::generic_mesh_store<Ts...>::view() const
{
return { begin(), end() };
}

View File

@@ -13,8 +13,8 @@ template<typename... Ts>
assets::detail::generic_point_cloud_store_iterator<Ts...>::generic_point_cloud_store_iterator(
id_iterator_type ids,
const component_iterator_type& components,
const flag_count_iterator_type flag_counts,
std::size_t index,
flag_count_iterator_type flag_counts,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -196,7 +196,7 @@ assets::detail::generic_point_cloud_store_iterator<Ts...>::dereference(std::inde
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -206,7 +206,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -216,8 +216,8 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
template<typename... Ts>
std::array<typename assets::detail::generic_point_cloud_store<Ts...>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_point_cloud_store<Ts...>::array_counts() const
std::array<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -229,113 +229,163 @@ assets::detail::generic_point_cloud_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::id_type assets::detail::generic_point_cloud_store<Ts...>::add(
const id_type id,
const data_type& point_cloud
) {
bool assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = unsafe_find(id);
const auto& vertices = point_cloud.component_arrays;
return unsafe_insert(result.first, id, data);
}
auto component_flags = component_flag_type{};
auto min_component_count = count_type{};
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
auto vertex_count = (
data.component_flags == component_flag_type{}
? count_type{}
: std::numeric_limits<count_type>::max()
);
// finding out correct component flags and count
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& component_array = std::get<Is>(vertices);
const auto& component_array = std::get<Is>(data.component_arrays);
if (not component_array.empty())
{
// TODO check count
const auto component_count = static_cast<count_type>(component_array.size());
if (min_component_count != 0 and component_count < min_component_count)
if (component_count != 0 and component_count < vertex_count)
{
min_component_count = component_count;
vertex_count = component_count;
}
component_flags |= component_flag_type{ 1 } << Is;
}
}
(std::index_sequence_for<Ts...>{});
// Insert vertex components
auto dst_component_flags = component_flag_type{};
auto dst_index_count = count_type{};
auto dst_vertex_count = count_type{};
const auto src_component_flag_count = std::tuple<component_flag_type, count_type>{
src_component_flags,
vertex_count
};
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(
m_component_flag_counts.begin() + index,
src_component_flag_count
);
}
else
{
std::tie(dst_component_flags, dst_index_count, dst_vertex_count) = m_component_flag_counts[index];
m_component_flag_counts[index] = src_component_flag_count;
}
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& src_array = std::get<Is>(vertices);
auto& dst_array = std::get<Is>(m_component_arrays);
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
if (not src_array.empty())
{
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
}
const auto& src_component_array = std::get<Is>(data.component_arrays);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[1 + Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
ztu::replace_range(
dst_component_array,
dst_component_it,
dst_component_it + dst_vertex_count,
src_component_array.begin(),
src_component_array.begin() + vertex_count
);
}
(std::index_sequence_for<Ts...>{});
// TODO check count
m_component_flag_counts.emplace_back(
point_cloud.component_flags,
min_component_count
);
return id;
return new_entry;
}
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id)
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id) const
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_point_cloud_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
const auto [ component_flags, triangle_count, vertex_count ] = m_component_flag_counts[index];
m_ids.erase(m_ids.begin() + index);
m_component_flag_counts.erase(m_component_flag_counts.begin() + index);
[&]<auto... Is>(std::index_sequence<Is>)
{
([&]{
auto& component_vector = std::get<Is>(m_component_arrays);
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
const auto end = begin + it.m_flag_counts[it.m_index];
component_vector.erase(begin, end);
if ( component_flags & component_flag_type{ 1 } << Is)
{
auto& component_array = std::get<Is>(m_component_arrays);
const auto component_it = component_array.begin() + it.m_offsets[1 + Is];
component_array.erase(component_it, component_it + vertex_count);
}
}(), ...);
} (std::index_sequence_for<Ts...>{});
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
m_ids.erase(m_ids.begin() + it.m_index);
}
template<typename... Ts>
void assets::detail::generic_point_cloud_store<Ts...>::clear()
void assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
@@ -345,9 +395,19 @@ void assets::detail::generic_point_cloud_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -357,9 +417,9 @@ typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets:
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::end()
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -369,7 +429,7 @@ typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets:
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::begin() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
@@ -381,7 +441,7 @@ typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::end() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
@@ -393,13 +453,13 @@ typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cbegin() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::cbegin() const
{
return const_cast<const generic_point_cloud_store*>(this)->begin();
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cend() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::cend() const
{
return const_cast<const generic_point_cloud_store*>(this)->end();
}

View File

@@ -15,7 +15,7 @@ assets::pose_list_store_iterator<Char>::pose_list_store_iterator(
id_iterator_type ids,
pose_iterator_type poses,
length_iterator_type lengths,
std::size_t index,
const size_type index,
const offset_type& offset
) :
m_ids{ ids },
@@ -169,62 +169,94 @@ assets::pose_list_store_iterator<Char>::dereference() const
);
}
assets::pose_list_store::id_type assets::pose_list_store::add(
const pose_list_id id,
const pose_list_data& pose_list
) {
inline bool assets::pose_list_store::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = find(id);
m_poses.insert(m_poses.end(), pose_list.begin(), pose_list.end());
m_lengths.push_back(pose_list.size());
return id;
return insert(result.first, id, data);
}
std::pair<assets::pose_list_store::iterator_type, bool> assets::pose_list_store::find(id_type id)
inline std::pair<assets::pose_list_store::iterator, bool> assets::pose_list_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
auto lock = std::shared_lock{ m_mutex };
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
return unsafe_find(id);
}
inline std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
inline bool assets::pose_list_store::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
// TODO Can currently not trust the material components, that should change!
auto dst_pose_count = count_type{};
const auto src_pose_count = data.size();
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_lengths.insert(m_lengths.begin() + index, src_pose_count);
}
else
{
dst_pose_count = m_lengths[index];
m_lengths[index] = src_pose_count;
}
const auto dst_pose_it = m_poses.begin() + it.m_offset;
ztu::replace_range(
m_poses,
dst_pose_it,
dst_pose_it + dst_pose_count,
data.begin(),
data.begin() + src_pose_count
);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return new_entry;
}
std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::find(id_type id) const
inline std::pair<assets::pose_list_store::iterator, bool> assets::pose_list_store::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
void assets::pose_list_store::remove(const iterator_type& it)
inline std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::unsafe_find(id_type id) const
{
m_ids.erase(m_ids.begin() + it.m_index);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto begin = m_poses.begin() + it.m_offset;
const auto end = begin + it.m_lengths[it.m_index];
m_poses.erase(begin, end);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
m_lengths.erase(m_lengths.begin() + it.m_index);
return { begin() + index, found };
}
void assets::pose_list_store::remove(const iterator& it)
{
const auto index = it.m_index;
m_ids.erase(m_ids.begin() + index);
const auto poses_it = m_poses.begin() + it.m_offset;
m_poses.erase(poses_it, poses_it + m_lengths[index]);
m_lengths.erase(m_lengths.begin() + index);
}
void assets::pose_list_store::clear()
@@ -234,9 +266,17 @@ void assets::pose_list_store::clear()
m_lengths.clear();
}
assets::pose_list_store::iterator_type assets::pose_list_store::begin()
std::shared_lock<std::shared_mutex> assets::pose_list_store::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
std::unique_lock<std::shared_mutex> assets::pose_list_store::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
assets::pose_list_store::iterator assets::pose_list_store::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_poses.data(),
m_lengths.data(),
@@ -245,9 +285,9 @@ assets::pose_list_store::iterator_type assets::pose_list_store::begin()
};
}
assets::pose_list_store::iterator_type assets::pose_list_store::end()
assets::pose_list_store::iterator assets::pose_list_store::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_poses.data(),
m_lengths.data(),

View File

@@ -17,7 +17,7 @@ assets::shader_source_store_iterator<Char>::shader_source_store_iterator(
string_iterator_type strings,
length_iterator_type lengths,
metadata_iterator_type metadata,
std::size_t index,
const size_type index,
const offset_type& offset
) :
m_ids{ ids },
@@ -172,65 +172,90 @@ assets::shader_source_store_iterator<Char>::dereference() const
);
}
assets::shader_source_store::id_type assets::shader_source_store::add(
const shader_source_id id,
const shader_source_data& shader_source
) {
bool assets::shader_source_store::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = find(id);
m_strings.reserve(m_strings.size() + shader_source.source.size() + 1);
m_strings.insert(m_strings.end(), shader_source.source.begin(), shader_source.source.end());
m_strings.push_back('\0');
m_lengths.push_back(shader_source.source.size());
m_metadata.push_back(shader_source.meta);
return id;
return insert(result.first, id, data);
}
std::pair<assets::shader_source_store::iterator_type, bool> assets::shader_source_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
template<typename... Ts>
bool assets::shader_source_store::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
auto dst_source_length = count_type{};
const auto src_source_length = data.source.size();
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_lengths.insert(m_lengths.begin() + index, src_source_length);
m_metadata.insert(m_metadata.begin() + index, data.meta);
}
else
{
dst_source_length = m_lengths[index];
m_lengths[index] = src_source_length;
m_metadata[index] = data.meta;
}
const auto dst_string_it = m_strings.begin() + it.m_offset;
ztu::replace_range(
m_strings,
dst_string_it,
dst_string_it + dst_source_length,
data.source.begin(),
data.source.end()
);
const auto index = id_it - m_ids.begin() - match;
if (new_entry)
{
m_strings.insert(m_strings.begin() + it.m_offset + src_source_length, '\0');
}
auto it = begin();
it += index;
return { it, match };
return new_entry;
}
std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
inline std::pair<assets::shader_source_store::iterator, bool> assets::shader_source_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
auto lock = std::shared_lock{ m_mutex };
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto index = id_it - m_ids.begin() - match;
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator_type& it)
inline std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.erase(m_ids.begin() + it.m_index);
const auto begin = m_strings.begin() + it.m_offset;
const auto end = begin + it.m_lengths[it.m_index];
m_strings.erase(begin, end);
const auto strings_begin = m_strings.begin() + it.m_offset;
const auto strings_end = begin + it.m_lengths[it.m_index] + sizeof('\0');
m_strings.erase(strings_begin, strings_end);
m_lengths.erase(m_lengths.begin() + it.m_index);
m_metadata.erase(m_metadata.begin() + it.m_index);
@@ -238,15 +263,25 @@ void assets::shader_source_store::remove(const iterator_type& it)
void assets::shader_source_store::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
m_strings.clear();
m_lengths.clear();
m_metadata.clear();
}
assets::shader_source_store::iterator_type assets::shader_source_store::begin()
std::shared_lock<std::shared_mutex> assets::shader_source_store::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
std::unique_lock<std::shared_mutex> assets::shader_source_store::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
assets::shader_source_store::iterator assets::shader_source_store::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),
@@ -256,9 +291,9 @@ assets::shader_source_store::iterator_type assets::shader_source_store::begin()
};
}
assets::shader_source_store::iterator_type assets::shader_source_store::end()
assets::shader_source_store::iterator assets::shader_source_store::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),