Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
jere8184 committed Dec 11, 2024
1 parent 6420b76 commit 0b01820
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 165 deletions.
2 changes: 1 addition & 1 deletion libopenage/curve/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_sources(libopenage
array.cpp
base_curve.cpp
continuous.cpp
discrete.cpp
Expand All @@ -12,7 +13,6 @@ add_sources(libopenage
queue.cpp
queue_filter_iterator.cpp
segmented.cpp
array.cpp
)

add_subdirectory("tests")
20 changes: 10 additions & 10 deletions libopenage/curve/array.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright 2017-2024 the openage authors. See copying.md for legal info.


#include "array.h"

namespace openage::curve {

// This file is intended to be empty

} // openage::curve
// Copyright 2024-2024 the openage authors. See copying.md for legal info.


#include "array.h"

namespace openage::curve {

// This file is intended to be empty

} // openage::curve
303 changes: 151 additions & 152 deletions libopenage/curve/array.h
Original file line number Diff line number Diff line change
@@ -1,152 +1,151 @@
// Copyright 2017-2024 the openage authors. See copying.md for legal info.

#pragma once

#include <array>

#include "curve/base_curve.h"
#include "curve/keyframe_container.h"


// remember to update docs
namespace openage {
namespace curve {

template <typename T, size_t Size>
class Array {
public:
using container_t = std::array<KeyframeContainer<T>, Size>;


Array() = default;

// prevent accidental copy of queue
Array(const Array &) = delete;


T get(const time::time_t &t, const size_t index) const;


std::array<T, Size> get_all(const time::time_t &t) const;


size_t size() const;

const Keyframe<T> &frame(const time::time_t &t, const size_t index) const;


const Keyframe<T> &next_frame(const time::time_t &t, const size_t index) const;

void set_insert(const time::time_t &t, const size_t index, T value);

void set_last(const time::time_t &t, const size_t index, T value);

void set_replace(const time::time_t &t, const size_t index, T value);

void sync(const Array<T, Size> &other, const time::time_t &t);


class Iterator {
public:
Iterator(Array<T, Size> *curve, const time::time_t &time = time::TIME_MAX, size_t offset = 0) :
curve(curve), time(time), offset(offset) {};

const T &operator*() {
return curve->frame(this->time, this->offset).value;
}

void operator++() {
this->offset++;
}

bool operator!=(const Array<T, Size>::Iterator &rhs) const {
return this->offset != rhs.offset;
}


private:
size_t offset;
Array<T, Size> *curve;
time::time_t time;
};


Iterator begin(const time::time_t &time = time::TIME_MAX);

Iterator end(const time::time_t &time = time::TIME_MAX);


private:
container_t container;
mutable size_t last_hit_index = 0;
};


template <typename T, size_t Size>
const Keyframe<T> &Array<T, Size>::frame(const time::time_t &t, const size_t index) const {
this->last_hit_index = container[index].last(t, this->last_hit_index);
return container[index].get(this->last_hit_index);
}

template <typename T, size_t Size>
const Keyframe<T> &Array<T, Size>::next_frame(const time::time_t &t, const size_t index) const {
this->last_hit_index = container[index].last(t, this->last_hit_index);
return container[index].get(this->last_hit_index + 1);
}

template <typename T, size_t Size>
T Array<T, Size>::get(const time::time_t &t, const size_t index) const {
return this->frame(t, index).value;
}

template <typename T, size_t Size>
std::array<T, Size> Array<T, Size>::get_all(const time::time_t &t) const {
return [&]<auto... I>(std::index_sequence<I...>) {
return std::array<T, Size>{this->get(t, I)...};
}(std::make_index_sequence<Size>{});
}

template <typename T, size_t Size>
size_t Array<T, Size>::size() const {
return Size;
}


template <typename T, size_t Size>
void Array<T, Size>::set_insert(const time::time_t &t, const size_t index, T value) {
this->last_hit_index = this->container[index].insert_after(Keyframe(t, value), this->last_hit_index);
}


template <typename T, size_t Size>
void Array<T, Size>::set_last(const time::time_t &t, const size_t index, T value) {
this->last_hit_index = this->container[index].insert_after(Keyframe(t, value), this->last_hit_index);
this->container[index].erase_after(this->last_hit_index);
}


template <typename T, size_t Size>
void Array<T, Size>::set_replace(const time::time_t &t, const size_t index, T value) {
this->container[index].insert_overwrite(Keyframe(t, value), this->last_hit_index);
}

template <typename T, size_t Size>
void Array<T, Size>::sync(const Array<T, Size> &other, const time::time_t &start) {
for (int i = 0; i < Size; i++) {
this->container[i].sync(other, start);
}
}

template <typename T, size_t Size>
typename Array<T, Size>::Iterator Array<T, Size>::begin(const time::time_t &time) {
return Array<T, Size>::Iterator(this, time);
}


template <typename T, size_t Size>
typename Array<T, Size>::Iterator Array<T, Size>::end(const time::time_t &time) {
return Array<T, Size>::Iterator(this, time, this->container.size());
}

} // namespace curve
} // namespace openage
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#pragma once

#include <array>

#include "curve/base_curve.h"
#include "curve/keyframe_container.h"


// remember to update docs
namespace openage {
namespace curve {

template <typename T, size_t Size>
class Array {
public:
Array() = default;

// prevent accidental copy of queue
Array(const Array &) = delete;


T get(const time::time_t &t, const size_t index) const;


std::array<T, Size> get_all(const time::time_t &t) const;


consteval size_t size() const;

std::pair<time::time_t, T> frame(const time::time_t &t, const size_t index) const;


std::pair<time::time_t, T> next_frame(const time::time_t &t, const size_t index) const;

void set_insert(const time::time_t &t, const size_t index, T value);

void set_last(const time::time_t &t, const size_t index, T value);

void set_replace(const time::time_t &t, const size_t index, T value);

void sync(const Array<T, Size> &other, const time::time_t &t);


class Iterator {
public:
Iterator(Array<T, Size> *curve, const time::time_t &time = time::TIME_MAX, size_t offset = 0) :
curve(curve), time(time), offset(offset) {};

const T &operator*() {
return curve->frame(this->time, this->offset).second;
}

void operator++() {
this->offset++;
}

bool operator!=(const Array<T, Size>::Iterator &rhs) const {
return this->offset != rhs.offset;
}


private:
size_t offset;
Array<T, Size> *curve;
time::time_t time;
};


Iterator begin(const time::time_t &time = time::TIME_MAX);

Iterator end(const time::time_t &time = time::TIME_MAX);


private:
std::array<KeyframeContainer<T>, Size> container;

//hint for KeyframeContainer operations
mutable size_t last_element = 0;
};


template <typename T, size_t Size>
std::pair<time::time_t, T> Array<T, Size>::frame(const time::time_t &t, const size_t index) const {
this->last_element = container[index].last(t, this->last_element);
return container[index].get(this->last_element).make_pair();
}

template <typename T, size_t Size>
std::pair<time::time_t, T> Array<T, Size>::next_frame(const time::time_t &t, const size_t index) const {
this->last_element = container[index].last(t, this->last_element);
return container[index].get(this->last_element + 1);
}

template <typename T, size_t Size>
T Array<T, Size>::get(const time::time_t &t, const size_t index) const {
return this->frame(t, index).second;
}

template <typename T, size_t Size>
std::array<T, Size> Array<T, Size>::get_all(const time::time_t &t) const {
return [&]<auto... I>(std::index_sequence<I...>) {
return std::array<T, Size>{this->get(t, I)...};
}(std::make_index_sequence<Size>{});
}

template <typename T, size_t Size>
consteval size_t Array<T, Size>::size() const {
return Size;
}


template <typename T, size_t Size>
void Array<T, Size>::set_insert(const time::time_t &t, const size_t index, T value) {
this->last_element = this->container[index].insert_after(Keyframe(t, value), this->last_element);
}


template <typename T, size_t Size>
void Array<T, Size>::set_last(const time::time_t &t, const size_t index, T value) {
this->last_element = this->container[index].insert_after(Keyframe(t, value), this->last_element);
this->container[index].erase_after(this->last_element);
}


template <typename T, size_t Size>
void Array<T, Size>::set_replace(const time::time_t &t, const size_t index, T value) {
this->container[index].insert_overwrite(Keyframe(t, value), this->last_element);
}

template <typename T, size_t Size>
void Array<T, Size>::sync(const Array<T, Size> &other, const time::time_t &start) {
for (int i = 0; i < Size; i++) {
this->container[i].sync(other[i], start);
}
}

template <typename T, size_t Size>
typename Array<T, Size>::Iterator Array<T, Size>::begin(const time::time_t &time) {
return Array<T, Size>::Iterator(this, time);
}


template <typename T, size_t Size>
typename Array<T, Size>::Iterator Array<T, Size>::end(const time::time_t &time) {
return Array<T, Size>::Iterator(this, time, this->container.size());
}

} // namespace curve
} // namespace openage
9 changes: 9 additions & 0 deletions libopenage/curve/keyframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ class Keyframe {
return this->value;
}

/**
* Get the value and timestamp of the keyframe in form of std::pair<time, value>
* @return keyframe pair
*/
std::pair<time::time_t, T> make_pair() const
{
return {time(), val()};
}

public:
/**
* Value of the keyframe.
Expand Down
2 changes: 0 additions & 2 deletions libopenage/curve/keyframe_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,6 @@ class KeyframeContainer {
* Replaces all keyframes beginning at t >= start with keyframes from \p other.
*
* @param other Curve that keyframes are copied from.
* @param converter Function that converts the value type of \p other to the
* value type of \p this.
* @param start Start time at which keyframes are replaced (default = -INF).
* Using the default value replaces ALL keyframes of \p this with
* the keyframes of \p other.
Expand Down

0 comments on commit 0b01820

Please sign in to comment.