Skip to content

Commit

Permalink
Merge branch 'master' into array_curve
Browse files Browse the repository at this point in the history
  • Loading branch information
jere8184 committed Dec 27, 2024
2 parents d9e5b51 + beb8945 commit dda1518
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 56 deletions.
1 change: 1 addition & 0 deletions .github/workflows/windows-server-2019.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ jobs:
$DLL_PATH = Join-Path package dll | Resolve-Path
cd package
python -m openage --add-dll-search-path $DLL_PATH --version
./run.exe test -a
shell: pwsh
- name: Publish build artifacts
uses: actions/upload-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/windows-server-2022.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ jobs:
$DLL_PATH = Join-Path package dll | Resolve-Path
cd package
python -m openage --add-dll-search-path $DLL_PATH --version
./run.exe test -a
shell: pwsh
- name: Publish build artifacts
uses: actions/upload-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions libopenage/curve/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_sources(libopenage
continuous.cpp
discrete.cpp
discrete_mod.cpp
element_wrapper.cpp
interpolated.cpp
iterator.cpp
keyframe.cpp
Expand Down
1 change: 1 addition & 0 deletions libopenage/curve/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Array : event::EventEntity {
EventEntity(loop, notifier), _id{id}, _idstr{idstr}, loop{loop} {}

Array(const Array &) = delete;
Array &operator=(const Array &) = delete;


/**
Expand Down
9 changes: 9 additions & 0 deletions libopenage/curve/element_wrapper.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 "element_wrapper.h"

namespace openage::curve {

// This file is intended to be empty

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

#pragma once

#include "time/time.h"

namespace openage::curve {

/**
* Wrapper for elements in a curve container.
*
* Stores the lifetime of the element (insertion time and erasure time) alongside the value.
*/
template <typename T>
class element_wrapper {
public:
/**
* Create a new element with insertion time \p time and a given value.
*
* Erasure time is set to time::TIME_MAX, i.e. the element is alive indefinitely.
*
* @param time Insertion time of the element.
* @param value Element value.
*/
element_wrapper(const time::time_t &time, const T &value) :
_alive{time},
_dead{time::TIME_MAX},
_value{value} {}

/**
* Create a new element with insertion time \p alive and erasure time \p dead and a given value.
*
* @param alive Insertion time of the element.
* @param dead Erasure time of the element.
* @param value Element value.
*/
element_wrapper(const time::time_t &alive, const time::time_t &dead, const T &value) :
_alive{alive},
_dead{dead},
_value{value} {}

/**
* Get the insertion time of this element.
*
* @return Time when the element was inserted into the container.
*/
const time::time_t &alive() const {
return _alive;
}

/**
* Get the erasure time of this element.
*
* @return Time when the element was erased from the container.
*/
const time::time_t &dead() const {
return _dead;
}

/**
* Set the erasure time of this element.
*
* @param time Time when the element was erased from the container.
*/
void set_dead(const time::time_t &time) {
_dead = time;
}

/**
* Get the value of this element.
*
* @return Value of the element.
*/
const T &value() const {
return _value;
}

private:
/**
* Time of insertion of the element into the container
*/
time::time_t _alive;

/**
* Time of erasure of the element from the container
*/
time::time_t _dead;

/**
* Element value
*/
T _value;
};

} // namespace openage::curve
22 changes: 6 additions & 16 deletions libopenage/curve/map.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2023 the openage authors. See copying.md for legal info.
// Copyright 2017-2024 the openage authors. See copying.md for legal info.

#pragma once

Expand All @@ -8,6 +8,7 @@
#include <utility>

#include "curve/map_filter_iterator.h"
#include "curve/element_wrapper.h"
#include "time/time.h"
#include "util/fixed_point.h"

Expand All @@ -20,26 +21,15 @@ namespace openage::curve {
*/
template <typename key_t, typename val_t>
class UnorderedMap {
/** Internal container to access all data and metadata */
struct map_element {
map_element(const val_t &v, const time::time_t &a, const time::time_t &d) :
value(v),
alive(a),
dead(d) {}

val_t value;
time::time_t alive;
time::time_t dead;
};

/**
* Data holder. Maps keys to map elements.
* Map elements themselves store when they are valid.
*/
std::unordered_map<key_t, map_element> container;
std::unordered_map<key_t, element_wrapper<val_t>> container;

public:
using const_iterator = typename std::unordered_map<key_t, map_element>::const_iterator;
using const_iterator = typename std::unordered_map<key_t, element_wrapper<val_t>>::const_iterator;

std::optional<MapFilterIterator<key_t, val_t, UnorderedMap>>
operator()(const time::time_t &, const key_t &) const;
Expand Down Expand Up @@ -95,7 +85,7 @@ std::optional<MapFilterIterator<key_t, val_t, UnorderedMap<key_t, val_t>>>
UnorderedMap<key_t, val_t>::at(const time::time_t &time,
const key_t &key) const {
auto e = this->container.find(key);
if (e != this->container.end() and e->second.alive <= time and e->second.dead > time) {
if (e != this->container.end() and e->second.alive() <= time and e->second.dead() > time) {
return MapFilterIterator<key_t, val_t, UnorderedMap<key_t, val_t>>(
e,
this,
Expand Down Expand Up @@ -160,7 +150,7 @@ UnorderedMap<key_t, val_t>::insert(const time::time_t &alive,
const time::time_t &dead,
const key_t &key,
const val_t &value) {
map_element e(value, alive, dead);
element_wrapper<val_t> e{alive, dead, value};
auto it = this->container.insert(std::make_pair(key, e));
return MapFilterIterator<key_t, val_t, UnorderedMap<key_t, val_t>>(
it.first,
Expand Down
8 changes: 4 additions & 4 deletions libopenage/curve/map_filter_iterator.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2023 the openage authors. See copying.md for legal info.
// Copyright 2017-2024 the openage authors. See copying.md for legal info.

#pragma once

Expand Down Expand Up @@ -35,16 +35,16 @@ class MapFilterIterator : public CurveIterator<val_t, container_t> {
using CurveIterator<val_t, container_t>::operator=;

virtual bool valid() const override {
return (this->get_base()->second.alive >= this->from
and this->get_base()->second.dead < this->to);
return (this->get_base()->second.alive() >= this->from
and this->get_base()->second.dead() < this->to);
}

/**
* Get the value behind the iterator.
* Nicer way of accessing it beside operator *.
*/
val_t const &value() const override {
return this->get_base()->second.value;
return this->get_base()->second.value();
}

/**
Expand Down
37 changes: 5 additions & 32 deletions libopenage/curve/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "curve/iterator.h"
#include "curve/queue_filter_iterator.h"
#include "curve/element_wrapper.h"
#include "event/evententity.h"
#include "time/time.h"
#include "util/fixed_point.h"
Expand All @@ -32,39 +33,11 @@ namespace curve {
*/
template <class T>
class Queue : public event::EventEntity {
struct queue_wrapper {
// Insertion time of the element
time::time_t _alive;
// Erase time of the element
// TODO: this has to be mutable because erase() will complain otherwise
mutable time::time_t _dead;
// Element value
T value;

queue_wrapper(const time::time_t &time, const T &value) :
_alive{time},
_dead{time::TIME_MAX},
value{value} {}

const time::time_t &alive() const {
return _alive;
}

const time::time_t &dead() const {
return _dead;
}

// TODO: this has to be const because erase() will complain otherwise
void set_dead(const time::time_t &time) const {
_dead = time;
}
};

public:
/**
* The underlaying container type.
*/
using container_t = typename std::vector<queue_wrapper>;
using container_t = typename std::vector<element_wrapper<T>>;

/**
* The index type to access elements in the container
Expand Down Expand Up @@ -304,7 +277,7 @@ const T &Queue<T>::front(const time::time_t &time) const {
<< ", container size: " << this->container.size()
<< ")");

return this->container.at(at).value;
return this->container.at(at).value();
}


Expand All @@ -330,7 +303,7 @@ const T &Queue<T>::pop_front(const time::time_t &time) {

this->changes(time);

return this->container.at(at).value;
return this->container.at(at).value();
}


Expand Down Expand Up @@ -412,7 +385,7 @@ QueueFilterIterator<T, Queue<T>> Queue<T>::insert(const time::time_t &time,

// Get the iterator to the insertion point
iterator insertion_point = std::next(this->container.begin(), at);
insertion_point = this->container.insert(insertion_point, queue_wrapper{time, e});
insertion_point = this->container.insert(insertion_point, element_wrapper<T>{time, e});

// TODO: Inserting before any dead elements shoud reset their death time
// since by definition, they cannot be popped before the new element
Expand Down
2 changes: 1 addition & 1 deletion libopenage/curve/queue_filter_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class QueueFilterIterator : public CurveIterator<val_t, container_t, typename co

const val_t &value() const override {
const auto &a = *this->get_base();
return a.value;
return a.value();
}
};

Expand Down
3 changes: 0 additions & 3 deletions libopenage/curve/tests/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,6 @@ void test_array() {
TESTEQUALS(next_frame.second, 40);
TESTEQUALS(next_frame.first, 5);

// Test operator[]
TESTEQUALS(a[0].get(a[0].last(2)).val(), 25);
TESTEQUALS(a[1].get(a[1].last(2)).val(), 5);

// Test begin and end
auto it = a.begin(1);
Expand Down

0 comments on commit dda1518

Please sign in to comment.