Add abstraction for timeline views

This commit is contained in:
NaiJi ✨ 2021-04-15 18:03:35 +03:00
parent dd3a175b55
commit ecd0e67ed1
12 changed files with 166 additions and 26 deletions

View File

@ -4,22 +4,24 @@ project(project-kyoku LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(SOURCES application.cpp note.cpp main.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(HEADER_FILES application.h note.h) set(SOURCES application.cpp note.cpp debughelper.cpp main.cpp timeline.cpp timelineviews/timelineviewmanager.cpp timelineviews/classicviewmanager.cpp)
set(HEADER_FILES application.h note.h debughelper.h timeline.h timelineviews/timelineviewmanager.h timelineviews/classicviewmanager.h)
# STATIC # # STATIC #
# You need to build SFML from sources with cmake # You need to build SFML from sources with cmake
#set(SFML_LIB_DIR set(SFML_LIB_DIR
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-graphics.so.2.5 ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-graphics.so.2.5
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-system.so.2.5 ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-system.so.2.5
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-window.so.2.5) ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-window.so.2.5
#set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include) ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-audio.so.2.5)
#include_directories(${SFML_INCL_DIR}) set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include)
#add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} ) include_directories(${SFML_INCL_DIR})
#target_link_libraries(project-kyoku ${SFML_LIB_DIR}) add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
target_link_libraries(project-kyoku ${SFML_LIB_DIR})
# DYNAMIC # # DYNAMIC #
# You only need to install SFML from your package manager # You only need to install SFML from your package manager
find_package(SFML REQUIRED graphics window system) #find_package(SFML REQUIRED graphics window system)
add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} ) #add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network) #target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network)

View File

@ -30,12 +30,6 @@ void Application::run()
startGameLoop(); startGameLoop();
} }
static bool isOneFramePassed(const sf::Time& time_since_last_update)
{
return time_since_last_update >= TIME_PER_FRAME;
}
void Application::startGameLoop() void Application::startGameLoop()
{ {
sf::Clock timer; sf::Clock timer;
@ -46,7 +40,9 @@ void Application::startGameLoop()
input(); input();
time_since_last_update += timer.restart(); time_since_last_update += timer.restart();
if (isOneFramePassed(time_since_last_update))
bool isOneFramePassed = time_since_last_update >= TIME_PER_FRAME;
if (isOneFramePassed)
{ {
time_since_last_update -= TIME_PER_FRAME; time_since_last_update -= TIME_PER_FRAME;
update(); update();
@ -148,11 +144,11 @@ void Application::onTap(const Note::Arrow &arrow)
return; return;
const auto music_offset = _music.getPlayingOffset().asMicroseconds(); const auto music_offset = _music.getPlayingOffset().asMicroseconds();
const auto note = _timeline.fetchActiveNote(music_offset); auto note = _timeline.fetchActiveNote(music_offset);
if (note) if (note)
{ {
const auto tap_result = note->onTap(arrow, music_offset); auto tap_result = note->onTap(arrow, music_offset);
makeGradeString(tap_result.rating, _grade); makeGradeString(tap_result.rating, _grade);
_grade.setFillColor(sf::Color(255, 255, 255, 255)); _grade.setFillColor(sf::Color(255, 255, 255, 255));
} }

View File

@ -24,8 +24,11 @@ microsec Note::offset() const noexcept
return _offset; return _offset;
} }
NoteGrade Note::onTap(Arrow arrow_type, microsec tap_time_stamp) const NoteGrade Note::onTap(Arrow arrow_type, microsec tap_time_stamp)
{ {
_sprite->setAttachment(false);
_sprite = nullptr;
if (arrow_type != _type) if (arrow_type != _type)
return {0, NoteGrade::Rating::WRONG}; return {0, NoteGrade::Rating::WRONG};
@ -56,4 +59,9 @@ void Note::resetPrecisionQualifier(microsec qualifier)
_precision_qualifier = qualifier; _precision_qualifier = qualifier;
} }
void Note::resetSprite(const std::shared_ptr<Sprite> &sprite) noexcept
{
_sprite = sprite;
}
microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second. microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second.

24
note.h
View File

@ -3,12 +3,30 @@
#include <SFML/System/Clock.hpp> #include <SFML/System/Clock.hpp>
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/RectangleShape.hpp> // TEMP MOCK
#include <memory>
//////////////////////////////// ////////////////////////////////
using microsec = sf::Int64; using microsec = sf::Int64;
using coordinates = sf::Vector2i; using coordinates = sf::Vector2i;
class Sprite // MOCK
{
public:
Sprite(sf::RectangleShape shape) : _shape(shape), _attached(false) {};
bool isAttached() const noexcept
{ return _attached; }
void setAttachment(bool attached) noexcept
{ _attached = attached; }
private:
sf::RectangleShape _shape;
bool _attached;
};
struct NoteGrade struct NoteGrade
{ {
int score; int score;
@ -44,9 +62,11 @@ public:
coordinates position() const noexcept; coordinates position() const noexcept;
microsec offset() const noexcept; microsec offset() const noexcept;
NoteGrade onTap(Arrow arrow_type, microsec tap_time_stamp) const; NoteGrade onTap(Arrow arrow_type, microsec tap_time_stamp);
bool isActive(microsec music_play_offset) const noexcept; bool isActive(microsec music_play_offset) const noexcept;
void resetSprite(const std::shared_ptr<Sprite>& sprite) noexcept;
static void resetPrecisionQualifier(microsec qualifier = 500000); static void resetPrecisionQualifier(microsec qualifier = 500000);
private: private:
@ -58,6 +78,8 @@ private:
static microsec _precision_qualifier; static microsec _precision_qualifier;
NoteGrade calculatePrecision(microsec odds) const; NoteGrade calculatePrecision(microsec odds) const;
std::shared_ptr<Sprite> _sprite;
}; };
#endif // NOTE_H #endif // NOTE_H

View File

@ -124,7 +124,7 @@ void Timeline::checkForNextActiveNote(const microsec &music_offset)
} }
} }
const Note* Timeline::fetchActiveNote(const microsec &music_offset) noexcept Note* Timeline::fetchActiveNote(const microsec &music_offset) noexcept
{ {
std::cout << "Clicked at: " << music_offset << '\n'; std::cout << "Clicked at: " << music_offset << '\n';
update(music_offset); update(music_offset);

View File

@ -19,7 +19,7 @@ public:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
void update(const microsec& music_offset); void update(const microsec& music_offset);
const Note* fetchActiveNote(const microsec &music_offset) noexcept; Note *fetchActiveNote(const microsec &music_offset) noexcept;
/* void init(); */ /* void init(); */
void clear(); void clear();

6
timelineviewmanager.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "timelineviewmanager.h"
TimelineViewManager::TimelineViewManager()
{
}

11
timelineviewmanager.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef TIMELINEVIEWMANAGER_H
#define TIMELINEVIEWMANAGER_H
class TimelineViewManager
{
public:
TimelineViewManager();
};
#endif // TIMELINEVIEWMANAGER_H

View File

@ -0,0 +1,28 @@
#include "classicviewmanager.h"
#include "../note.h"
#include <SFML/Graphics/RectangleShape.hpp>
static constexpr std::size_t RESERVED_SIZE = 20;
ClassicViewManager::ClassicViewManager()
{
for (std::size_t i = ARROW_UP; i < AMOUNT_OF_KINDS; ++i)
{
SpritePoll &poll = _sprite_dispatcher.at(i);
poll.reserve(RESERVED_SIZE);
for (auto &sprite : poll)
{
}
}
}
std::shared_ptr<Sprite> ClassicViewManager::createSprite(Button kind_of_button) const
{
auto sprite = std::make_shared<sf::RectangleShape>();
sprite->setSize({20.f, 20.f});
switch (kind_of_button)
{
return
}
}

View File

@ -0,0 +1,43 @@
#ifndef CLASSICDIVAVIEWMANAGER_H
#define CLASSICDIVAVIEWMANAGER_H
#include "timelineviewmanager.h"
#include <vector>
#include <memory>
class Sprite;
class ClassicViewManager : public TimelineViewManager
{
public:
explicit ClassicViewManager();
virtual ~ClassicViewManager() override;
virtual void update() override;
virtual void draw() override;
virtual void initNoteGraphics(Note *note) override;
private:
enum Button
{
ARROW_UP,
ARROW_DOWN,
ARROW_LEFT,
ARROW_RIGHT,
SHOULDER_RIGHT,
SHOULDER_LEFT,
AMOUNT_OF_KINDS
};
using SpritePoll = std::vector<std::shared_ptr<Sprite>>;
using SpriteDispatcher = std::array<SpritePoll, AMOUNT_OF_KINDS>;
SpriteDispatcher _sprite_dispatcher;
std::shared_ptr<Sprite> createSprite(Button kind_of_button) const;
};
#endif // CLASSICDIVAVIEWMANAGER_H

View File

@ -0,0 +1,7 @@
#include "timelineviewmanager.h"
TimelineViewManager::TimelineViewManager()
{}
TimelineViewManager::~TimelineViewManager()
{}

View File

@ -0,0 +1,17 @@
#ifndef TIMELINEVIEWMANAGER_H
#define TIMELINEVIEWMANAGER_H
class Note;
class TimelineViewManager
{
public:
explicit TimelineViewManager();
virtual ~TimelineViewManager();
virtual void update() = 0;
virtual void draw() = 0;
virtual void initNoteGraphics(Note *note) = 0;
};
#endif // TIMELINEVIEWMANAGER_H