Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array curve #1724

Merged
merged 13 commits into from
Jan 19, 2025
41 changes: 40 additions & 1 deletion doc/code/curves.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Curves are an integral part of openage's event-based game simulation.
2. [Container](#container)
1. [Queue](#queue)
2. [Unordered Map](#unordered-map)
3. [Array](#array)


## Motivation
Expand Down Expand Up @@ -198,7 +199,7 @@ e.g. angles between 0 and 360 degrees.
### Container

Container curves are intended for storing changes to collections and containers.
The currently supported containers are `Queue` and `UnorderedMap`.
The currently supported containers are `Queue`, `UnorderedMap` and `Array`.

The most important distinction between regular C++ containers and curve containers
is that curve containers track the *lifespan* of each element, i.e. their insertion time,
Expand Down Expand Up @@ -253,3 +254,41 @@ Unordered map curve containers store key-value pairs while additionally keeping
track of element insertion time. Requests for a key `k` at time `t` will return the value
of `k` at that time. The unordered map can also be iterated over for a specific time `t` which
allows access to all key-value pairs that were in the map at time `t`.


#### Array

Array curve containers store a fixed number of `n` elements where `n` is determined at compile-time.
They are the curve equivalent to the `std::array` C++ containers. In comparison to `std::array` each
element in the array curve container is tracked individually over time. Hence, each index is associated
with its own `KeyframeContainer` whose keyframes can be updated independent from other indices.
When a value is added to the `Array` curve at a given index, a new keyframe is added to the respective
`KeyframeContainer` stored at that index.

**Read**

Read operations retrieve values for a specific point in time.

| Method | Description |
| ------------------ | ------------------------------------------------------------------------ |
| `get(t, i)` | Get value of element at index `i` at time <= `t` |
| `get(t)` | Get array of values at time <= `t` |
| `size()` | Get the number of elements in the array |
| `frame(t, i)` | Get the previous keyframe (time and value) at index `i` before or at `t` |
| `next_frame(t, i)` | Get the next keyframe (time and value) at index `i` after `t` |

**Modify**

Modify operations insert values for a specific point in time.

| Method | Description |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| `set_insert(t, i, value)` | Insert a new keyframe(`t`, `value`) at index `i` |
| `set_last(t, i, value)` | Insert a new keyframe(`t`, `value`) at index `i`; delete all keyframes after time `t` |
| `set_replace(t, i, value)` | Insert a new keyframe(`t`, `value`) at index `i`; remove all other keyframes with time `t` |

**Copy**

| Method | Description |
| ---------------- | ------------------------------------------------------------------------------------------------ |
| `sync(Curve, t)` | Replace all keyframes from self after time `t` with keyframes from source `Curve` after time `t` |
7 changes: 1 addition & 6 deletions libopenage/curve/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@ add_sources(libopenage
continuous.cpp
discrete.cpp
discrete_mod.cpp
element_wrapper.cpp
interpolated.cpp
iterator.cpp
keyframe.cpp
keyframe_container.cpp
map.cpp
map_filter_iterator.cpp
queue.cpp
queue_filter_iterator.cpp
segmented.cpp
)

add_subdirectory("container")
add_subdirectory("tests")
7 changes: 4 additions & 3 deletions libopenage/curve/base_curve.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2024 the openage authors. See copying.md for legal info.
// Copyright 2017-2025 the openage authors. See copying.md for legal info.

#pragma once

Expand Down Expand Up @@ -47,6 +47,7 @@ class BaseCurve : public event::EventEntity {
// registration. If you need to copy a curve, use the sync() method.
// TODO: if copying is enabled again, these members have to be reassigned: _id, _idstr, last_element
BaseCurve(const BaseCurve &) = delete;
BaseCurve &operator=(const BaseCurve &) = delete;

BaseCurve(BaseCurve &&) = default;

Expand Down Expand Up @@ -245,7 +246,7 @@ template <typename 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());
return elem.as_pair();
}


Expand All @@ -254,7 +255,7 @@ std::pair<time::time_t, const T> BaseCurve<T>::next_frame(const time::time_t &ti
auto e = this->container.last(time, this->container.size());
e++;
auto elem = this->container.get(e);
return std::make_pair(elem.time(), elem.val());
return elem.as_pair();
}

template <typename T>
Expand Down
9 changes: 9 additions & 0 deletions libopenage/curve/container/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
add_sources(libopenage
array.cpp
element_wrapper.cpp
iterator.cpp
map.cpp
map_filter_iterator.cpp
queue.cpp
queue_filter_iterator.cpp
)
10 changes: 10 additions & 0 deletions libopenage/curve/container/array.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2024-2025 the openage authors. See copying.md for legal info.


#include "array.h"

namespace openage::curve {

// This file is intended to be empty

} // openage::curve
Loading
Loading