|
|
|
@ -2,7 +2,8 @@
|
|
|
|
|
#include "classicactions.h"
|
|
|
|
|
#include "classictimeline.h"
|
|
|
|
|
#include "classicnote.h"
|
|
|
|
|
#include "classicviewmanager.h"
|
|
|
|
|
#include "spritecontainer.h"
|
|
|
|
|
|
|
|
|
|
#include <SFML/Graphics/RenderTarget.hpp>
|
|
|
|
|
|
|
|
|
|
ClassicTimeline::ClassicTimeline()
|
|
|
|
@ -44,6 +45,7 @@ ClassicTimeline::ClassicTimeline()
|
|
|
|
|
x += 70;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expire(_first_visible_note);
|
|
|
|
|
expire(_last_visible_note);
|
|
|
|
|
expire(_active_note);
|
|
|
|
|
_top_note = _timeline.begin();
|
|
|
|
@ -65,9 +67,6 @@ void ClassicTimeline::clear()
|
|
|
|
|
delete note;
|
|
|
|
|
|
|
|
|
|
_timeline.clear();
|
|
|
|
|
expire(_top_note);
|
|
|
|
|
expire(_last_visible_note);
|
|
|
|
|
expire(_active_note);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::update()
|
|
|
|
@ -79,8 +78,12 @@ void ClassicTimeline::update()
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset)
|
|
|
|
|
{
|
|
|
|
|
if (!isExpired(_active_note)
|
|
|
|
|
&& ((!(*_active_note)->isActive(music_offset)) || (*_active_note)->state() == ClassicNote::State::DEAD))
|
|
|
|
|
if (isExpired(_active_note))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto note = *_active_note;
|
|
|
|
|
|
|
|
|
|
if (!note->isActive(music_offset))
|
|
|
|
|
{
|
|
|
|
|
expire(_active_note);
|
|
|
|
|
++_top_note;
|
|
|
|
@ -89,16 +92,16 @@ void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset)
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::checkForNextActiveNote(const microsec &music_offset)
|
|
|
|
|
{
|
|
|
|
|
if (isExpired(_active_note) && (*_top_note)->isActive(music_offset))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "New active note: " << music_offset << '\n';
|
|
|
|
|
if (!isExpired(_active_note))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto top_note = *_top_note;
|
|
|
|
|
if (top_note->isActive(music_offset))
|
|
|
|
|
_active_note = _top_note;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClassicTimeline::Iterator ClassicTimeline::getActiveNote() noexcept
|
|
|
|
|
{
|
|
|
|
|
update();
|
|
|
|
|
return _active_note;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -117,68 +120,74 @@ microsec ClassicTimeline::currentMusicOffset() const
|
|
|
|
|
return _music.getPlayingOffset().asMicroseconds();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::discardExpiredNotes(const std::unique_ptr<ClassicViewManager> &view_manager)
|
|
|
|
|
{
|
|
|
|
|
if (_top_note == _timeline.begin())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Iterator past_note = _top_note - 1;
|
|
|
|
|
std::shared_ptr<ClassicSprite> sprite = (*past_note)->sprite();
|
|
|
|
|
while (sprite)
|
|
|
|
|
{
|
|
|
|
|
auto state = (*past_note)->state();
|
|
|
|
|
if (state == ClassicNote::State::DEAD || state == ClassicNote::State::FLYING)
|
|
|
|
|
view_manager->resetNoteSprite(*past_note);
|
|
|
|
|
if (past_note == _timeline.begin())
|
|
|
|
|
return;
|
|
|
|
|
--past_note;
|
|
|
|
|
sprite = (*past_note)->sprite();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClassicTimeline::isVisiblyClose(const Iterator &iterator, const microsec &music_offset) const
|
|
|
|
|
{
|
|
|
|
|
return ((*iterator)->offset() - _visibility_offset) <= music_offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::fetchVisibleNotes(const std::unique_ptr<ClassicViewManager>& view_manager)
|
|
|
|
|
void ClassicTimeline::fetchVisibleNotes(SpriteContainer& sprite_container)
|
|
|
|
|
{
|
|
|
|
|
const microsec music_offset = currentMusicOffset();
|
|
|
|
|
discardExpiredNotes(view_manager);
|
|
|
|
|
initGraphicsForNewNotes(sprite_container, music_offset);
|
|
|
|
|
discardGraphicsForDeadNotes(sprite_container);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::initGraphicsForNewNotes(SpriteContainer& sprite_container, const microsec &music_offset)
|
|
|
|
|
{
|
|
|
|
|
Iterator note_iterator = _top_note;
|
|
|
|
|
while (isVisiblyClose(note_iterator, music_offset))
|
|
|
|
|
{
|
|
|
|
|
ClassicNote* note = *note_iterator;
|
|
|
|
|
if (!note->sprite())
|
|
|
|
|
{
|
|
|
|
|
note->saveAppearanceTime(music_offset);
|
|
|
|
|
view_manager->initNoteSprite(note);
|
|
|
|
|
}
|
|
|
|
|
if (nothingToDraw())
|
|
|
|
|
_first_visible_note = note_iterator;
|
|
|
|
|
|
|
|
|
|
if (note->state() == ClassicNote::State::DEAD)
|
|
|
|
|
view_manager->resetNoteSprite(note);
|
|
|
|
|
auto note = *note_iterator;
|
|
|
|
|
|
|
|
|
|
if (note->sprite())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
note->saveAppearanceTime(music_offset);
|
|
|
|
|
|
|
|
|
|
note->update(music_offset);
|
|
|
|
|
++note_iterator;
|
|
|
|
|
const auto action_type = note->action();
|
|
|
|
|
const auto sprite = sprite_container.getSprite(action_type);
|
|
|
|
|
note->setSprite(sprite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_last_visible_note = note_iterator;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::drawVisibleNotes(sf::RenderWindow &window) const
|
|
|
|
|
void ClassicTimeline::discardGraphicsForDeadNotes(SpriteContainer &sprite_container)
|
|
|
|
|
{
|
|
|
|
|
bool no_visible_notes = isExpired(_last_visible_note)
|
|
|
|
|
|| _top_note > _last_visible_note;
|
|
|
|
|
|
|
|
|
|
if (no_visible_notes)
|
|
|
|
|
if (nothingToDraw())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Iterator note_to_draw = _top_note;
|
|
|
|
|
while (note_to_draw != (_last_visible_note))
|
|
|
|
|
auto note_iterator = _first_visible_note;
|
|
|
|
|
while (note_iterator != _last_visible_note)
|
|
|
|
|
{
|
|
|
|
|
if ((*note_to_draw)->sprite())
|
|
|
|
|
window.draw(*(*note_to_draw));
|
|
|
|
|
++note_to_draw;
|
|
|
|
|
auto note = *note_iterator;
|
|
|
|
|
if (note->state() == ClassicNote::State::DEAD)
|
|
|
|
|
{
|
|
|
|
|
note->setState(ClassicNote::State::NONE);
|
|
|
|
|
const auto action_type = note->action();
|
|
|
|
|
sprite_container.resetSprite(note->sprite(), action_type);
|
|
|
|
|
note->setSprite(nullptr);
|
|
|
|
|
++_first_visible_note;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClassicTimeline::nothingToDraw() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return isExpired(_first_visible_note);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicTimeline::drawVisibleNotes(sf::RenderWindow &window) const
|
|
|
|
|
{
|
|
|
|
|
if (nothingToDraw())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
std::for_each(_first_visible_note, _last_visible_note,
|
|
|
|
|
[&window](const auto& note)
|
|
|
|
|
{
|
|
|
|
|
window.draw(*note);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|