Skip to content

Commit fb36b9d

Browse files
authored
Merge pull request #1744 from jere8184/array_curve
ArrayIterator inherit from CurveIterator
2 parents 1bd3cfa + 768bd99 commit fb36b9d

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

libopenage/curve/container/array.h

+41-37
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class Array : event::EventEntity {
2626
public:
2727
/// Underlying container type.
2828
using container_t = std::array<KeyframeContainer<T>, Size>;
29+
30+
/// Uderlying iterator type
31+
using const_iterator = typename std::array<KeyframeContainer<T>, Size>::const_iterator;
32+
2933
/// Index type to access elements in the container.
3034
using index_t = typename container_t::size_type;
3135

@@ -167,61 +171,60 @@ class Array : event::EventEntity {
167171
return this->_idstr;
168172
}
169173

170-
/**
171-
* Array::Iterator is used to iterate over KeyframeContainers contained in a curve at a given time.
172-
*/
173-
class Iterator {
174-
public:
175-
Iterator(Array<T, Size> *curve, const time::time_t &time = time::TIME_MAX, size_t offset = 0) :
176-
curve(curve), time(time), offset(offset) {};
177174

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

185-
/**
186-
* increments the Iterator to point at the next KeyframeContainer
187-
*/
188-
void operator++() {
189-
this->offset++;
190-
}
191186

192-
/**
193-
* Compare two Iterators by their offset
194-
*/
195-
bool operator!=(const Array<T, Size>::Iterator &rhs) const {
196-
return this->offset != rhs.offset;
187+
virtual bool valid() const override {
188+
if (this->container->end().get_base() != this->get_base() && this->get_base()->begin()->time() <= this->to) {
189+
return true;
190+
}
191+
return false;
197192
}
198193

199-
private:
200194
/**
201-
* the curve object that this iterator, iterates over
195+
* Get the keyFrame with a time <= this->to from the KeyframeContainer
196+
* that this iterator currently points at
202197
*/
203-
Array<T, Size> *curve;
204-
205-
/**
206-
* time at which this iterator is iterating over
207-
*/
208-
time::time_t time;
198+
const T &value() const override {
199+
const auto &key_frame_container = *this->get_base();
200+
size_t hint_index = std::distance(this->container->begin().get_base(), this->get_base());
201+
size_t e = key_frame_container.last(this->to, last_elements[hint_index]);
202+
this->last_elements[hint_index] = e;
203+
return key_frame_container.get(e).val();
204+
}
209205

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

216+
216217
/**
217218
* iterator pointing to a keyframe of the first KeyframeContainer in the curve at a given time
218219
*/
219-
Iterator begin(const time::time_t &time = time::TIME_MIN);
220+
ArrayIterator begin(const time::time_t &time = time::TIME_MIN) const;
221+
220222

221223
/**
222224
* iterator pointing after the last KeyframeContainer in the curve at a given time
223225
*/
224-
Iterator end(const time::time_t &time = time::TIME_MIN);
226+
ArrayIterator end(const time::time_t &time = time::TIME_MAX) const;
227+
225228

226229
private:
227230
/**
@@ -382,13 +385,14 @@ void Array<T, Size>::sync(const Array<T, Size> &other,
382385
}
383386

384387
template <typename T, size_t Size>
385-
typename Array<T, Size>::Iterator Array<T, Size>::begin(const time::time_t &time) {
386-
return Array<T, Size>::Iterator(this, time);
388+
auto Array<T, Size>::begin(const time::time_t &t) const -> ArrayIterator {
389+
return ArrayIterator(this->containers.begin(), this, t);
387390
}
388391

392+
389393
template <typename T, size_t Size>
390-
typename Array<T, Size>::Iterator Array<T, Size>::end(const time::time_t &time) {
391-
return Array<T, Size>::Iterator(this, time, this->containers.size());
394+
auto Array<T, Size>::end(const time::time_t &t) const -> ArrayIterator {
395+
return ArrayIterator(this->containers.end(), this, t);
392396
}
393397

394398
} // namespace curve

0 commit comments

Comments
 (0)