Iterative refactoring of what's done to this moment
This commit is contained in:
		
							parent
							
								
									ad1b31c95c
								
							
						
					
					
						commit
						106697f6af
					
				| @ -4,4 +4,5 @@ class Sprite | |||||||
| { | { | ||||||
| public: | public: | ||||||
|     virtual ~Sprite() = default; |     virtual ~Sprite() = default; | ||||||
|  |     virtual void reset() = 0; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,12 +0,0 @@ | |||||||
| #ifndef TIMELINEVIEWMANAGER_H |  | ||||||
| #define TIMELINEVIEWMANAGER_H |  | ||||||
| 
 |  | ||||||
| class Note; |  | ||||||
| 
 |  | ||||||
| class TimelineViewManager |  | ||||||
| { |  | ||||||
| public: |  | ||||||
|     virtual ~TimelineViewManager() = default; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| #endif // TIMELINEVIEWMANAGER_H
 |  | ||||||
| @ -44,10 +44,16 @@ void Application::input() | |||||||
|     sf::Event event; |     sf::Event event; | ||||||
|     while (_game_window.pollEvent(event)) |     while (_game_window.pollEvent(event)) | ||||||
|     { |     { | ||||||
|         if (event.type == sf::Event::Closed) |         switch(event.type) | ||||||
|  |         { | ||||||
|  |         case sf::Event::Closed: | ||||||
|             _game_window.close(); |             _game_window.close(); | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|  |         default: | ||||||
|             _game->input(event); |             _game->input(event); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,12 +1,11 @@ | |||||||
| #include "classicgame.h" | #include "classicgame.h" | ||||||
| #include "classicinputtype.h" | #include "classicinputtype.h" | ||||||
| #include "classictimeline.h" | #include "classictimeline.h" | ||||||
| #include "classicviewmanager.h" | #include "spritecontainer.h" | ||||||
| #include "classicnote.h" | #include "classicnote.h" | ||||||
| 
 | 
 | ||||||
| ClassicGame::ClassicGame() : | ClassicGame::ClassicGame() : | ||||||
|     _timeline(std::make_unique<ClassicTimeline>()), |     _timeline(std::make_unique<ClassicTimeline>()) | ||||||
|     _view_manager(std::make_unique<ClassicViewManager>()) |  | ||||||
| { | { | ||||||
|     _keys_to_buttons = |     _keys_to_buttons = | ||||||
|     { |     { | ||||||
| @ -52,7 +51,7 @@ ClassicGame::~ClassicGame() | |||||||
| 
 | 
 | ||||||
| void ClassicGame::run() | void ClassicGame::run() | ||||||
| { | { | ||||||
|     _timeline->fetchVisibleNotes(_view_manager); |     _timeline->fetchVisibleNotes(_sprite_container); | ||||||
|     _timeline->run(); |     _timeline->run(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -82,7 +81,7 @@ void ClassicGame::input(const sf::Event& event) | |||||||
| 
 | 
 | ||||||
|     auto note = _timeline->getActiveNote(); |     auto note = _timeline->getActiveNote(); | ||||||
| 
 | 
 | ||||||
|     if (!_timeline->isExpired(note) && (*note)->state() == ClassicNote::State::FLYING) |     if (!_timeline->isExpired(note)) | ||||||
|     { |     { | ||||||
|         (*note)->input(ClassicInputType(timestamp, new_action)); |         (*note)->input(ClassicInputType(timestamp, new_action)); | ||||||
|     } |     } | ||||||
| @ -101,7 +100,7 @@ Action ClassicGame::getActionKeyReleased(Button button) const | |||||||
| void ClassicGame::update() | void ClassicGame::update() | ||||||
| { | { | ||||||
|     _timeline->update(); |     _timeline->update(); | ||||||
|     _timeline->fetchVisibleNotes(_view_manager); |     _timeline->fetchVisibleNotes(_sprite_container); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicGame::draw(sf::RenderWindow& window) const | void ClassicGame::draw(sf::RenderWindow& window) const | ||||||
|  | |||||||
| @ -5,9 +5,9 @@ | |||||||
| #include <list> | #include <list> | ||||||
| #include "game.h" | #include "game.h" | ||||||
| #include "classicactions.h" | #include "classicactions.h" | ||||||
|  | #include "spritecontainer.h" | ||||||
| 
 | 
 | ||||||
| class ClassicTimeline; | class ClassicTimeline; | ||||||
| class ClassicViewManager; |  | ||||||
| 
 | 
 | ||||||
| class ClassicGame final : public Game | class ClassicGame final : public Game | ||||||
| { | { | ||||||
| @ -30,7 +30,7 @@ private: | |||||||
|     Action getActionKeyReleased(Button button) const; |     Action getActionKeyReleased(Button button) const; | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<ClassicTimeline> _timeline; |     std::unique_ptr<ClassicTimeline> _timeline; | ||||||
|     std::unique_ptr<ClassicViewManager> _view_manager; |     SpriteContainer _sprite_container; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // CLASSICGAME_H
 | #endif // CLASSICGAME_H
 | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfec | |||||||
|     _coordinates(coord), |     _coordinates(coord), | ||||||
|     _evaluator(intervals, _perfect_offset), |     _evaluator(intervals, _perfect_offset), | ||||||
|     _action(action), |     _action(action), | ||||||
|  |     _state(State::NONE), | ||||||
|     _appearance_time(0) |     _appearance_time(0) | ||||||
| {} | {} | ||||||
| 
 | 
 | ||||||
| @ -26,8 +27,18 @@ static int getPt( int n1 , int n2 , float perc ) | |||||||
| 
 | 
 | ||||||
| void ClassicNote::update(const microsec& music_offset) | void ClassicNote::update(const microsec& music_offset) | ||||||
| { | { | ||||||
|     auto update_time = music_offset - _appearance_time; |     switch (_state)   // States will be objects
 | ||||||
|     auto i = update_time / _trail_path_percent / 100; |     { | ||||||
|  |     case State::DYING: | ||||||
|  |         _sprite->update(); | ||||||
|  |         if (_sprite->isDead()) | ||||||
|  |             setState(State::DEAD); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     case State::FLYING: | ||||||
|  |     { | ||||||
|  |         auto update_time = music_offset - _appearance_time;   // This all will be inside ::update
 | ||||||
|  |         auto i = update_time / _trail_path_percent / 100;      //         of an animation object
 | ||||||
| 
 | 
 | ||||||
|         int xa = getPt( 720./2. , 1280./2. , i ); |         int xa = getPt( 720./2. , 1280./2. , i ); | ||||||
|         int ya = getPt( 0 , 720./2. , i ); |         int ya = getPt( 0 , 720./2. , i ); | ||||||
| @ -35,10 +46,12 @@ void ClassicNote::update(const microsec& music_offset) | |||||||
|         int yb = getPt( 720./2. , _coordinates.y , i ); |         int yb = getPt( 720./2. , _coordinates.y , i ); | ||||||
| 
 | 
 | ||||||
|         _sprite->update(getPt( xa , xb , i ), getPt( ya , yb , i )); |         _sprite->update(getPt( xa , xb , i ), getPt( ya , yb , i )); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (_state == State::DYING) |     default: | ||||||
|         if (_sprite->isDead()) |         break; | ||||||
|             _state = State::DEAD; |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicNote::draw(sf::RenderTarget& target, sf::RenderStates states) const | void ClassicNote::draw(sf::RenderTarget& target, sf::RenderStates states) const | ||||||
| @ -51,13 +64,12 @@ auto ClassicNote::input(ClassicInputType&& input_data) -> Grade | |||||||
|     auto grade = ClassicNote::Grade::BAD; |     auto grade = ClassicNote::Grade::BAD; | ||||||
| 
 | 
 | ||||||
|     if (input_data == _action) |     if (input_data == _action) | ||||||
|     { |  | ||||||
|         grade = _evaluator.calculatePrecision(input_data.timestamp()); |         grade = _evaluator.calculatePrecision(input_data.timestamp()); | ||||||
|     } | 
 | ||||||
|  |     setState(State::DYING); | ||||||
| 
 | 
 | ||||||
|     std::cout << "User input: " << static_cast<int>(grade) << "\n"; |     std::cout << "User input: " << static_cast<int>(grade) << "\n"; | ||||||
|     _state = State::DYING; | 
 | ||||||
|     _sprite->showGrade(); |  | ||||||
|     return grade; |     return grade; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -73,6 +85,24 @@ auto ClassicNote::state() const -> State | |||||||
| 
 | 
 | ||||||
| void ClassicNote::setState(State next_state) | void ClassicNote::setState(State next_state) | ||||||
| { | { | ||||||
|  |     switch (next_state)   // States will be objects
 | ||||||
|  |     { | ||||||
|  |     case State::DYING: | ||||||
|  |         _sprite->pulse(); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     case State::FLYING: | ||||||
|  |         _sprite->setCoordinates(_coordinates.x, _coordinates.y, 720/2, 50); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     case State::NONE: | ||||||
|  |         _sprite->reset(); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     _state = next_state; |     _state = next_state; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -91,7 +121,7 @@ void ClassicNote::setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexce | |||||||
| { | { | ||||||
|     _sprite = sprite; |     _sprite = sprite; | ||||||
|     if (_sprite) |     if (_sprite) | ||||||
|         _sprite->setCoordinates(_coordinates.x, _coordinates.y, 720/2, 50); |         setState(State::FLYING); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Coordinates& ClassicNote::getCoordinates() const noexcept | const Coordinates& ClassicNote::getCoordinates() const noexcept | ||||||
|  | |||||||
| @ -32,6 +32,8 @@ public: | |||||||
| 
 | 
 | ||||||
|     enum class State |     enum class State | ||||||
|     { |     { | ||||||
|  |           NONE, | ||||||
|  | 
 | ||||||
|         FLYING, |         FLYING, | ||||||
|          DYING, |          DYING, | ||||||
|           DEAD |           DEAD | ||||||
| @ -60,7 +62,7 @@ private: | |||||||
|     const Coordinates _coordinates; |     const Coordinates _coordinates; | ||||||
|     const PrecisionEvaluator<Grade> _evaluator; |     const PrecisionEvaluator<Grade> _evaluator; | ||||||
|     const Action _action; |     const Action _action; | ||||||
|     State _state = State::FLYING; |     State _state; | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<ClassicSprite> _sprite; |     std::shared_ptr<ClassicSprite> _sprite; | ||||||
|     microsec _appearance_time; |     microsec _appearance_time; | ||||||
|  | |||||||
| @ -16,6 +16,14 @@ void ClassicSprite::draw(sf::RenderTarget& target, sf::RenderStates states) cons | |||||||
|     target.draw(_grade_text, states); |     target.draw(_grade_text, states); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ClassicSprite::reset() | ||||||
|  | { | ||||||
|  |     _shape.setPosition(0, 0); | ||||||
|  |     _trail.setPosition(0, 0); | ||||||
|  |     _grade_text.setPosition(0, 0); | ||||||
|  |     _grade_text.setFillColor(sf::Color(255, 255, 255, 0)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_y) noexcept | void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_y) noexcept | ||||||
| { | { | ||||||
|     _shape.setPosition(x, y); |     _shape.setPosition(x, y); | ||||||
| @ -26,12 +34,17 @@ void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_ | |||||||
| void ClassicSprite::update(float trail_x, float trail_y) noexcept | void ClassicSprite::update(float trail_x, float trail_y) noexcept | ||||||
| { | { | ||||||
|     _trail.setPosition(trail_x, trail_y); |     _trail.setPosition(trail_x, trail_y); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ClassicSprite::update() noexcept | ||||||
|  | { | ||||||
|     fade(); |     fade(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicSprite::showGrade() | void ClassicSprite::pulse() | ||||||
| { | { | ||||||
|     _grade_text.setFillColor(sf::Color(255, 255, 255, 255)); |     _grade_text.setFillColor(sf::Color(255, 255, 255, 255)); | ||||||
|  |     _shape.setFillColor(sf::Color(140, 140, 140)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicSprite::fade() | void ClassicSprite::fade() | ||||||
| @ -41,13 +54,24 @@ void ClassicSprite::fade() | |||||||
|     if (fill_color.a == 0) |     if (fill_color.a == 0) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     const auto new_alpha = fill_color.a - 55; |     auto new_alpha = fill_color.a - 55; | ||||||
|     fill_color.a = new_alpha < 0 ? 0 : new_alpha; |     fill_color.a = new_alpha < 0 ? 0 : new_alpha; | ||||||
| 
 | 
 | ||||||
|     _grade_text.setFillColor(fill_color); |     _grade_text.setFillColor(fill_color); | ||||||
|  | 
 | ||||||
|  |     fill_color = _shape.getFillColor(); | ||||||
|  | 
 | ||||||
|  |     if (fill_color.a == 0) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     new_alpha = fill_color.a - 55; | ||||||
|  |     fill_color.a = new_alpha < 0 ? 0 : new_alpha; | ||||||
|  | 
 | ||||||
|  |     _shape.setFillColor(fill_color); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ClassicSprite::isDead() const | bool ClassicSprite::isDead() const | ||||||
| { | { | ||||||
|     return _grade_text.getFillColor().a == 0; |     return _grade_text.getFillColor().a == 0 | ||||||
|  |         ||      _shape.getFillColor().a == 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,10 +9,13 @@ class ClassicSprite : public Sprite, public sf::Drawable | |||||||
| public: | public: | ||||||
|     ClassicSprite(const sf::RectangleShape& shape, const sf::Font &font); |     ClassicSprite(const sf::RectangleShape& shape, const sf::Font &font); | ||||||
|     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; |     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; | ||||||
|  |     virtual void reset() override; | ||||||
| 
 | 
 | ||||||
|     void setCoordinates(float x, float y, float trail_x, float trail_y) noexcept; |     void setCoordinates(float x, float y, float trail_x, float trail_y) noexcept; | ||||||
|     void update(float trail_x, float trail_y) noexcept; |     void update(float trail_x, float trail_y) noexcept; | ||||||
|     void showGrade(); |     void update() noexcept; | ||||||
|  | 
 | ||||||
|  |     void pulse(); | ||||||
|     void fade(); |     void fade(); | ||||||
|     bool isDead() const; |     bool isDead() const; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,7 +2,8 @@ | |||||||
| #include "classicactions.h" | #include "classicactions.h" | ||||||
| #include "classictimeline.h" | #include "classictimeline.h" | ||||||
| #include "classicnote.h" | #include "classicnote.h" | ||||||
| #include "classicviewmanager.h" | #include "spritecontainer.h" | ||||||
|  | 
 | ||||||
| #include <SFML/Graphics/RenderTarget.hpp> | #include <SFML/Graphics/RenderTarget.hpp> | ||||||
| 
 | 
 | ||||||
| ClassicTimeline::ClassicTimeline() | ClassicTimeline::ClassicTimeline() | ||||||
| @ -44,6 +45,7 @@ ClassicTimeline::ClassicTimeline() | |||||||
|         x += 70; |         x += 70; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     expire(_first_visible_note); | ||||||
|     expire(_last_visible_note); |     expire(_last_visible_note); | ||||||
|     expire(_active_note); |     expire(_active_note); | ||||||
|     _top_note = _timeline.begin(); |     _top_note = _timeline.begin(); | ||||||
| @ -65,9 +67,6 @@ void ClassicTimeline::clear() | |||||||
|         delete note; |         delete note; | ||||||
| 
 | 
 | ||||||
|     _timeline.clear(); |     _timeline.clear(); | ||||||
|     expire(_top_note); |  | ||||||
|     expire(_last_visible_note); |  | ||||||
|     expire(_active_note); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicTimeline::update() | void ClassicTimeline::update() | ||||||
| @ -79,8 +78,12 @@ void ClassicTimeline::update() | |||||||
| 
 | 
 | ||||||
| void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset) | void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset) | ||||||
| { | { | ||||||
|     if (!isExpired(_active_note) |     if (isExpired(_active_note)) | ||||||
|     && ((!(*_active_note)->isActive(music_offset)) || (*_active_note)->state() == ClassicNote::State::DEAD)) |         return; | ||||||
|  | 
 | ||||||
|  |     auto note = *_active_note; | ||||||
|  | 
 | ||||||
|  |     if (!note->isActive(music_offset)) | ||||||
|     { |     { | ||||||
|         expire(_active_note); |         expire(_active_note); | ||||||
|         ++_top_note; |         ++_top_note; | ||||||
| @ -89,16 +92,16 @@ void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset) | |||||||
| 
 | 
 | ||||||
| void ClassicTimeline::checkForNextActiveNote(const microsec &music_offset) | void ClassicTimeline::checkForNextActiveNote(const microsec &music_offset) | ||||||
| { | { | ||||||
|     if (isExpired(_active_note) && (*_top_note)->isActive(music_offset)) |     if (!isExpired(_active_note)) | ||||||
|     { |         return; | ||||||
|         std::cout << "New active note: " << music_offset << '\n'; | 
 | ||||||
|  |     auto top_note = *_top_note; | ||||||
|  |     if (top_note->isActive(music_offset)) | ||||||
|         _active_note = _top_note; |         _active_note = _top_note; | ||||||
| } | } | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| ClassicTimeline::Iterator ClassicTimeline::getActiveNote() noexcept | ClassicTimeline::Iterator ClassicTimeline::getActiveNote() noexcept | ||||||
| { | { | ||||||
|     update(); |  | ||||||
|     return _active_note; |     return _active_note; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -117,68 +120,74 @@ microsec ClassicTimeline::currentMusicOffset() const | |||||||
|     return _music.getPlayingOffset().asMicroseconds(); |     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 | bool ClassicTimeline::isVisiblyClose(const Iterator &iterator, const microsec &music_offset) const | ||||||
| { | { | ||||||
|     return ((*iterator)->offset() - _visibility_offset) <= music_offset; |     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(); |     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; |     Iterator note_iterator = _top_note; | ||||||
|     while (isVisiblyClose(note_iterator, music_offset)) |     while (isVisiblyClose(note_iterator, music_offset)) | ||||||
|     { |     { | ||||||
|         ClassicNote* note = *note_iterator; |         if (nothingToDraw()) | ||||||
|         if (!note->sprite()) |             _first_visible_note = note_iterator; | ||||||
|         { | 
 | ||||||
|  |         auto note = *note_iterator; | ||||||
|  | 
 | ||||||
|  |         if (note->sprite()) | ||||||
|  |             continue; | ||||||
|  | 
 | ||||||
|         note->saveAppearanceTime(music_offset); |         note->saveAppearanceTime(music_offset); | ||||||
|             view_manager->initNoteSprite(note); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (note->state() == ClassicNote::State::DEAD) |         const auto action_type = note->action(); | ||||||
|             view_manager->resetNoteSprite(note); |         const auto sprite = sprite_container.getSprite(action_type); | ||||||
| 
 |         note->setSprite(sprite); | ||||||
|         note->update(music_offset); |  | ||||||
|         ++note_iterator; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     _last_visible_note = note_iterator; |     _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) |     if (nothingToDraw()) | ||||||
|                          || _top_note > _last_visible_note; |  | ||||||
| 
 |  | ||||||
|     if (no_visible_notes) |  | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     Iterator note_to_draw = _top_note; |     auto note_iterator = _first_visible_note; | ||||||
|     while (note_to_draw != (_last_visible_note)) |     while (note_iterator != _last_visible_note) | ||||||
|     { |     { | ||||||
|         if ((*note_to_draw)->sprite()) |         auto note = *note_iterator; | ||||||
|             window.draw(*(*note_to_draw)); |         if (note->state() == ClassicNote::State::DEAD) | ||||||
|         ++note_to_draw; |         { | ||||||
|  |             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); | ||||||
|  |                   }); | ||||||
|  | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ | |||||||
| #include <SFML/Audio/Music.hpp> | #include <SFML/Audio/Music.hpp> | ||||||
| 
 | 
 | ||||||
| class ClassicNote; | class ClassicNote; | ||||||
| class ClassicViewManager; | class SpriteContainer; | ||||||
| 
 | 
 | ||||||
| class ClassicTimeline : public Timeline | class ClassicTimeline : public Timeline | ||||||
| { | { | ||||||
| @ -20,7 +20,9 @@ public: | |||||||
|     virtual microsec currentMusicOffset() const override; |     virtual microsec currentMusicOffset() const override; | ||||||
|     virtual void drawVisibleNotes(sf::RenderWindow& window) const override; |     virtual void drawVisibleNotes(sf::RenderWindow& window) const override; | ||||||
| 
 | 
 | ||||||
|     void fetchVisibleNotes(const std::unique_ptr<ClassicViewManager>& view_manager); |     void fetchVisibleNotes(SpriteContainer& sprite_container); | ||||||
|  |     void initGraphicsForNewNotes(SpriteContainer& sprite_container, const microsec& music_offset); | ||||||
|  |     void discardGraphicsForDeadNotes(SpriteContainer& sprite_container); | ||||||
| 
 | 
 | ||||||
|     using Iterator = std::vector<ClassicNote*>::const_iterator; |     using Iterator = std::vector<ClassicNote*>::const_iterator; | ||||||
| 
 | 
 | ||||||
| @ -34,6 +36,7 @@ private: | |||||||
|     Iterator _top_note; |     Iterator _top_note; | ||||||
|     Iterator _active_note; |     Iterator _active_note; | ||||||
|     Iterator _last_visible_note; |     Iterator _last_visible_note; | ||||||
|  |     Iterator _first_visible_note; | ||||||
| 
 | 
 | ||||||
|     microsec _visibility_offset; |     microsec _visibility_offset; | ||||||
| 
 | 
 | ||||||
| @ -41,8 +44,8 @@ private: | |||||||
| 
 | 
 | ||||||
|     void checkCurrentActiveNote(const microsec &music_offset); |     void checkCurrentActiveNote(const microsec &music_offset); | ||||||
|     void checkForNextActiveNote(const microsec &music_offset); |     void checkForNextActiveNote(const microsec &music_offset); | ||||||
|     void discardExpiredNotes(const std::unique_ptr<ClassicViewManager>& view_manager); |  | ||||||
|     bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const; |     bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const; | ||||||
|  |     bool nothingToDraw() const noexcept; | ||||||
| 
 | 
 | ||||||
|     /* Difference between top and active note is that
 |     /* Difference between top and active note is that
 | ||||||
|      * top note is the note handling input right now |      * top note is the note handling input right now | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| #include "classicviewmanager.h" | #include "spritecontainer.h" | ||||||
| #include "classicsprite.h" | #include "classicsprite.h" | ||||||
| #include "classicnote.h" | 
 | ||||||
| #include <SFML/Graphics/RectangleShape.hpp> | #include <SFML/Graphics/RectangleShape.hpp> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| 
 | 
 | ||||||
| static constexpr std::size_t RESERVED_SIZE = 20; | static constexpr std::size_t RESERVED_SIZE = 20; | ||||||
| 
 | 
 | ||||||
| ClassicViewManager::ClassicViewManager() | SpriteContainer::SpriteContainer() | ||||||
| { | { | ||||||
|     for (auto kind_of_action : {Action::PRESS_UP, Action::PRESS_DOWN, |     for (auto kind_of_action : {Action::PRESS_UP, Action::PRESS_DOWN, | ||||||
|                                 Action::PRESS_LEFT, Action::PRESS_RIGHT}) |                                 Action::PRESS_LEFT, Action::PRESS_RIGHT}) | ||||||
| @ -14,10 +14,12 @@ ClassicViewManager::ClassicViewManager() | |||||||
|         reallocatePoll(kind_of_action); |         reallocatePoll(kind_of_action); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     std::cout << "Sprite poll reallocated.\n"; | ||||||
|  | 
 | ||||||
|     _font.loadFromFile("VeraMono.ttf"); |     _font.loadFromFile("VeraMono.ttf"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicViewManager::reallocatePoll(Action kind_of_action) | void SpriteContainer::reallocatePoll(Action kind_of_action) | ||||||
| { | { | ||||||
|     SpritePoll &poll = _sprite_dispatcher[kind_of_action]; |     SpritePoll &poll = _sprite_dispatcher[kind_of_action]; | ||||||
|     for (std::size_t i = 0; i < RESERVED_SIZE; ++i) |     for (std::size_t i = 0; i < RESERVED_SIZE; ++i) | ||||||
| @ -26,7 +28,7 @@ void ClassicViewManager::reallocatePoll(Action kind_of_action) | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<ClassicSprite> ClassicViewManager::createSprite(Action kind_of_action) const | std::shared_ptr<ClassicSprite> SpriteContainer::createSprite(Action kind_of_action) const | ||||||
| { | { | ||||||
|     sf::RectangleShape sprite; |     sf::RectangleShape sprite; | ||||||
|     sprite.setSize({20.f, 20.f}); |     sprite.setSize({20.f, 20.f}); | ||||||
| @ -55,22 +57,22 @@ std::shared_ptr<ClassicSprite> ClassicViewManager::createSprite(Action kind_of_a | |||||||
|     return std::make_shared<ClassicSprite>(sprite, _font); |     return std::make_shared<ClassicSprite>(sprite, _font); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicViewManager::initNoteSprite(ClassicNote* note) | std::shared_ptr<ClassicSprite> SpriteContainer::getSprite(Action action) | ||||||
| { | { | ||||||
|     const auto action_type = note->action(); |     SpritePoll& poll = _sprite_dispatcher.at(action); | ||||||
|     SpritePoll& poll = _sprite_dispatcher.at(action_type); |  | ||||||
| 
 | 
 | ||||||
|     if (poll.empty()) |     if (poll.empty()) | ||||||
|         reallocatePoll(action_type); |         reallocatePoll(action); | ||||||
| 
 | 
 | ||||||
|     note->setSprite(poll.top()); |     std::shared_ptr<ClassicSprite> sprite = poll.top(); | ||||||
|     poll.pop(); |     poll.pop(); | ||||||
|     std::cout << "Taking a sprite from poll.\n"; |     std::cout << "Taking a sprite from poll.\n"; | ||||||
|  | 
 | ||||||
|  |     return sprite; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ClassicViewManager::resetNoteSprite(ClassicNote* note) | void SpriteContainer::resetSprite(const std::shared_ptr<ClassicSprite> &sprite, Action action) | ||||||
| { | { | ||||||
|     _sprite_dispatcher[note->action()].push(note->sprite()); |     _sprite_dispatcher[action].push(sprite); | ||||||
|     note->setSprite(nullptr); |  | ||||||
|     std::cout << "Returning a sprite to poll.\n"; |     std::cout << "Returning a sprite to poll.\n"; | ||||||
| } | } | ||||||
| @ -1,24 +1,25 @@ | |||||||
| #ifndef CLASSICDIVAVIEWMANAGER_H | #pragma once | ||||||
| #define CLASSICDIVAVIEWMANAGER_H |  | ||||||
| 
 | 
 | ||||||
| #include "timelineviewmanager.h" |  | ||||||
| #include "classicactions.h" | #include "classicactions.h" | ||||||
| 
 | 
 | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <stack> | #include <stack> | ||||||
| #include <map> | 
 | ||||||
| #include <SFML/Graphics/Font.hpp> | #include <SFML/Graphics/Font.hpp> | ||||||
| 
 | 
 | ||||||
| class ClassicSprite; | class ClassicSprite; | ||||||
| class ClassicNote; | class ClassicNote; | ||||||
| 
 | 
 | ||||||
| class ClassicViewManager : public TimelineViewManager | /* Move Sprite initialization into factory
 | ||||||
|  |  *          and make this class template   */ | ||||||
|  | 
 | ||||||
|  | class SpriteContainer | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     explicit ClassicViewManager(); |     explicit SpriteContainer(); | ||||||
| 
 | 
 | ||||||
|     void initNoteSprite(ClassicNote *note); |     std::shared_ptr<ClassicSprite> getSprite(Action action); | ||||||
|     void resetNoteSprite(ClassicNote *note); |     void resetSprite(const std::shared_ptr<ClassicSprite> &sprite, Action action); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void reallocatePoll(Action kind_of_action); |     void reallocatePoll(Action kind_of_action); | ||||||
| @ -28,5 +29,3 @@ private: | |||||||
|     std::map<Action, SpritePoll> _sprite_dispatcher; |     std::map<Action, SpritePoll> _sprite_dispatcher; | ||||||
|     sf::Font _font; |     sf::Font _font; | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| #endif // CLASSICDIVAVIEWMANAGER_H
 |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user