Loading...
Searching...
No Matches
CurveSegmentData.hpp
1#pragma once
2#include <Curve/Palette/CurvePoint.hpp>
3
4#include <score/model/IdentifiedObject.hpp>
5#include <score/plugins/UuidKey.hpp>
6#include <score/serialization/DataStreamFwd.hpp>
7#include <score/tools/IdentifierGeneration.hpp>
8
9#include <ossia/detail/algorithms.hpp>
10#include <ossia/detail/hash_map.hpp>
11
12#include <QVariant>
13
14#include <span>
15
16namespace Curve
17{
18class SegmentFactory;
19class SegmentModel;
20class Category_k;
21struct SegmentData;
22/* TODO it would maybe faster to have them on the heap and use QPointer for
23 * caching ...
24class SegmentId
25{
26 public:
27 using value_type = std::optional<int32_t>;
28 explicit SegmentId() = default;
29 explicit SegmentId(value_type val) : m_id {val} { }
30 SegmentId(const SegmentId&) = delete;
31 SegmentId(SegmentId&& ) = delete;
32 SegmentId& operator=(const SegmentId&) = delete;
33 SegmentId& operator=(SegmentId&& ) = delete;
34
35 friend bool operator== (const id_base_t& lhs, const id_base_t& rhs)
36 { return lhs.m_id == rhs.m_id; }
37
38 friend bool operator!= (const id_base_t& lhs, const id_base_t& rhs)
39 { return lhs.m_id != rhs.m_id; }
40
41 friend bool operator< (const id_base_t& lhs, const id_base_t& rhs)
42 { return *lhs.val() < *rhs.val(); }
43
44 explicit operator bool() const
45 { return bool(m_id); }
46
47 explicit operator value_type() const
48 { return m_id; }
49
50 const value_type& val() const
51 { return m_id; }
52
53 void setVal(value_type&& val)
54 { m_id = val; }
55
56 void unset()
57 { m_id = value_type(); }
58
59 private:
60 mutable CurveSegmentData* m_ptr{};
61 value_type m_id {};
62};*/
63
64// An object wrapper useful for saving / loading
66{
67 SegmentData() = default;
68 SegmentData(const SegmentData&) = default;
69 SegmentData(SegmentData&&) = default;
70 SegmentData& operator=(const SegmentData&) = default;
71 SegmentData& operator=(SegmentData&&) = default;
72
74 Id<SegmentModel> i, Curve::Point s, Curve::Point e, OptionalId<SegmentModel> prev,
75 OptionalId<SegmentModel> foll, const UuidKey<Curve::SegmentFactory>& t,
76 QVariant data)
77 : id(std::move(i))
78 , start(s)
79 , end(e)
80 , previous(std::move(prev))
81 , following(std::move(foll))
82 , type(t)
83 , specificSegmentData(std::move(data))
84 {
85 }
86
88
89 Curve::Point start, end;
90 OptionalId<SegmentModel> previous, following;
91
93 QVariant specificSegmentData;
94
95 double x() const { return start.x(); }
96 bool operator==(const SegmentData& other) = delete;
97 bool operator!=(const SegmentData& other) = delete;
98};
99
100inline bool operator<(const SegmentData& lhs, const SegmentData& rhs)
101{
102 return lhs.x() < rhs.x();
103}
104
105inline bool operator<=(const SegmentData& lhs, const SegmentData& rhs)
106{
107 return lhs.x() <= rhs.x();
108}
109
110// REFACTORME with SettableIdentifierGeneration...
111template <typename Container>
112Id<SegmentModel> getSegmentId(const Container& ids)
113{
114 Id<SegmentModel> id{};
115 auto end = ids.end();
116 do
117 {
119 } while(ids.find(id) != end);
120
121 return id;
122}
123
124inline Id<SegmentModel> getSegmentId(const std::vector<SegmentData>& ids)
125{
126 Id<SegmentModel> id{};
127
128 auto end = ids.end();
129 do
130 {
132 } while(ossia::find_if(ids, [&](const auto& other) { return other.id == id; }) != end);
133
134 return id;
135}
136
137inline Id<SegmentModel> getSegmentId(const std::vector<Id<SegmentModel>>& ids)
138{
139 Id<SegmentModel> id{};
140
141 auto end = ids.end();
142 do
143 {
145 } while(ossia::find_if(ids, [&](const auto& other) { return other == id; }) != end);
146
147 return id;
148}
149
152{
153public:
154 explicit SegmentIdAllocator(std::span<const SegmentData> taken)
155 {
156 m_taken.reserve(taken.size());
157 for(const auto& s : taken)
158 m_taken.insert(s.id.val());
159 }
160
161 Id<SegmentModel> next()
162 {
163 for(;;)
164 {
166 if(m_taken.insert(v).second)
167 return Id<SegmentModel>{v};
168 }
169 }
170
171private:
172 ossia::hash_set<int32_t> m_taken;
173};
174
175// We don't want crashes on invalid ids search
177{
178public:
179 std::size_t operator()(const Id<SegmentModel>& id) const { return id.val(); }
180};
181
182enum Segments
183{
184 Hashed
185};
186}
187
188SCORE_SERIALIZE_DATASTREAM_DECLARE(, Curve::SegmentData)
189Q_DECLARE_METATYPE(Curve::SegmentData)
190W_REGISTER_ARGTYPE(Curve::SegmentData)
191
192#define CURVE_SEGMENT_FACTORY_METADATA(Export, Model, Uuid) \
193 template <> \
194 struct Export Metadata<ConcreteKey_k, Model> \
195 { \
196 static const auto& get() \
197 { \
198 static const UuidKey<Curve::SegmentFactory> k{Uuid}; \
199 return k; \
200 } \
201 };
202
203#define CURVE_SEGMENT_METADATA(Export, Model, Uuid, ObjectKey, PrettyName, Category) \
204 OBJECTKEY_METADATA(Export, Model, ObjectKey) \
205 CURVE_SEGMENT_FACTORY_METADATA(Export, Model, Uuid) \
206 template <> \
207 struct Export Metadata<PrettyName_k, Model> \
208 { \
209 static auto get() { return QObject::tr(PrettyName); } \
210 }; \
211 template <> \
212 struct Export Metadata<Curve::Category_k, Model> \
213 { \
214 static auto get() { return QObject::tr(Category); } \
215 };
Metadata to categorize objects: curves, audio, etc.
Definition CurveSegmentData.hpp:177
Fresh ids for new segments: O(N) to set up, then O(1) each.
Definition CurveSegmentData.hpp:152
Definition UuidKey.hpp:345
The id_base_t class.
Definition Identifier.hpp:59
Utilities and base classes for 1D curves.
Definition FocusDispatcher.hpp:12
Definition CurveSegmentData.hpp:66
static int32_t getRandomId()
getNextId
Definition IdentifierGeneration.cpp:38