From fb2a88823bfa791de9435c6c50865c2bb9470164 Mon Sep 17 00:00:00 2001 From: Jeremiah Morgan Date: Tue, 3 Dec 2024 01:58:26 +0000 Subject: [PATCH] init --- libopenage/curve/CMakeLists.txt | 1 + libopenage/curve/array.cpp | 10 ++ libopenage/curve/array.h | 161 +++++++++++++++++++++++++ libopenage/curve/tests/curve_types.cpp | 20 ++- 4 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 libopenage/curve/array.cpp create mode 100644 libopenage/curve/array.h diff --git a/libopenage/curve/CMakeLists.txt b/libopenage/curve/CMakeLists.txt index 1aa1efb55b..63a7a12c00 100644 --- a/libopenage/curve/CMakeLists.txt +++ b/libopenage/curve/CMakeLists.txt @@ -12,6 +12,7 @@ add_sources(libopenage queue.cpp queue_filter_iterator.cpp segmented.cpp + array.cpp ) add_subdirectory("tests") diff --git a/libopenage/curve/array.cpp b/libopenage/curve/array.cpp new file mode 100644 index 0000000000..355bdefe98 --- /dev/null +++ b/libopenage/curve/array.cpp @@ -0,0 +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 \ No newline at end of file diff --git a/libopenage/curve/array.h b/libopenage/curve/array.h new file mode 100644 index 0000000000..a3ae1fee0a --- /dev/null +++ b/libopenage/curve/array.h @@ -0,0 +1,161 @@ +// Copyright 2017-2024 the openage authors. See copying.md for legal info. + + +#pragma once + +#include + +#include "curve/base_curve.h" +#include "curve/keyframe_container.h" + + +// remember to update docs +namespace openage { +namespace curve { + +template +class Array { +public: + using this_type = Array; + using container_t = std::array, Size>; + + + // Array() = default; + + // prevent accidental copy of queue + // Array(const Array &) = delete; + + + T get(const time::time_t &t, const size_t index) const; + // T get(const time::time_t& t, const size_t index, const size_t hint) const; + + + std::array get_all(const time::time_t &t) const; + // std::array, size> get_all(const time::time_t& t, const size_t hint) const; + + + size_t size() const; + + const Keyframe &frame(const time::time_t &t, const size_t index) const; + + + const Keyframe &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 &other, const time::time_t &t); + + + class Iterator { + public: + const T *ptr; + size_t offset; + const Array *const curve; + time::time_t time; + + Iterator(const Array *curve, const time::time_t &time = time::TIME_MAX, size_t offset = 0) : + curve(curve), time(time), offset(offset) { + if (this->offset != Size) { + std::cout << this->offset << Size; + ptr = &this->curve->frame(this->time, this->offset).value; + } + }; + + const T &operator*() { + ptr = &curve->frame(this->time, this->offset).value; + return *this->ptr; + } + + void operator++() { + this->offset++; + } + + bool operator!=(const Array::Iterator &rhs) const { + return this->offset != rhs.offset; + } + }; + + + Iterator begin(const time::time_t &time = time::TIME_MAX) const; + + Iterator end(const time::time_t &time = time::TIME_MAX) const; + + +private: + container_t container; + mutable size_t last_hit_index = 0; +}; + + +template +const Keyframe &Array::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 +const Keyframe &Array::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 +T Array::get(const time::time_t &t, const size_t index) const { + return this->frame(t, index).value; +} + +template +std::array Array::get_all(const time::time_t &t) const { + return [&](std::index_sequence) { + return std::array{this->get(t, I)...}; + }(std::make_index_sequence{}); +} + +template +size_t Array::size() const { + return Size; +} + + +template +void Array::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 +void Array::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 +void Array::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 +void Array::sync(const Array &other, const time::time_t &start) { + for (int i = 0; i < Size; i++) { + this->container[i].sync(other, start); + } +} + +template +typename Array::Iterator Array::begin(const time::time_t &time) const { + return Array::Iterator(this, time); +} + + +template +typename Array::Iterator Array::end(const time::time_t &time) const { + return Array::Iterator(this, time, this->container.size()); +} + +} // namespace curve +} // namespace openage diff --git a/libopenage/curve/tests/curve_types.cpp b/libopenage/curve/tests/curve_types.cpp index 421d3fb4d7..9d3465ab2e 100644 --- a/libopenage/curve/tests/curve_types.cpp +++ b/libopenage/curve/tests/curve_types.cpp @@ -5,6 +5,7 @@ #include #include +#include "curve/array.h" #include "curve/continuous.h" #include "curve/discrete.h" #include "curve/discrete_mod.h" @@ -232,7 +233,7 @@ void curve_types() { TESTEQUALS(c.get(8), 4); } - //Check the discrete type + // Check the discrete type { auto f = std::make_shared(); Discrete c(f, 0); @@ -257,7 +258,7 @@ void curve_types() { TESTEQUALS(complex.get(10), "Test 10"); } - //Check the discrete mod type + // Check the discrete mod type { auto f = std::make_shared(); DiscreteMod c(f, 0); @@ -290,7 +291,7 @@ void curve_types() { TESTEQUALS(c.get_mod(15, 0), 0); } - //check set_last + // check set_last { auto f = std::make_shared(); Discrete c(f, 0); @@ -386,6 +387,19 @@ void curve_types() { TESTEQUALS(c.get(1), 0); TESTEQUALS(c.get(5), 0); } + + { // array + Array a; + a.set_insert(time::time_t(1), 0, 0); + a.set_insert(time::time_t(1), 1, 1); + const auto res = a.get_all(1); + TESTEQUALS(res[0], 0); + TESTEQUALS(res[1], 1); + + for (auto r : a) { + std::cout << r << std::endl; + } + } } } // namespace openage::curve::tests