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

@@ -1,38 +1,135 @@
#pragma once
#include <vector>
#include <span>
#include <mutex>
#include <shared_mutex>
#include "util/uix.hpp"
#include "util/id_type.hpp"
namespace assets::detail {
template<typename ID, typename T>
class generic_basic_store;
template<typename ID, typename T>
class generic_basic_store_iterator
{
public:
using size_type = std::size_t;
using id_type = ID;
using data_type = T;
using value_type = std::pair<id_type, data_type>;
using id_iterator_type = const id_type*;
using data_iterator_type = data_type*;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = std::pair<id_type, data_type&>;
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_basic_store<ID, T>;
generic_basic_store_iterator(
id_iterator_type ids,
data_iterator_type data,
std::size_t index
);
public:
constexpr generic_basic_store_iterator() noexcept = default;
constexpr generic_basic_store_iterator(const generic_basic_store_iterator&) noexcept = default;
constexpr generic_basic_store_iterator(generic_basic_store_iterator&&) noexcept = default;
constexpr generic_basic_store_iterator& operator=(const generic_basic_store_iterator&) noexcept = default;
constexpr generic_basic_store_iterator& operator=(generic_basic_store_iterator&&) noexcept = default;
reference operator*() const;
generic_basic_store_iterator& operator++();
generic_basic_store_iterator operator++(int);
generic_basic_store_iterator& operator--();
generic_basic_store_iterator operator--(int);
generic_basic_store_iterator& operator+=(difference_type n);
generic_basic_store_iterator& operator-=(difference_type n);
generic_basic_store_iterator operator+(difference_type n) const;
generic_basic_store_iterator operator-(difference_type n) const;
difference_type operator-(const generic_basic_store_iterator& other) const;
reference operator[](difference_type n) const;
bool operator==(const generic_basic_store_iterator& other) const;
bool operator!=(const generic_basic_store_iterator& other) const;
bool operator<(const generic_basic_store_iterator& other) const;
bool operator<=(const generic_basic_store_iterator& other) const;
bool operator>(const generic_basic_store_iterator& other) const;
bool operator>=(const generic_basic_store_iterator& other) const;
protected:
reference dereference() const;
private:
id_iterator_type m_ids{};
data_iterator_type m_data{};
size_type m_index{};
};
template<typename ID, typename T>
class generic_basic_store
{
public:
using id_type = ID;
using container_type = std::vector<T>;
using iterator_type = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
using iterator = generic_basic_store_iterator<ID, T>;
using const_iterator = generic_basic_store_iterator<std::add_const_t<T>...>;
ID add(const T& data);
using size_type = std::size_t;
using data_type = T;
[[nodiscard]] std::pair<iterator_type, bool> find(ID id);
bool insert(ID id, const T& data);
[[nodiscard]] std::pair<const_iterator, bool> find(ID id) const;
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::span<T> data();
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::span<const T> data() const;
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(iterator_type it);
void remove(iterator it);
void clear();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, ID id, const T& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(ID id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(ID id) const;
private:
std::vector<T> m_data;
std::vector<ID> m_ids;
std::vector<T> m_data;
mutable std::shared_mutex m_mutex;
};
}
#define INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION
#include "assets/data_stores/generic/generic_basic_store.ipp"
#undef INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION

View File

@@ -3,12 +3,13 @@
#include "assets/components/material_components.hpp"
#include "assets/data/material_data.hpp"
#include "assets/data_views/material_view.hpp"
#include <mutex>
#include <shared_mutex>
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_material_store;
template<typename... Ts>
@@ -33,7 +34,7 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_material_store<Ts...>;
friend generic_material_store<z3d::structure<Ts...>>;
generic_material_store_iterator(
id_iterator_type ids,
@@ -94,32 +95,37 @@ private:
template<typename... Ts>
class generic_material_store
class generic_material_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using component_flag_type = material_components::flags;
using data_type = material_data;
using iterator_type = generic_material_store_iterator<Ts...>;
using iterator = generic_material_store_iterator<Ts...>;
using const_iterator = generic_material_store_iterator<std::add_const_t<Ts>...>;
using view_type = std::ranges::subrange<iterator_type>;
using const_view_type = std::ranges::subrange<const_iterator>;
using id_type = material_id;
id_type add(const material_data& material);
bool insert(id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -129,11 +135,13 @@ public:
const_iterator cend() const;
view_type view();
const_view_type view() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -144,6 +152,7 @@ private:
std::vector<id_type> m_ids;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<component_flag_type> m_component_flag_counts;
mutable std::shared_mutex m_mutex;
};
}

View File

@@ -1,5 +1,8 @@
#pragma once
#include <mutex>
#include <shared_mutex>
#include "assets/components/mesh_vertex_components.hpp"
#include "assets/data_stores/material_store.hpp"
#include "assets/data/mesh_data.hpp"
@@ -8,7 +11,7 @@
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_mesh_store;
template<typename... Ts>
@@ -17,7 +20,7 @@ class generic_mesh_store_iterator
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using index_type = z3d::vertex_index;
using triangle_type = z3d::index_triangle;
using material_id_type = material_store::id_type;
using component_flag_type = mesh_vertex_components::flags;
using id_type = mesh_id;
@@ -26,7 +29,7 @@ public:
using id_iterator_type = id_type*;
using component_iterator_type = std::tuple<std::add_pointer_t<Ts>...>;
using index_iterator_type = index_type*;
using triangle_iterator_type = triangle_type*;
using flag_count_iterator_type = const flag_count_type*;
using material_id_iterator_type = material_id_type*;
@@ -37,11 +40,11 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_mesh_store<Ts...>;
friend generic_mesh_store<z3d::structure<Ts...>>;
generic_mesh_store_iterator(
id_iterator_type ids,
index_iterator_type indices,
triangle_iterator_type triangles,
const component_iterator_type& components,
material_id_iterator_type material_ids,
flag_count_iterator_type flag_counts,
@@ -92,7 +95,7 @@ protected:
private:
id_iterator_type m_ids{};
index_iterator_type m_indices{};
triangle_iterator_type m_triangles{};
component_iterator_type m_components{};
material_id_iterator_type m_material_ids{};
flag_count_iterator_type m_flag_counts{};
@@ -102,34 +105,39 @@ private:
template<typename... Ts>
class generic_mesh_store
class generic_mesh_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using index_type = z3d::vertex_index;
using triangle_type = z3d::index_triangle;
using component_flag_type = mesh_vertex_components::flags;
using material_id_type = material_store::id_type;
using iterator_type = generic_mesh_store_iterator<Ts...>;
using const_iterator = generic_mesh_store_iterator<std::add_const_t<Ts>...>;
using view_type = std::ranges::subrange<iterator_type>;
using const_view_type = std::ranges::subrange<const_iterator>;
using material_id_type = material_id;
using data_type = mesh_data;
using id_type = mesh_id;
id_type add(const mesh_data& mesh);
using iterator = generic_mesh_store_iterator<Ts...>;
using const_iterator = generic_mesh_store_iterator<std::add_const_t<Ts>...>;
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(id_type id, const data_type& data);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -139,11 +147,12 @@ public:
const_iterator cend() const;
view_type view();
const_view_type view() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -152,11 +161,11 @@ protected:
private:
std::vector<id_type> m_ids;
std::vector<index_type> m_indices;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<triangle_type> m_triangles;
std::vector<std::tuple<component_flag_type, count_type, count_type>> m_component_flag_counts;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<material_store::id_type> m_material_ids;
id_type m_next_data_id{ 1 };
mutable std::shared_mutex m_mutex{};
};
}

View File

@@ -1,19 +1,19 @@
#pragma once
#include <mutex>
#include <shared_mutex>
#include "util/uix.hpp"
#include "util/id_type.hpp"
#include "assets/components/point_cloud_vertex_components.hpp"
#include "assets/data/point_cloud_data.hpp"
#include "assets/data_views/point_cloud_view.hpp"
namespace assets
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_point_cloud_store;
namespace detail
{
template<typename... Ts>
class generic_point_cloud_store_iterator
@@ -37,13 +37,13 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_point_cloud_store<Ts...>;
friend generic_point_cloud_store<z3d::structure<Ts...>>;
generic_point_cloud_store_iterator(
id_iterator_type ids,
const component_iterator_type& components,
flag_count_iterator_type flag_counts,
std::size_t index,
size_type index,
const offsets_type& offsets
);
@@ -98,31 +98,37 @@ private:
template<typename... Ts>
class generic_point_cloud_store
class generic_point_cloud_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using component_flag_type = point_cloud_vertex_components::flags;
using data_type = point_cloud_data;
using iterator_type = generic_point_cloud_store_iterator<Ts...>;
using const_iterator = generic_point_cloud_store_iterator<std::add_const_t<Ts>...>;
using id_type = point_cloud_id;
using data_type = point_cloud_data;
id_type add(id_type id, const data_type& point_cloud);
using iterator = generic_point_cloud_store_iterator<Ts...>;
using const_iterator = generic_point_cloud_store_iterator<std::add_const_t<Ts>...>;
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(id_type id, const data_type& data);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -133,6 +139,12 @@ public:
const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -143,12 +155,11 @@ private:
std::vector<id_type> m_ids;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<std::pair<component_flag_type, count_type>> m_component_flag_counts;
id_type m_next_data_id{ 1 };
mutable std::shared_mutex m_mutex;
};
}
}
#define INCLUDE_GENERIC_POINT_CLOUD_STORE_IMPLEMENTATION