Skip to content

Commit

Permalink
Merge pull request #1724 from jere8184/array_curve
Browse files Browse the repository at this point in the history
Array curve
  • Loading branch information
heinezen authored Jan 19, 2025
2 parents 3850400 + d571822 commit 6d9d8d7
Show file tree
Hide file tree
Showing 27 changed files with 615 additions and 55 deletions.
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

0 comments on commit 6d9d8d7

Please sign in to comment.