Skip to content

Commit

Permalink
curve: Concept for curve values.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Oct 31, 2024
1 parent a76e409 commit a5832dd
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 98 deletions.
1 change: 1 addition & 0 deletions libopenage/curve/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_sources(libopenage
base_curve.cpp
concept.cpp
continuous.cpp
discrete.cpp
discrete_mod.cpp
Expand Down
27 changes: 14 additions & 13 deletions libopenage/curve/base_curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "log/log.h"
#include "log/message.h"

#include "curve/concept.h"
#include "curve/keyframe_container.h"
#include "event/evententity.h"
#include "time/time.h"
Expand All @@ -27,7 +28,7 @@ class EventLoop;

namespace curve {

template <typename T>
template <KeyframeValueLike T>
class BaseCurve : public event::EventEntity {
public:
BaseCurve(const std::shared_ptr<event::EventLoop> &loop,
Expand Down Expand Up @@ -170,7 +171,7 @@ class BaseCurve : public event::EventEntity {
* Redundant keyframes are keyframes that don't change the value
* calculaton of the curve at any given time, e.g. duplicate keyframes.
*/
template <typename O>
template <KeyframeValueLike O>
void sync(const BaseCurve<O> &other,
const std::function<T(const O &)> &converter,
const time::time_t &start = time::TIME_MIN,
Expand Down Expand Up @@ -239,7 +240,7 @@ class BaseCurve : public event::EventEntity {
};


template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::set_last(const time::time_t &at,
const T &value,
bool compress) {
Expand All @@ -266,7 +267,7 @@ void BaseCurve<T>::set_last(const time::time_t &at,
}


template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::set_insert(const time::time_t &at,
const T &value,
bool compress) {
Expand All @@ -286,38 +287,38 @@ void BaseCurve<T>::set_insert(const time::time_t &at,
}


template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::set_replace(const time::time_t &at,
const T &value) {
this->container.insert_overwrite(at, value, this->last_element);
this->changes(at);
}


template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::erase(const time::time_t &at) {
this->last_element = this->container.erase(at, this->last_element);
this->changes(at);
}


template <typename T>
template <KeyframeValueLike T>
std::pair<time::time_t, const T> BaseCurve<T>::frame(const time::time_t &time) const {
auto e = this->container.last(time, this->container.size());
auto elem = this->container.get(e);
return std::make_pair(elem.time(), elem.val());
}


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

template <typename T>
template <KeyframeValueLike T>
std::string BaseCurve<T>::str() const {
std::stringstream ss;
ss << "Curve[" << this->idstr() << "]{" << std::endl;
Expand All @@ -329,7 +330,7 @@ std::string BaseCurve<T>::str() const {
return ss.str();
}

template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::check_integrity() const {
time::time_t last_time = time::TIME_MIN;
for (const auto &keyframe : this->container) {
Expand All @@ -340,7 +341,7 @@ void BaseCurve<T>::check_integrity() const {
}
}

template <typename T>
template <KeyframeValueLike T>
void BaseCurve<T>::sync(const BaseCurve<T> &other,
const time::time_t &start,
bool compress) {
Expand All @@ -362,8 +363,8 @@ void BaseCurve<T>::sync(const BaseCurve<T> &other,
}


template <typename T>
template <typename O>
template <KeyframeValueLike T>
template <KeyframeValueLike O>
void BaseCurve<T>::sync(const BaseCurve<O> &other,
const std::function<T(const O &)> &converter,
const time::time_t &start,
Expand Down
9 changes: 9 additions & 0 deletions libopenage/curve/concept.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#include "concept.h"


namespace openage::curve {


} // namespace openage::curve
15 changes: 15 additions & 0 deletions libopenage/curve/concept.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#pragma once

#include <concepts>

namespace openage::curve {

/**
* Concept for keyframe values.
*/
template <typename T>
concept KeyframeValueLike = std::copyable<T> && std::equality_comparable<T>;

} // namespace openage::curve
9 changes: 5 additions & 4 deletions libopenage/curve/continuous.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <sstream>
#include <string>

#include "curve/concept.h"
#include "curve/interpolated.h"
#include "time/time.h"

Expand All @@ -22,7 +23,7 @@ namespace openage::curve {
* The bound template type T has to implement `operator+(T)` and
* `operator*(time::time_t)`.
*/
template <typename T>
template <KeyframeValueLike T>
class Continuous : public Interpolated<T> {
public:
using Interpolated<T>::Interpolated;
Expand All @@ -47,7 +48,7 @@ class Continuous : public Interpolated<T> {
};


template <typename T>
template <KeyframeValueLike T>
void Continuous<T>::set_last(const time::time_t &at,
const T &value,
bool compress) {
Expand All @@ -74,15 +75,15 @@ void Continuous<T>::set_last(const time::time_t &at,
}


template <typename T>
template <KeyframeValueLike T>
void Continuous<T>::set_insert(const time::time_t &t,
const T &value,
bool /* compress */) {
this->set_replace(t, value);
}


template <typename T>
template <KeyframeValueLike T>
std::string Continuous<T>::idstr() const {
std::stringstream ss;
ss << "ContinuousCurve[";
Expand Down
18 changes: 7 additions & 11 deletions libopenage/curve/discrete.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <utility>

#include "curve/base_curve.h"
#include "curve/concept.h"
#include "time/time.h"


Expand All @@ -18,13 +19,8 @@ namespace openage::curve {
* Does not interpolate between values. The template type does only need to
* implement `operator=` and copy ctor.
*/
template <typename T>
template <KeyframeValueLike T>
class Discrete : public BaseCurve<T> {
static_assert(std::is_copy_assignable<T>::value,
"Template type is not copy assignable");
static_assert(std::is_copy_constructible<T>::value,
"Template type is not copy constructible");

public:
using BaseCurve<T>::BaseCurve;

Expand Down Expand Up @@ -53,14 +49,14 @@ class Discrete : public BaseCurve<T> {
};


template <typename T>
template <KeyframeValueLike T>
T Discrete<T>::get(const time::time_t &time) const {
auto e = this->container.last(time, this->last_element);
this->last_element = e; // TODO if Caching?
return this->container.get(e).val();
}

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

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

template <typename T>
template <KeyframeValueLike T>
std::string Discrete<T>::idstr() const {
std::stringstream ss;
ss << "DiscreteCurve[";
Expand All @@ -103,7 +99,7 @@ std::string Discrete<T>::idstr() const {
}


template <typename T>
template <KeyframeValueLike T>
std::pair<time::time_t, T> Discrete<T>::get_time(const time::time_t &time) const {
auto e = this->container.last(time, this->last_element);
this->last_element = e;
Expand All @@ -113,7 +109,7 @@ std::pair<time::time_t, T> Discrete<T>::get_time(const time::time_t &time) const
}


template <typename T>
template <KeyframeValueLike T>
std::optional<std::pair<time::time_t, T>> Discrete<T>::get_previous(const time::time_t &time) const {
auto e = this->container.last(time, this->last_element);
this->last_element = e;
Expand Down
22 changes: 9 additions & 13 deletions libopenage/curve/discrete_mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <utility>

#include "curve/base_curve.h"
#include "curve/concept.h"
#include "curve/discrete.h"
#include "time/time.h"
#include "util/fixed_point.h"
Expand All @@ -27,13 +28,8 @@ namespace openage::curve {
* always be inserted at t = 0. Also, the last keyframe should have the same value
* as the first keyframe as a convention.
*/
template <typename T>
template <KeyframeValueLike T>
class DiscreteMod : public Discrete<T> {
static_assert(std::is_copy_assignable<T>::value,
"Template type is not copy assignable");
static_assert(std::is_copy_constructible<T>::value,
"Template type is not copy constructible");

public:
using Discrete<T>::Discrete;

Expand Down Expand Up @@ -75,7 +71,7 @@ class DiscreteMod : public Discrete<T> {
};


template <typename T>
template <KeyframeValueLike T>
void DiscreteMod<T>::set_last(const time::time_t &at,
const T &value,
bool compress) {
Expand All @@ -84,7 +80,7 @@ void DiscreteMod<T>::set_last(const time::time_t &at,
}


template <typename T>
template <KeyframeValueLike T>
void DiscreteMod<T>::set_insert(const time::time_t &at,
const T &value,
bool compress) {
Expand All @@ -96,7 +92,7 @@ void DiscreteMod<T>::set_insert(const time::time_t &at,
}


template <typename T>
template <KeyframeValueLike T>
void DiscreteMod<T>::erase(const time::time_t &at) {
BaseCurve<T>::erase(at);

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


template <typename T>
template <KeyframeValueLike T>
std::string DiscreteMod<T>::idstr() const {
std::stringstream ss;
ss << "DiscreteRingCurve[";
Expand All @@ -121,7 +117,7 @@ std::string DiscreteMod<T>::idstr() const {
}


template <typename T>
template <KeyframeValueLike T>
T DiscreteMod<T>::get_mod(const time::time_t &time, const time::time_t &start) const {
time::time_t offset = time - start;
if (this->time_length == 0) {
Expand All @@ -134,7 +130,7 @@ T DiscreteMod<T>::get_mod(const time::time_t &time, const time::time_t &start) c
}


template <typename T>
template <KeyframeValueLike T>
std::pair<time::time_t, T> DiscreteMod<T>::get_time_mod(const time::time_t &time,
const time::time_t &start) const {
time::time_t offset = time - start;
Expand All @@ -148,7 +144,7 @@ std::pair<time::time_t, T> DiscreteMod<T>::get_time_mod(const time::time_t &time
}


template <typename T>
template <KeyframeValueLike T>
std::optional<std::pair<time::time_t, T>> DiscreteMod<T>::get_previous_mod(const time::time_t &time,
const time::time_t &start) const {
time::time_t offset = time - start;
Expand Down
9 changes: 5 additions & 4 deletions libopenage/curve/interpolated.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#pragma once

#include "curve/base_curve.h"
#include "curve/concept.h"
#include "time/time.h"
#include "util/fixed_point.h"

Expand All @@ -17,7 +18,7 @@ namespace openage::curve {
* The bound template type T has to implement `operator +(T)` and
* `operator *(time::time_t)`.
*/
template <typename T>
template <KeyframeValueLike T>
class Interpolated : public BaseCurve<T> {
public:
using BaseCurve<T>::BaseCurve;
Expand Down Expand Up @@ -56,7 +57,7 @@ class Interpolated : public BaseCurve<T> {
};


template <typename T>
template <KeyframeValueLike T>
T Interpolated<T>::get(const time::time_t &time) const {
const auto e = this->container.last(time, this->last_element);
this->last_element = e;
Expand Down Expand Up @@ -91,7 +92,7 @@ T Interpolated<T>::get(const time::time_t &time) const {
}
}

template <typename T>
template <KeyframeValueLike T>
void Interpolated<T>::compress(const time::time_t &start) {
// Find the last element before the start time
auto e = this->container.last_before(start, this->last_element);
Expand Down Expand Up @@ -129,7 +130,7 @@ void Interpolated<T>::compress(const time::time_t &start) {
this->changes(start);
}

template <typename T>
template <KeyframeValueLike T>
inline T Interpolated<T>::interpolate(typename KeyframeContainer<T>::elem_ptr before,
typename KeyframeContainer<T>::elem_ptr after,
double elapsed) const {
Expand Down
Loading

0 comments on commit a5832dd

Please sign in to comment.