#pragma once #include "game/timeline.h" #include #include class ClassicNote; class ClassicNoteManager; class ClassicTimeline : public Timeline { public: explicit ClassicTimeline(const std::shared_ptr& manager); virtual ~ClassicTimeline(); virtual void update(const microsec& offset) override; virtual void clear() override; virtual void drawVisibleNotes() const override; void setNotes(std::vector&& notes, const microsec& visibility); void fetchVisibleNotes(); void findLastVisibleNote(const microsec& music_offset); void findFirstVisibleNote(); using Iterator = std::vector::const_iterator; Iterator getActiveNote() noexcept; bool isExpired(const Iterator& iterator) const; inline void expire(Iterator& iterator); private: std::shared_ptr _note_manager; std::vector _input_intervals; std::vector _timeline; microsec _visibility_offset; microsec _current_offset; void updateVisibleSprites(const microsec& music_offset); void checkCurrentActiveNote(); void checkForNextActiveNote(); bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const; inline bool nothingToDraw() const noexcept; /* Difference between top and active note is that * top note is the note handling input right now * OR it's the closest note from current music offset * position, not necessarily active. A note stops being top only * after dying or being tapped by player, even if it's already * past her perfect offset. * * Meanwhile active note is the note which is currently handling * player input for grade. * * An active note is always top note but a top note * is not always active note. * */ Iterator _top_note; Iterator _active_note; Iterator _last_visible_note; Iterator _first_visible_note; };