Wildmeshing Toolkit
Loading...
Searching...
No Matches
AttributeTransactionStack.hpp
Go to the documentation of this file.
1#pragma once
2#include <Eigen/Core>
3#include <map>
4#include <memory>
6#include "MapTypes.hpp"
7
8
9namespace wmtk::attribute {
10template <typename T>
11class Attribute;
12template <typename T, int Dim>
13class AccessorBase;
14namespace internal {
15template <typename T>
17{
18public:
19 template <int D>
21 template <int D>
23
24
31
32
33 template <typename Derived>
34 void try_caching(int64_t index, const Eigen::MatrixBase<Derived>& value);
35 void try_caching(int64_t index, const T& value);
36
37
38 const T* get_value(int64_t index) const;
39
40 // clears a stack
41 void clear();
42 int64_t size() const;
43
44 void apply_to(Attribute<T>& attribute) const;
45
46 // applyes to some other buffer that was passed in
47 void apply_to(const Attribute<T>& attribute, std::vector<T>& other) const;
48
49 const std::vector<T>& buffer() const { return m_buffer; }
50 const std::vector<std::pair<size_t, size_t>>& indices() const { return m_indices; }
51
52
54
55 // the starting index of each transaction
56 const std::vector<size_t>& transaction_starts() const { return m_transaction_starts; }
57 size_t buffer_end() const { return m_buffer_end; }
58 size_t indices_end() const { return m_indices_end; }
59
60 // OLD API
61 //==========
62
63
64 bool empty() const;
65
66
67 bool writing_enabled() const;
68
69
71 template <
72 int D = Eigen::Dynamic,
73 int D2 = Eigen::Dynamic,
74 int TrueD = D == Eigen::Dynamic ? D2 : D>
77
78 template <
79 int D = Eigen::Dynamic,
80 int D2 = Eigen::Dynamic,
81 int TrueD = D == Eigen::Dynamic ? D2 : D>
83 const;
85 template <int D2>
86 T& scalar_attribute(AccessorBase<T, D2>& accessor, int64_t index);
87
89 template <int D = Eigen::Dynamic>
90 T const_scalar_attribute(const AccessorBase<T, D>& accessor, int64_t index) const;
91
92 template <int D = Eigen::Dynamic>
94 T const_scalar_attribute(const AccessorBase<T, D>& accessor, int64_t index, int8_t offset)
95 const;
96
97 void emplace();
98 void pop(Attribute<T>& attribute, bool preserve_changes);
99 // go to the next most historic scope
102 // go to the scope with active data
105
107 bool at_current_scope() const;
108
109
111
112 std::vector<std::pair<size_t, size_t>>::const_iterator transaction_start_begin(
113 size_t scope_index) const;
114 std::vector<std::pair<size_t, size_t>>::const_iterator final_transaction_end() const;
115
116 std::vector<std::pair<size_t, size_t>>::const_reverse_iterator transaction_start_rend(
117 size_t scope_index) const;
118 std::vector<std::pair<size_t, size_t>>::const_reverse_iterator final_transaction_rbegin() const;
119
120 void update_buffer_sizes_for_add(size_t data_size);
121
122
123private:
124 void apply_last_scope(Attribute<T>& attr);
125
126protected:
127 std::vector<T> m_buffer;
128 std::vector<std::pair<size_t, size_t>> m_indices;
129
131
132 // the starting index of each transaction
133 std::vector<size_t> m_transaction_starts;
136};
137
138
139template <typename T>
141
142 -> std::vector<std::pair<size_t, size_t>>::const_iterator
143{
144 return m_indices.begin() + m_transaction_starts[scope_index];
145}
146template <typename T>
148 -> std::vector<std::pair<size_t, size_t>>::const_iterator
149
150{
151 return m_indices.begin() + m_indices_end;
152}
153
154template <typename T>
156 -> std::vector<std::pair<size_t, size_t>>::const_reverse_iterator
157{
158 return std::reverse_iterator(transaction_start_begin(scope_index));
159}
160template <typename T>
162 -> std::vector<std::pair<size_t, size_t>>::const_reverse_iterator
163{
164 return std::reverse_iterator(final_transaction_end());
165}
166
167template <typename T>
169{
170 return m_transaction_starts.size();
171}
172
173template <typename T>
175{
176 assert(!empty());
177 assert(at_current_scope());
178 apply_last_scope(attr);
179}
180
181template <typename T>
182template <int D, int D2, int TrueD>
184 AccessorBase<T, D2>& accessor,
185 int64_t index) -> MapResult<TrueD>
186{
187 assert(writing_enabled());
188
189 static_assert(D == Eigen::Dynamic || D2 == Eigen::Dynamic || D == D2);
190 auto data = accessor.template vector_attribute<TrueD>(index);
191 assert(data.cols() == 1);
192 if constexpr (D != Eigen::Dynamic) {
193 assert(data.size() == D);
194 }
195 if constexpr (D2 != Eigen::Dynamic) {
196 assert(data.size() == D2);
197 }
198 // we are typically only going to write when caching is enabled so better to optimize for this
199 if (!empty()) {
200 // assert(m_scopes.back() == *m_back);
201 try_caching(index, data);
202 // m_back->try_caching(index,data);
203 }
204 return data;
205}
206
207template <typename T>
208template <int D, int D2, int TrueD>
210 const AccessorBase<T, D2>& accessor,
211 int64_t index) const -> ConstMapResult<TrueD>
212{
213 static_assert(D == Eigen::Dynamic || D2 == Eigen::Dynamic || D == D2);
214 if (!at_current_scope()) {
215 assert(m_current_transaction_index < m_transaction_starts.size());
216
217 const T* ptr = get_value(index);
218 if (ptr != nullptr) {
219 const int dim = accessor.dimension();
220 auto dat = ConstMapResult<TrueD>(ptr, dim);
221 return dat;
222 }
223 }
224 return accessor.template const_vector_attribute<TrueD>(index);
225}
226
227template <typename T>
228template <int D2>
230 AccessorBase<T, D2>& accessor,
231 int64_t index) -> T&
232{
233 assert(writing_enabled());
234 T& value = accessor.scalar_attribute(index);
235 if (!empty()) {
236 try_caching(index, value);
237 // m_active->try_caching(index, value);
238 }
239 return value;
240}
241
242template <typename T>
243template <int D2>
245 const AccessorBase<T, D2>& accessor,
246 int64_t index) const -> T
247{
248 return const_vector_attribute<1>(accessor, index)(0);
249}
250template <typename T>
251template <int D2>
253 const AccessorBase<T, D2>& accessor,
254 int64_t index,
255 int8_t offset) const -> T
256{
257 if (!at_current_scope()) {
258 return const_vector_attribute<D2>(accessor, index)(offset);
259 } else {
260 return accessor.const_scalar_attribute(index, offset);
261 }
262}
263} // namespace internal
264} // namespace wmtk::attribute
265
This class stores data of type T in a vector.
Definition Attribute.hpp:32
T const_scalar_attribute(const AccessorBase< T, D > &accessor, int64_t index) const
default immutable scalar access
T & scalar_attribute(AccessorBase< T, D2 > &accessor, int64_t index)
default mutable scalar access
AttributeTransactionStack & operator=(AttributeTransactionStack &&)=default
void pop(Attribute< T > &attribute, bool preserve_changes)
bool at_current_scope() const
checks that we are viewing the active state of the attribute
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator final_transaction_rbegin() const
AttributeTransactionStack(const AttributeTransactionStack &)=delete
AttributeTransactionStack(AttributeTransactionStack &&)=default
std::vector< std::pair< size_t, size_t > >::const_iterator final_transaction_end() const
MapResult< TrueD > vector_attribute(AccessorBase< T, D2 > &accessor, int64_t index)
default mutable vector access
ConstMapResult< TrueD > const_vector_attribute(const AccessorBase< T, D2 > &accessor, int64_t index) const
default immutable vector access
void try_caching(int64_t index, const Eigen::MatrixBase< Derived > &value)
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator transaction_start_rend(size_t scope_index) const
T const_scalar_attribute(const AccessorBase< T, D > &accessor, int64_t index, int8_t offset) const
specialized immutable scalar access useful for topological operations
const std::vector< std::pair< size_t, size_t > > & indices() const
AttributeTransactionStack & operator=(const AttributeTransactionStack &)=delete
std::vector< std::pair< size_t, size_t > >::const_iterator transaction_start_begin(size_t scope_index) const
typename VectorResult< T, R >::MapType MapResult
the default map type used by attributes is a map of our vector type.
Definition MapTypes.hpp:21
typename VectorResult< T, R >::ConstMapType ConstMapResult
Definition MapTypes.hpp:23