diff --git a/core/shared/core/note.h b/core/shared/core/note.h index 43e4552..c8582bd 100644 --- a/core/shared/core/note.h +++ b/core/shared/core/note.h @@ -11,7 +11,6 @@ public: virtual bool isActive(const microsec& offset) const = 0; virtual void update(const microsec& music_offset) = 0; - virtual void draw() const = 0; virtual void putToGame(const microsec& offset) = 0; virtual bool isInGame() const = 0; diff --git a/core/shared/core/timeline.h b/core/shared/core/timeline.h index 0372b5a..2f91009 100644 --- a/core/shared/core/timeline.h +++ b/core/shared/core/timeline.h @@ -128,6 +128,11 @@ public: iterator = _timeline.end(); } + inline Iterator getTopNote() const noexcept + { + return _top_note; + } + private: std::set _timeline; microsec _current_offset; diff --git a/modes/classicmode/classicfactory.cpp b/modes/classicmode/classicfactory.cpp index b4d0f8c..3d07926 100644 --- a/modes/classicmode/classicfactory.cpp +++ b/modes/classicmode/classicfactory.cpp @@ -1,18 +1,18 @@ #include "shared/classicmode/classicfactory.h" #include "game/classicgame.h" -#include "graphics/classicgraphicsmanager.h" +#include "game/classicgraphicsmanager.h" #include "tools/music.h" #include "editor/classiceditor.h" #include -std::unique_ptr classic::initGame(sf::RenderWindow& game_window) +std::unique_ptr classic::initGame() { - return std::make_unique(std::make_unique(game_window)); + return std::make_unique(); } -std::unique_ptr classic::initEditor(sf::RenderWindow& game_window) +std::unique_ptr classic::initEditor() { - return std::make_unique(std::make_unique(game_window)); + return std::make_unique(); } diff --git a/modes/classicmode/editor/classiceditor.cpp b/modes/classicmode/editor/classiceditor.cpp index f027ac7..2afff43 100644 --- a/modes/classicmode/editor/classiceditor.cpp +++ b/modes/classicmode/editor/classiceditor.cpp @@ -1,13 +1,10 @@ #include "classiceditor.h" -ClassicEditor::ClassicEditor(std::shared_ptr&& manager) : - _graphics_manager(manager), +ClassicEditor::ClassicEditor() : _selected_type(Type::UP), _current_time(0), _scroll_step(500000) { - _context.graphics_manager = _graphics_manager; - std::set set = {}; // VISIBILITY 1648648 diff --git a/modes/classicmode/editor/classiceditor.h b/modes/classicmode/editor/classiceditor.h index c2b5daa..c73b483 100644 --- a/modes/classicmode/editor/classiceditor.h +++ b/modes/classicmode/editor/classiceditor.h @@ -12,7 +12,7 @@ class ClassicGraphicsManager; class ClassicEditor : public Editor { public: - explicit ClassicEditor(std::shared_ptr&& manager); + explicit ClassicEditor(); virtual void input(PlayerInput&& inputdata) override; virtual void update(UpdateData&& updatedata) override; diff --git a/modes/classicmode/editor/mockclassicnote.cpp b/modes/classicmode/editor/mockclassicnote.cpp index 6bdd878..4bab56c 100644 --- a/modes/classicmode/editor/mockclassicnote.cpp +++ b/modes/classicmode/editor/mockclassicnote.cpp @@ -1,5 +1,5 @@ #include "mockclassicnote.h" -#include "graphics/classicgraphicsmanager.h" +#include "game/classicgraphicsmanager.h" // Replace with interface by dependency injection #include "graphics/classicflyinganimationscenario.h" @@ -21,12 +21,6 @@ MockClassicNote::MockClassicNote(MockArrowNoteInitializer&& init) : { _elements[i].coordinates = init.elements[i].coordinates; _elements[i].type = init.elements[i].type; - - // Animations will be injected into note. - _elements[i].animations[State::NONE] = nullptr; - _elements[i].animations[State::FLYING] = std::make_shared(); - _elements[i].animations[State::DYING] = std::make_shared(); - _elements[i].animations[State::DEAD] = nullptr; } } @@ -50,14 +44,6 @@ bool MockClassicNote::shouldRemove() const void MockClassicNote::putToGame(const microsec &music_offset) { _state = State::FLYING; (void)music_offset; - - for (auto& element : _elements) - { - element.sprite = _context->graphics_manager->getSprite(element.type); - element.sprite->setCoordinates(element.coordinates); - element.sprite->setTrailCoordinates(Coordinates(0.f, 9.f)); - element.animations[_state]->launch(element.sprite, offset() - 1648648, offset()); - } } void MockClassicNote::update(const microsec &music_offset) @@ -78,13 +64,3 @@ void MockClassicNote::update(const microsec &music_offset) element.animations[_state]->update(music_offset); } -void MockClassicNote::draw() const -{ - for (std::size_t i = 0; i < _elements.size(); ++i) - { - if (i >= 1) - _context->graphics_manager->drawLine(_elements[i-1].sprite->trailCoordinates(), _elements[i].sprite->trailCoordinates()); - - _context->graphics_manager->draw(_elements[i].sprite); - } -} diff --git a/modes/classicmode/editor/mockclassicnote.h b/modes/classicmode/editor/mockclassicnote.h index 2e935b0..79d6716 100644 --- a/modes/classicmode/editor/mockclassicnote.h +++ b/modes/classicmode/editor/mockclassicnote.h @@ -31,7 +31,6 @@ public: virtual void putToGame(const microsec &music_offset) override final; virtual void update(const microsec &music_offset) override final; - virtual void draw() const override final; private: struct MockElement diff --git a/modes/classicmode/game/classicarrownote.cpp b/modes/classicmode/game/classicarrownote.cpp index fe26576..71aaad7 100644 --- a/modes/classicmode/game/classicarrownote.cpp +++ b/modes/classicmode/game/classicarrownote.cpp @@ -1,5 +1,5 @@ #include "classicarrownote.h" -#include "graphics/classicgraphicsmanager.h" +#include "game/classicgraphicsmanager.h" #include "holdmanager.h" // Replace with interface by dependency injection @@ -18,26 +18,12 @@ ClassicArrowNote::ClassicArrowNote(ArrowNoteInitializer&& init) : _elements[i].keys = init.elements[i].keys; _elements[i].coordinates = init.elements[i].element.coordinates; _elements[i].type = init.elements[i].element.type; - - // Animations will be injected into note. - _elements[i].animations[State::NONE] = nullptr; - _elements[i].animations[State::FLYING] = std::make_shared(); - _elements[i].animations[State::DYING] = std::make_shared(); - _elements[i].animations[State::DEAD] = nullptr; } } void ClassicArrowNote::putToGame(const microsec &music_offset) { - _state = State::FLYING; - - for (auto& element : _elements) - { - element.sprite = _context->graphics_manager->getSprite(element.type); - element.sprite->setCoordinates(element.coordinates); - element.sprite->setTrailCoordinates(Coordinates( 0.f, 9.f )); - element.animations[_state]->launch(element.sprite, music_offset, offset()); - } + _state = State::FLYING; (void)music_offset; } void ClassicArrowNote::input(PlayerInput&& inputdata) @@ -80,17 +66,6 @@ void ClassicArrowNote::input(PlayerInput&& inputdata) std::cout << "User input: " << static_cast(grade) << "\n"; } -void ClassicArrowNote::draw() const -{ - for (std::size_t i = 0; i < _elements.size(); ++i) - { - if (i >= 1) - _context->graphics_manager->drawLine(_elements[i-1].sprite->trailCoordinates(), _elements[i].sprite->trailCoordinates()); - - _context->graphics_manager->draw(_elements[i].sprite); - } -} - void ClassicArrowNote::update(const microsec& music_offset) { switch (_state) diff --git a/modes/classicmode/game/classicarrownote.h b/modes/classicmode/game/classicarrownote.h index 066e54d..991c4c0 100644 --- a/modes/classicmode/game/classicarrownote.h +++ b/modes/classicmode/game/classicarrownote.h @@ -12,7 +12,6 @@ public: virtual void putToGame(const microsec& music_offset) override; virtual void update(const microsec &music_offset) override; virtual void input(PlayerInput&& inputdata) override; - virtual void draw() const override; bool allElementsPressed() const; bool isPressedAs(sf::Keyboard::Key key) const; diff --git a/modes/classicmode/game/classicgame.cpp b/modes/classicmode/game/classicgame.cpp index 56fdb26..ece48f6 100644 --- a/modes/classicmode/game/classicgame.cpp +++ b/modes/classicmode/game/classicgame.cpp @@ -1,12 +1,11 @@ #include "classicgame.h" #include "classicnote.h" #include "classicmapcreator.h" -#include "graphics/classicgraphicsmanager.h" +#include "game/classicgraphicsmanager.h" #include "holdmanager.h" -ClassicGame::ClassicGame(std::shared_ptr&& manager) : - _graphics_manager(std::move(manager)), - _hold_manager(std::make_unique(_graphics_manager)) +ClassicGame::ClassicGame() : + _hold_manager(std::make_unique()) { _slap_buffer.loadFromFile("Tick.ogg"); _slap.setBuffer(_slap_buffer); @@ -57,7 +56,6 @@ ClassicGame::~ClassicGame() void ClassicGame::run() { _context.hold_manager = _hold_manager; - _context.graphics_manager = _graphics_manager; auto beatmap = classic::createBeatmap("aa", _context); _timeline.setNotes(beatmap.notes); diff --git a/modes/classicmode/game/classicgame.h b/modes/classicmode/game/classicgame.h index 881d3dc..af8e39f 100644 --- a/modes/classicmode/game/classicgame.h +++ b/modes/classicmode/game/classicgame.h @@ -20,7 +20,7 @@ class HoldManager; class ClassicGame final : public Game { public: - explicit ClassicGame(std::shared_ptr&& manager); + explicit ClassicGame(); virtual ~ClassicGame() override; virtual void run() override; @@ -34,7 +34,7 @@ private: std::map _buttons_to_pressed_actions; std::map _buttons_to_released_actions; - std::shared_ptr _graphics_manager; + std::unique_ptr _graphics_manager; std::shared_ptr _hold_manager; Timeline _timeline; diff --git a/modes/classicmode/game/classicgraphicsmanager.cpp b/modes/classicmode/game/classicgraphicsmanager.cpp new file mode 100644 index 0000000..5d7f462 --- /dev/null +++ b/modes/classicmode/game/classicgraphicsmanager.cpp @@ -0,0 +1,60 @@ +#include "classicgraphicsmanager.h" +#include "graphics/classicsprite.h" + +ClassicGraphicsManager::ClassicGraphicsManager(Timeline &timeline, const microsec& visibility_offset) : + _sprite_container({Type::UP, Type::DOWN, + Type::LEFT, Type::RIGHT}, + std::make_unique()), + _timeline(&timeline), + _visibility_offset(visibility_offset) +{ + _timeline->expire(_first); + _timeline->expire(_last); +} + +void ClassicGraphicsManager::draw(sf::RenderTarget& target, sf::RenderStates states) const +{ + if (nothingToDraw()) + return; + + std::for_each(_first, _last, + [&target, &states](const auto& note) + { + target.draw(*note->sprite(), states); + }); +} + +std::shared_ptr ClassicGraphicsManager::getSprite(Type type) +{ + return _sprite_container.getSprite(type); +} + +void ClassicGraphicsManager::update(const microsec &offset) +{ + Iterator note_iterator = _timeline->getTopNote(); + while (!_timeline->isExpired(note_iterator) && isVisiblyClose(note_iterator, offset)) + { + if (nothingToDraw()) + _first = note_iterator; + + auto note = *note_iterator; + + if (!note->isInGame()) + note->putToGame(offset); + + ++note_iterator; + } + + _last = note_iterator; +} + +bool ClassicGraphicsManager::nothingToDraw() const noexcept +{ + return _timeline->isExpired(_first) + || _timeline->isExpired(_last); +} + +bool ClassicGraphicsManager::isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept +{ + return ((iterator)->offset() - _visibility_offset) <= music_offset; +} diff --git a/modes/classicmode/game/classicgraphicsmanager.h b/modes/classicmode/game/classicgraphicsmanager.h new file mode 100644 index 0000000..1ae96d6 --- /dev/null +++ b/modes/classicmode/game/classicgraphicsmanager.h @@ -0,0 +1,35 @@ +#pragma once + +#include "spritecontainer.h" +#include "classicmode/classicactions.h" +#include "graphics/classicspritefactory.h" +#include "classicnote.h" +#include "core/timeline.h" + +#include + +class ClassicSprite; + +class ClassicGraphicsManager : public sf::Drawable +{ +public: + explicit ClassicGraphicsManager(Timeline& timeline, const microsec& visibility_offset); + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; + + std::shared_ptr getSprite(Type type); + void update(const microsec& offset); + +private: + using Iterator = Timeline::Iterator; + + Iterator _first; + Iterator _last; + + SpriteContainer _sprite_container; + Timeline * const _timeline; + + microsec _visibility_offset; + + inline bool nothingToDraw() const noexcept; + inline bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept; +}; diff --git a/modes/classicmode/game/classicnote.h b/modes/classicmode/game/classicnote.h index 9b80ed7..07e6f1d 100644 --- a/modes/classicmode/game/classicnote.h +++ b/modes/classicmode/game/classicnote.h @@ -37,7 +37,6 @@ public: virtual void putToGame(const microsec &music_offset) override = 0; virtual void update(const microsec &music_offset) override = 0; - virtual void draw() const override = 0; virtual void input(PlayerInput&& inputdata) = 0; diff --git a/modes/classicmode/game/holdmanager.cpp b/modes/classicmode/game/holdmanager.cpp index 161a12e..aeb204d 100644 --- a/modes/classicmode/game/holdmanager.cpp +++ b/modes/classicmode/game/holdmanager.cpp @@ -3,10 +3,6 @@ #include -HoldManager::HoldManager(const std::shared_ptr& graphics_manager) : - _graphics_manager(graphics_manager) -{} - void HoldManager::emplace(ClassicArrowNote* note) { _notes_on_hold.emplace_back(note); diff --git a/modes/classicmode/game/holdmanager.h b/modes/classicmode/game/holdmanager.h index 577ded8..5527709 100644 --- a/modes/classicmode/game/holdmanager.h +++ b/modes/classicmode/game/holdmanager.h @@ -10,7 +10,6 @@ class ClassicGraphicsManager; class HoldManager { public: - explicit HoldManager(const std::shared_ptr& graphics_manager); void emplace(ClassicArrowNote* note); void checkRelease(sf::Keyboard::Key released_key); diff --git a/modes/classicmode/graphics/classicgraphicsmanager.cpp b/modes/classicmode/graphics/classicgraphicsmanager.cpp deleted file mode 100644 index 7b21388..0000000 --- a/modes/classicmode/graphics/classicgraphicsmanager.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "classicgraphicsmanager.h" -#include "classicsprite.h" - -ClassicGraphicsManager::ClassicGraphicsManager(sf::RenderTarget& target) : - _sprite_container({Type::UP, Type::DOWN, - Type::LEFT, Type::RIGHT}, - std::make_unique()), - _render_target(target) -{} - -std::shared_ptr ClassicGraphicsManager::getSprite(Type type) -{ - return _sprite_container.getSprite(type); -} - -void ClassicGraphicsManager::draw(const std::shared_ptr& sprite) -{ - _render_target.draw(*sprite); -} - -void ClassicGraphicsManager::drawLine(const Coordinates &p1, const Coordinates &p2) -{ - sf::VertexArray line(sf::LinesStrip, 2); - line[0].color = sf::Color::Yellow; - line[0].position = {p1.x + 10, p1.y}; - line[1].color = sf::Color::Blue; - line[1].position = {p2.x + 10, p2.y}; - _render_target.draw(line); -} diff --git a/modes/classicmode/graphics/classicgraphicsmanager.h b/modes/classicmode/graphics/classicgraphicsmanager.h deleted file mode 100644 index 26b626a..0000000 --- a/modes/classicmode/graphics/classicgraphicsmanager.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "spritecontainer.h" -#include "classicmode/classicactions.h" -#include "classicspritefactory.h" - -#include - -class ClassicSprite; -class ClassicNote; - -class ClassicGraphicsManager -{ -public: - explicit ClassicGraphicsManager(sf::RenderTarget& target); - - std::shared_ptr getSprite(Type type); - void draw(const std::shared_ptr &sprite); - void drawLine(const Coordinates &p1, const Coordinates &p2); - -private: - SpriteContainer _sprite_container; - sf::RenderTarget& _render_target; -}; diff --git a/modes/classicmode/include/classicmode/context.h b/modes/classicmode/include/classicmode/context.h index 8d977a9..9cf2dea 100644 --- a/modes/classicmode/include/classicmode/context.h +++ b/modes/classicmode/include/classicmode/context.h @@ -2,11 +2,9 @@ #include -class ClassicGraphicsManager; class HoldManager; struct Context { - std::shared_ptr graphics_manager; std::shared_ptr hold_manager; }; diff --git a/modes/classicmode/shared/classicmode/classicfactory.h b/modes/classicmode/shared/classicmode/classicfactory.h index 150250f..e2efef0 100644 --- a/modes/classicmode/shared/classicmode/classicfactory.h +++ b/modes/classicmode/shared/classicmode/classicfactory.h @@ -10,6 +10,6 @@ namespace sf { class RenderWindow; } namespace classic { - std::unique_ptr initGame(sf::RenderWindow& game_window); - std::unique_ptr initEditor(sf::RenderWindow& game_window); + std::unique_ptr initGame(); + std::unique_ptr initEditor(); }