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

ArrayIterator inherit from CurveIterator #1744

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 41 additions & 37 deletions libopenage/curve/container/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class Array : event::EventEntity {
public:
/// Underlying container type.
using container_t = std::array<KeyframeContainer<T>, Size>;

/// Uderlying iterator type
using const_iterator = typename std::array<KeyframeContainer<T>, Size>::const_iterator;

/// Index type to access elements in the container.
using index_t = typename container_t::size_type;

Expand Down Expand Up @@ -167,61 +171,60 @@ class Array : event::EventEntity {
return this->_idstr;
}

/**
* Array::Iterator is used to iterate over KeyframeContainers contained in a curve at a given time.
*/
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) {};

class ArrayIterator : public CurveIterator<T, Array<T, Size>> {
public:
/**
* returns a copy of the keyframe at the current offset and time
* Construct the iterator from its boundary conditions: time and container
*/
const T operator*() {
return this->curve->frame(this->time, this->offset).second;
ArrayIterator(const const_iterator &base,
const Array<T, Size> *base_container,
const time::time_t &to) :
CurveIterator<T, Array<T, Size>>(base, base_container, -time::TIME_MAX, to) {
}

/**
* increments the Iterator to point at the next KeyframeContainer
*/
void operator++() {
this->offset++;
}

/**
* Compare two Iterators by their offset
*/
bool operator!=(const Array<T, Size>::Iterator &rhs) const {
return this->offset != rhs.offset;
virtual bool valid() const override {
if (this->container->end().get_base() != this->get_base() && this->get_base()->begin()->time() <= this->to) {
return true;
}
return false;
}

private:
/**
* the curve object that this iterator, iterates over
* Get the keyFrame with a time <= this->to from the KeyframeContainer
* that this iterator currently points at
*/
Array<T, Size> *curve;

/**
* time at which this iterator is iterating over
*/
time::time_t time;
const T &value() const override {
const auto &key_frame_container = *this->get_base();
size_t hint_index = std::distance(this->container->begin().get_base(), this->get_base());
size_t e = key_frame_container.last(this->to, last_elements[hint_index]);
this->last_elements[hint_index] = e;
return key_frame_container.get(e).val();
}

/**
* used to index the Curve::Array pointed to by this iterator
* Cache hints for containers. Stores the index of the last keyframe accessed in each container.
*
* hints is used to speed up the search for keyframes.
*
* mutable as hints are updated by const read-only functions.
*/
size_t offset;
mutable std::array<typename KeyframeContainer<T>::elem_ptr, Size> last_elements = {};
};


/**
* iterator pointing to a keyframe of the first KeyframeContainer in the curve at a given time
*/
Iterator begin(const time::time_t &time = time::TIME_MIN);
ArrayIterator begin(const time::time_t &time = time::TIME_MIN) const;


/**
* iterator pointing after the last KeyframeContainer in the curve at a given time
*/
Iterator end(const time::time_t &time = time::TIME_MIN);
ArrayIterator end(const time::time_t &time = time::TIME_MAX) const;


private:
/**
Expand Down Expand Up @@ -382,13 +385,14 @@ void Array<T, Size>::sync(const Array<T, Size> &other,
}

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);
auto Array<T, Size>::begin(const time::time_t &t) const -> ArrayIterator {
return ArrayIterator(this->containers.begin(), this, t);
}


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->containers.size());
auto Array<T, Size>::end(const time::time_t &t) const -> ArrayIterator {
return ArrayIterator(this->containers.end(), this, t);
}

} // namespace curve
Expand Down
Loading