Skip to content

Commit 3c17e2b

Browse files
committed
curve: Concept for curve values.
1 parent 8746953 commit 3c17e2b

File tree

17 files changed

+126
-98
lines changed

17 files changed

+126
-98
lines changed

libopenage/curve/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_sources(libopenage
22
base_curve.cpp
3+
concept.cpp
34
continuous.cpp
45
discrete.cpp
56
discrete_mod.cpp

libopenage/curve/base_curve.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "log/log.h"
1515
#include "log/message.h"
1616

17+
#include "curve/concept.h"
1718
#include "curve/keyframe_container.h"
1819
#include "event/evententity.h"
1920
#include "time/time.h"
@@ -27,7 +28,7 @@ class EventLoop;
2728

2829
namespace curve {
2930

30-
template <typename T>
31+
template <KeyframeValueLike T>
3132
class BaseCurve : public event::EventEntity {
3233
public:
3334
BaseCurve(const std::shared_ptr<event::EventLoop> &loop,
@@ -170,7 +171,7 @@ class BaseCurve : public event::EventEntity {
170171
* Redundant keyframes are keyframes that don't change the value
171172
* calculaton of the curve at any given time, e.g. duplicate keyframes.
172173
*/
173-
template <typename O>
174+
template <KeyframeValueLike O>
174175
void sync(const BaseCurve<O> &other,
175176
const std::function<T(const O &)> &converter,
176177
const time::time_t &start = time::TIME_MIN,
@@ -239,7 +240,7 @@ class BaseCurve : public event::EventEntity {
239240
};
240241

241242

242-
template <typename T>
243+
template <KeyframeValueLike T>
243244
void BaseCurve<T>::set_last(const time::time_t &at,
244245
const T &value,
245246
bool compress) {
@@ -266,7 +267,7 @@ void BaseCurve<T>::set_last(const time::time_t &at,
266267
}
267268

268269

269-
template <typename T>
270+
template <KeyframeValueLike T>
270271
void BaseCurve<T>::set_insert(const time::time_t &at,
271272
const T &value,
272273
bool compress) {
@@ -286,38 +287,38 @@ void BaseCurve<T>::set_insert(const time::time_t &at,
286287
}
287288

288289

289-
template <typename T>
290+
template <KeyframeValueLike T>
290291
void BaseCurve<T>::set_replace(const time::time_t &at,
291292
const T &value) {
292293
this->container.insert_overwrite(at, value, this->last_element);
293294
this->changes(at);
294295
}
295296

296297

297-
template <typename T>
298+
template <KeyframeValueLike T>
298299
void BaseCurve<T>::erase(const time::time_t &at) {
299300
this->last_element = this->container.erase(at, this->last_element);
300301
this->changes(at);
301302
}
302303

303304

304-
template <typename T>
305+
template <KeyframeValueLike T>
305306
std::pair<time::time_t, const T> BaseCurve<T>::frame(const time::time_t &time) const {
306307
auto e = this->container.last(time, this->container.size());
307308
auto elem = this->container.get(e);
308309
return std::make_pair(elem.time(), elem.val());
309310
}
310311

311312

312-
template <typename T>
313+
template <KeyframeValueLike T>
313314
std::pair<time::time_t, const T> BaseCurve<T>::next_frame(const time::time_t &time) const {
314315
auto e = this->container.last(time, this->container.size());
315316
e++;
316317
auto elem = this->container.get(e);
317318
return std::make_pair(elem.time(), elem.val());
318319
}
319320

320-
template <typename T>
321+
template <KeyframeValueLike T>
321322
std::string BaseCurve<T>::str() const {
322323
std::stringstream ss;
323324
ss << "Curve[" << this->idstr() << "]{" << std::endl;
@@ -329,7 +330,7 @@ std::string BaseCurve<T>::str() const {
329330
return ss.str();
330331
}
331332

332-
template <typename T>
333+
template <KeyframeValueLike T>
333334
void BaseCurve<T>::check_integrity() const {
334335
time::time_t last_time = time::TIME_MIN;
335336
for (const auto &keyframe : this->container) {
@@ -340,7 +341,7 @@ void BaseCurve<T>::check_integrity() const {
340341
}
341342
}
342343

343-
template <typename T>
344+
template <KeyframeValueLike T>
344345
void BaseCurve<T>::sync(const BaseCurve<T> &other,
345346
const time::time_t &start,
346347
bool compress) {
@@ -362,8 +363,8 @@ void BaseCurve<T>::sync(const BaseCurve<T> &other,
362363
}
363364

364365

365-
template <typename T>
366-
template <typename O>
366+
template <KeyframeValueLike T>
367+
template <KeyframeValueLike O>
367368
void BaseCurve<T>::sync(const BaseCurve<O> &other,
368369
const std::function<T(const O &)> &converter,
369370
const time::time_t &start,

libopenage/curve/concept.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
2+
3+
#include "concept.h"
4+
5+
6+
namespace openage::curve {
7+
8+
9+
} // namespace openage::curve

libopenage/curve/concept.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
2+
3+
#pragma once
4+
5+
#include <concepts>
6+
7+
namespace openage::curve {
8+
9+
/**
10+
* Concept for keyframe values.
11+
*/
12+
template <typename T>
13+
concept KeyframeValueLike = std::copyable<T> && std::equality_comparable<T>;
14+
15+
} // namespace openage::curve

libopenage/curve/continuous.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sstream>
66
#include <string>
77

8+
#include "curve/concept.h"
89
#include "curve/interpolated.h"
910
#include "time/time.h"
1011

@@ -22,7 +23,7 @@ namespace openage::curve {
2223
* The bound template type T has to implement `operator+(T)` and
2324
* `operator*(time::time_t)`.
2425
*/
25-
template <typename T>
26+
template <KeyframeValueLike T>
2627
class Continuous : public Interpolated<T> {
2728
public:
2829
using Interpolated<T>::Interpolated;
@@ -47,7 +48,7 @@ class Continuous : public Interpolated<T> {
4748
};
4849

4950

50-
template <typename T>
51+
template <KeyframeValueLike T>
5152
void Continuous<T>::set_last(const time::time_t &at,
5253
const T &value,
5354
bool compress) {
@@ -74,15 +75,15 @@ void Continuous<T>::set_last(const time::time_t &at,
7475
}
7576

7677

77-
template <typename T>
78+
template <KeyframeValueLike T>
7879
void Continuous<T>::set_insert(const time::time_t &t,
7980
const T &value,
8081
bool /* compress */) {
8182
this->set_replace(t, value);
8283
}
8384

8485

85-
template <typename T>
86+
template <KeyframeValueLike T>
8687
std::string Continuous<T>::idstr() const {
8788
std::stringstream ss;
8889
ss << "ContinuousCurve[";

libopenage/curve/discrete.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <utility>
1010

1111
#include "curve/base_curve.h"
12+
#include "curve/concept.h"
1213
#include "time/time.h"
1314

1415

@@ -18,13 +19,8 @@ namespace openage::curve {
1819
* Does not interpolate between values. The template type does only need to
1920
* implement `operator=` and copy ctor.
2021
*/
21-
template <typename T>
22+
template <KeyframeValueLike T>
2223
class Discrete : public BaseCurve<T> {
23-
static_assert(std::is_copy_assignable<T>::value,
24-
"Template type is not copy assignable");
25-
static_assert(std::is_copy_constructible<T>::value,
26-
"Template type is not copy constructible");
27-
2824
public:
2925
using BaseCurve<T>::BaseCurve;
3026

@@ -53,14 +49,14 @@ class Discrete : public BaseCurve<T> {
5349
};
5450

5551

56-
template <typename T>
52+
template <KeyframeValueLike T>
5753
T Discrete<T>::get(const time::time_t &time) const {
5854
auto e = this->container.last(time, this->last_element);
5955
this->last_element = e; // TODO if Caching?
6056
return this->container.get(e).val();
6157
}
6258

63-
template <typename T>
59+
template <KeyframeValueLike T>
6460
void Discrete<T>::compress(const time::time_t &start) {
6561
auto e = this->container.last_before(start, this->last_element);
6662

@@ -88,7 +84,7 @@ void Discrete<T>::compress(const time::time_t &start) {
8884
this->changes(start);
8985
}
9086

91-
template <typename T>
87+
template <KeyframeValueLike T>
9288
std::string Discrete<T>::idstr() const {
9389
std::stringstream ss;
9490
ss << "DiscreteCurve[";
@@ -103,7 +99,7 @@ std::string Discrete<T>::idstr() const {
10399
}
104100

105101

106-
template <typename T>
102+
template <KeyframeValueLike T>
107103
std::pair<time::time_t, T> Discrete<T>::get_time(const time::time_t &time) const {
108104
auto e = this->container.last(time, this->last_element);
109105
this->last_element = e;
@@ -113,7 +109,7 @@ std::pair<time::time_t, T> Discrete<T>::get_time(const time::time_t &time) const
113109
}
114110

115111

116-
template <typename T>
112+
template <KeyframeValueLike T>
117113
std::optional<std::pair<time::time_t, T>> Discrete<T>::get_previous(const time::time_t &time) const {
118114
auto e = this->container.last(time, this->last_element);
119115
this->last_element = e;

libopenage/curve/discrete_mod.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <utility>
1010

1111
#include "curve/base_curve.h"
12+
#include "curve/concept.h"
1213
#include "curve/discrete.h"
1314
#include "time/time.h"
1415
#include "util/fixed_point.h"
@@ -27,13 +28,8 @@ namespace openage::curve {
2728
* always be inserted at t = 0. Also, the last keyframe should have the same value
2829
* as the first keyframe as a convention.
2930
*/
30-
template <typename T>
31+
template <KeyframeValueLike T>
3132
class DiscreteMod : public Discrete<T> {
32-
static_assert(std::is_copy_assignable<T>::value,
33-
"Template type is not copy assignable");
34-
static_assert(std::is_copy_constructible<T>::value,
35-
"Template type is not copy constructible");
36-
3733
public:
3834
using Discrete<T>::Discrete;
3935

@@ -75,7 +71,7 @@ class DiscreteMod : public Discrete<T> {
7571
};
7672

7773

78-
template <typename T>
74+
template <KeyframeValueLike T>
7975
void DiscreteMod<T>::set_last(const time::time_t &at,
8076
const T &value,
8177
bool compress) {
@@ -84,7 +80,7 @@ void DiscreteMod<T>::set_last(const time::time_t &at,
8480
}
8581

8682

87-
template <typename T>
83+
template <KeyframeValueLike T>
8884
void DiscreteMod<T>::set_insert(const time::time_t &at,
8985
const T &value,
9086
bool compress) {
@@ -96,7 +92,7 @@ void DiscreteMod<T>::set_insert(const time::time_t &at,
9692
}
9793

9894

99-
template <typename T>
95+
template <KeyframeValueLike T>
10096
void DiscreteMod<T>::erase(const time::time_t &at) {
10197
BaseCurve<T>::erase(at);
10298

@@ -106,7 +102,7 @@ void DiscreteMod<T>::erase(const time::time_t &at) {
106102
}
107103

108104

109-
template <typename T>
105+
template <KeyframeValueLike T>
110106
std::string DiscreteMod<T>::idstr() const {
111107
std::stringstream ss;
112108
ss << "DiscreteRingCurve[";
@@ -121,7 +117,7 @@ std::string DiscreteMod<T>::idstr() const {
121117
}
122118

123119

124-
template <typename T>
120+
template <KeyframeValueLike T>
125121
T DiscreteMod<T>::get_mod(const time::time_t &time, const time::time_t &start) const {
126122
time::time_t offset = time - start;
127123
if (this->time_length == 0) {
@@ -134,7 +130,7 @@ T DiscreteMod<T>::get_mod(const time::time_t &time, const time::time_t &start) c
134130
}
135131

136132

137-
template <typename T>
133+
template <KeyframeValueLike T>
138134
std::pair<time::time_t, T> DiscreteMod<T>::get_time_mod(const time::time_t &time,
139135
const time::time_t &start) const {
140136
time::time_t offset = time - start;
@@ -148,7 +144,7 @@ std::pair<time::time_t, T> DiscreteMod<T>::get_time_mod(const time::time_t &time
148144
}
149145

150146

151-
template <typename T>
147+
template <KeyframeValueLike T>
152148
std::optional<std::pair<time::time_t, T>> DiscreteMod<T>::get_previous_mod(const time::time_t &time,
153149
const time::time_t &start) const {
154150
time::time_t offset = time - start;

libopenage/curve/interpolated.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#pragma once
44

55
#include "curve/base_curve.h"
6+
#include "curve/concept.h"
67
#include "time/time.h"
78
#include "util/fixed_point.h"
89

@@ -17,7 +18,7 @@ namespace openage::curve {
1718
* The bound template type T has to implement `operator +(T)` and
1819
* `operator *(time::time_t)`.
1920
*/
20-
template <typename T>
21+
template <KeyframeValueLike T>
2122
class Interpolated : public BaseCurve<T> {
2223
public:
2324
using BaseCurve<T>::BaseCurve;
@@ -56,7 +57,7 @@ class Interpolated : public BaseCurve<T> {
5657
};
5758

5859

59-
template <typename T>
60+
template <KeyframeValueLike T>
6061
T Interpolated<T>::get(const time::time_t &time) const {
6162
const auto e = this->container.last(time, this->last_element);
6263
this->last_element = e;
@@ -91,7 +92,7 @@ T Interpolated<T>::get(const time::time_t &time) const {
9192
}
9293
}
9394

94-
template <typename T>
95+
template <KeyframeValueLike T>
9596
void Interpolated<T>::compress(const time::time_t &start) {
9697
// Find the last element before the start time
9798
auto e = this->container.last_before(start, this->last_element);
@@ -129,7 +130,7 @@ void Interpolated<T>::compress(const time::time_t &start) {
129130
this->changes(start);
130131
}
131132

132-
template <typename T>
133+
template <KeyframeValueLike T>
133134
inline T Interpolated<T>::interpolate(typename KeyframeContainer<T>::elem_ptr before,
134135
typename KeyframeContainer<T>::elem_ptr after,
135136
double elapsed) const {

0 commit comments

Comments
 (0)