#include "classictimeline.h" #include "classicnotemanager.h" #include ClassicTimeline::ClassicTimeline(const std::shared_ptr& manager) : _note_manager(manager), _current_offset(0) {} void ClassicTimeline::setNotes(std::vector &¬es, const microsec &visibility) { _visibility_offset = visibility; _timeline = std::move(notes); _top_note = _timeline.begin(); expire(_first_visible_note); expire(_last_visible_note); expire(_active_note); fetchVisibleNotes(); } ClassicTimeline::~ClassicTimeline() { clear(); } void ClassicTimeline::clear() { for (auto& note : _timeline) delete note; _timeline.clear(); } void ClassicTimeline::update(const microsec& offset) { _current_offset = offset; checkCurrentActiveNote(); checkForNextActiveNote(); updateVisibleSprites(_current_offset); } void ClassicTimeline::checkCurrentActiveNote() { if (isExpired(_active_note)) return; auto note = *_active_note; if (!_note_manager->isActive(note)) { expire(_active_note); ++_top_note; } } void ClassicTimeline::checkForNextActiveNote() { if (!isExpired(_active_note)) return; auto top_note = *_top_note; if (_note_manager->isActive(top_note)) _active_note = _top_note; } void ClassicTimeline::updateVisibleSprites(const microsec& music_offset) { if (nothingToDraw()) return; const auto& note_manager = _note_manager; std::for_each(_first_visible_note, _last_visible_note, [¬e_manager, &music_offset](const auto& note) { note_manager->update(note, music_offset); }); } ClassicTimeline::Iterator ClassicTimeline::getActiveNote() noexcept { return _active_note; } bool ClassicTimeline::isExpired(const Iterator& iterator) const { return iterator == _timeline.end(); } void ClassicTimeline::expire(Iterator& iterator) { iterator = _timeline.end(); } bool ClassicTimeline::isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const { return ((*iterator)->evaluator.offset() - _visibility_offset) <= music_offset; } void ClassicTimeline::fetchVisibleNotes() { findLastVisibleNote(_current_offset); findFirstVisibleNote(); } void ClassicTimeline::findLastVisibleNote(const microsec &music_offset) { Iterator note_iterator = _top_note; while (isVisiblyClose(note_iterator, music_offset)) { if (nothingToDraw()) _first_visible_note = note_iterator; auto note = *note_iterator; if (!_note_manager->isInGame(note)) _note_manager->putToGame(note, music_offset); ++note_iterator; } _last_visible_note = note_iterator; } void ClassicTimeline::findFirstVisibleNote() { if (nothingToDraw()) return; auto note_iterator = _first_visible_note; while (note_iterator != _last_visible_note) { auto note = *note_iterator; if (_note_manager->shouldRemove(note)) ++_first_visible_note; ++note_iterator; } } bool ClassicTimeline::nothingToDraw() const noexcept { return isExpired(_first_visible_note); } void ClassicTimeline::drawVisibleNotes() const { if (nothingToDraw()) return; const auto& note_manager = _note_manager; std::for_each(_first_visible_note, _last_visible_note, [¬e_manager](const auto& note) { note_manager->draw(note); }); }