161 lines
3.5 KiB
C++
161 lines
3.5 KiB
C++
#include "classictimeline.h"
|
|
#include "classicnotemanager.h"
|
|
#include <iostream>
|
|
|
|
ClassicTimeline::ClassicTimeline(const std::shared_ptr<ClassicNoteManager>& manager) :
|
|
_note_manager(manager),
|
|
_current_offset(0)
|
|
{}
|
|
|
|
void ClassicTimeline::setNotes(std::vector<ClassicNote *> &¬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);
|
|
});
|
|
}
|
|
|