Compare commits

..

3 Commits

15 changed files with 98 additions and 107 deletions

View File

@ -23,7 +23,10 @@ class PrecisionEvaluator
_end_handling_offset = _offset + intervals.back(); _end_handling_offset = _offset + intervals.back();
} }
inline microsec offset() const noexcept { return _offset; } inline microsec offset() const noexcept
{
return _offset;
}
inline bool isActive(microsec music_play_offset) const noexcept inline bool isActive(microsec music_play_offset) const noexcept
{ {
@ -35,9 +38,6 @@ class PrecisionEvaluator
{ {
microsec shift_from_perfect = std::abs(odds - offset()); microsec shift_from_perfect = std::abs(odds - offset());
std::cout << "Shift " << ((odds > _offset) ? "late: " : "early: ")
<< shift_from_perfect << "\n";
std::size_t raw_grade; std::size_t raw_grade;
for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade) for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade)
{ {

View File

@ -15,9 +15,7 @@ template <class TNote,
class Timeline class Timeline
{ {
public: public:
explicit Timeline() : _current_offset(0) explicit Timeline() : _current_offset(0) {}
{
}
typedef typename std::set<TNote *>::const_iterator Iterator; typedef typename std::set<TNote *>::const_iterator Iterator;
@ -26,30 +24,30 @@ class Timeline
_current_offset = offset; _current_offset = offset;
expire(_top_note); expire(_top_note);
if (_timeline.empty()) if (!_timeline.empty())
return;
Iterator head_iterator = _timeline.begin();
while (!isExpired(head_iterator))
{ {
if ((*head_iterator)->getPerfectOffset() >= offset) Iterator head_iterator = _timeline.begin();
{
Iterator pre_head = head_iterator;
--pre_head;
_top_note = while (!isExpired(head_iterator))
!isExpired(pre_head) && (*pre_head)->isActive(offset) {
? pre_head if ((*head_iterator)->getPerfectOffset() >= offset)
: head_iterator; {
break; Iterator pre_head = head_iterator;
--pre_head;
_top_note =
!isExpired(pre_head) && (*pre_head)->isActive(offset)
? pre_head
: head_iterator;
break;
}
++head_iterator;
} }
++head_iterator; if (isExpired(_top_note))
_top_note = _timeline.begin();
} }
if (isExpired(_top_note))
_top_note = _timeline.begin();
} }
void setNotes(const std::set<TNote *, NotePtrComparator> &notes) void setNotes(const std::set<TNote *, NotePtrComparator> &notes)
@ -130,20 +128,11 @@ class Timeline
iterator = _timeline.end(); iterator = _timeline.end();
} }
inline Iterator getTopNote() const noexcept inline Iterator getTopNote() const noexcept { return _top_note; }
{
return _top_note;
}
inline Iterator begin() const noexcept inline Iterator begin() const noexcept { return _timeline.begin(); }
{
return _timeline.begin();
}
inline Iterator end() const noexcept inline Iterator end() const noexcept { return _timeline.end(); }
{
return _timeline.end();
}
private: private:
std::set<TNote *, NotePtrComparator> _timeline; std::set<TNote *, NotePtrComparator> _timeline;

View File

@ -35,7 +35,7 @@ class Log
void log(LogLevel level, const std::string &fmt, ...); void log(LogLevel level, const std::string &fmt, ...);
private: private:
inline std::string _getLabel(LogLevel level) inline std::string getLabel(LogLevel level)
{ {
switch (level) switch (level)
{ {

View File

@ -23,5 +23,5 @@ void Log::log(LogLevel level, const std::string &fmt, ...)
std::vsnprintf(&buf[0], len + 1, fmt.c_str(), args); std::vsnprintf(&buf[0], len + 1, fmt.c_str(), args);
va_end(args); va_end(args);
std::cout << this->_getLabel(level) << " " << &buf[0] << std::endl; std::cout << this->getLabel(level) << " " << &buf[0] << std::endl;
} }

View File

@ -51,8 +51,8 @@ void ApplicationSFML::run()
} }
} }
bool isOneFramePassed = time_since_last_update >= TIME_PER_FRAME; bool is_frame_passed = time_since_last_update >= TIME_PER_FRAME;
if (isOneFramePassed) if (is_frame_passed)
{ {
time_since_last_update -= TIME_PER_FRAME; time_since_last_update -= TIME_PER_FRAME;
update(time_since_last_update.asMicroseconds()); update(time_since_last_update.asMicroseconds());

View File

@ -36,8 +36,7 @@ classic::getEditor(const std::shared_ptr<kku::CoreFactory> &core_factory)
const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory); const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory);
const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>(); const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>();
const auto selection_manager = const auto selection_manager = std::make_shared<SelectionManager>();
std::make_shared<SelectionManager<ClassicNote>>();
std::vector<std::shared_ptr<ClassicGraphicsManager>> graphics_managers; std::vector<std::shared_ptr<ClassicGraphicsManager>> graphics_managers;
graphics_managers.emplace_back( graphics_managers.emplace_back(
std::make_shared<ClassicSceneGraphicsManager>(timeline, factory, std::make_shared<ClassicSceneGraphicsManager>(timeline, factory,

View File

@ -43,6 +43,7 @@ ClassicEditor::ClassicEditor(
element.position = kku::Point(x, 390.f); element.position = kku::Point(x, 390.f);
element.falling_curve_interpolation = {}; element.falling_curve_interpolation = {};
element.id = 0;
element.keys = {kku::SystemEvent::Key::Code::W, element.keys = {kku::SystemEvent::Key::Code::W,
kku::SystemEvent::Key::Code::Up}; kku::SystemEvent::Key::Code::Up};
@ -103,7 +104,6 @@ void ClassicEditor::input(kku::GameEvent &&input)
switch (input.event.type) switch (input.event.type)
{ {
default: default:
break; break;
@ -153,8 +153,6 @@ void ClassicEditor::input(kku::GameEvent &&input)
if (!_context->getSelectionManager()->isMultiselectionEnabled()) if (!_context->getSelectionManager()->isMultiselectionEnabled())
_context->getSelectionManager()->discard(); _context->getSelectionManager()->discard();
//_graphics_manager->input(std::move(input));
break; break;
} }
} }

View File

@ -5,7 +5,7 @@
#include "graphics/classicnotegraphics.h" #include "graphics/classicnotegraphics.h"
EditorContext::EditorContext( EditorContext::EditorContext(
const std::shared_ptr<SelectionManager<ClassicNote>> &selection_manager, const std::shared_ptr<SelectionManager> &selection_manager,
std::vector<std::shared_ptr<ClassicGraphicsManager>> &&graphics_managers) std::vector<std::shared_ptr<ClassicGraphicsManager>> &&graphics_managers)
: _selection_manager(selection_manager), : _selection_manager(selection_manager),
_graphics_managers(std::move(graphics_managers)) _graphics_managers(std::move(graphics_managers))
@ -14,41 +14,27 @@ EditorContext::EditorContext(
void EditorContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const void EditorContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const
{ {
(void)note;
switch (input.event.type) switch (input.event.type)
{ {
default: default:
break; break;
/*case kku::SystemEvent::Type::MousePress: case kku::SystemEvent::Type::MousePress:
{
const auto clicked_position =
std::get<kku::SystemEvent::Mouse>(input.event.data).position;
for (auto &element : note->getElements())
{ {
bool selection_changed = false; if (element.sprite->getRectangle()->contains(clicked_position))
std::size_t amount_selected = 0;
const auto position =
std::get<kku::SystemEvent::Mouse>(input.event.data).position; for (auto&
element : note->getElements())
{ {
if (element.sprite->getRectangle()->contains(position)) if (_selection_manager->isSelected(note->getId(), element.id))
{ _selection_manager->remove(note->getId(), element.id);
element.selected = !element.selected;
selection_changed = true;
if (element.selected)
++amount_selected;
}
}
if (selection_changed)
{
if (amount_selected > 0)
_selection_manager->fetch(note);
else else
_selection_manager->remove(note); _selection_manager->fetch(note->getId(), element.id);
} }
}
break; break;
}*/ }
} }
} }
@ -95,8 +81,7 @@ void EditorContext::update(ClassicArrowNote *note,
element.animations[note->getState()]->update(music_offset); element.animations[note->getState()]->update(music_offset);
} }
std::shared_ptr<SelectionManager<ClassicNote>> std::shared_ptr<SelectionManager> EditorContext::getSelectionManager() const
EditorContext::getSelectionManager() const
{ {
return _selection_manager; return _selection_manager;
} }

View File

@ -11,7 +11,7 @@ class ClassicGraphicsManager;
class EditorContext : public Context class EditorContext : public Context
{ {
public: public:
explicit EditorContext(const std::shared_ptr<SelectionManager<ClassicNote>>& selection_manager, explicit EditorContext(const std::shared_ptr<SelectionManager>& selection_manager,
std::vector<std::shared_ptr<ClassicGraphicsManager>>&& graphics_managers); std::vector<std::shared_ptr<ClassicGraphicsManager>>&& graphics_managers);
virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const override; virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const override;
@ -21,9 +21,9 @@ public:
void updateGraphics(const kku::microsec& music_offset); void updateGraphics(const kku::microsec& music_offset);
void displayGraphics() const; void displayGraphics() const;
std::shared_ptr<SelectionManager<ClassicNote>> getSelectionManager() const; std::shared_ptr<SelectionManager> getSelectionManager() const;
private: private:
const std::shared_ptr<SelectionManager<ClassicNote>> _selection_manager; const std::shared_ptr<SelectionManager> _selection_manager;
const std::vector<std::shared_ptr<ClassicGraphicsManager>> _graphics_managers; const std::vector<std::shared_ptr<ClassicGraphicsManager>> _graphics_managers;
}; };

View File

@ -1,51 +1,54 @@
#pragma once #pragma once
#include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
template <class T>
class SelectionManager class SelectionManager
{ {
public: public:
SelectionManager() : explicit SelectionManager() :
_multiselection_enabled(false) _multiselection_enabled(false)
{} {}
void discard() void discard()
{ {
_selected_things.clear(); _selected_ids.clear();
} }
void fetch(T * const thing) void fetch(int note_id, int element_id)
{ {
bool already_there = std::any_of(_selected_things.begin(), _selected_things.end(), if (!isSelected(note_id, element_id))
[&thing](const auto& selected_thing) _selected_ids[note_id].emplace_back(element_id);
{
return thing == selected_thing;
});
if (!already_there)
_selected_things.emplace_back(thing);
} }
void remove(T * const thing) void remove(int note_id, int element_id)
{ {
for (std::size_t i = 0; i < _selected_things.size(); ++i) if (_selected_ids.count(note_id) == 0)
return;
auto& elements_ids = _selected_ids[note_id];
for (std::size_t i = 0; i < elements_ids.size(); ++i)
{ {
if (thing == _selected_things.at(i)) if (element_id == elements_ids.at(i))
{ {
_selected_things[i] = std::move(_selected_things.back()); elements_ids[i] = std::move(elements_ids.back());
_selected_things.pop_back(); elements_ids.pop_back();
break; break;
} }
} }
} }
bool isSelected(const T * const thing) const bool isSelected(int note_id, int element_id) const
{ {
for (const auto& selected_thing : thing) if (_selected_ids.count(note_id) == 0)
if (thing == selected_thing) return false;
const std::vector<int>& selected_elements = _selected_ids.at(note_id);
for (const auto& selected_element : selected_elements)
if (selected_element == element_id)
return true; return true;
return false; return false;
@ -61,13 +64,7 @@ public:
return _multiselection_enabled; return _multiselection_enabled;
} }
void apply(const std::function<void(T*)>& function)
{
for (auto& thing : _selected_things)
function(thing);
}
private: private:
std::vector<T*> _selected_things; std::map<int, std::vector<int>> _selected_ids;
bool _multiselection_enabled; bool _multiselection_enabled;
}; };

View File

@ -10,10 +10,12 @@
#include <array> #include <array>
class ClassicNoteGraphics; class ClassicNoteGraphics;
class ClassicSelectionGraphics;
class ClassicAnimationScenario; class ClassicAnimationScenario;
struct ArrowElement struct ArrowElement
{ {
std::shared_ptr<ClassicSelectionGraphics> selection;
std::shared_ptr<ClassicNoteGraphics> sprite; std::shared_ptr<ClassicNoteGraphics> sprite;
std::array<std::shared_ptr<ClassicAnimationScenario>, 5> animations; std::array<std::shared_ptr<ClassicAnimationScenario>, 5> animations;
@ -24,6 +26,7 @@ struct ArrowElement
std::array<kku::SystemEvent::Key::Code, 2> keys; std::array<kku::SystemEvent::Key::Code, 2> keys;
Type type = Type::NONE; Type type = Type::NONE;
bool pressed = false; bool pressed = false;
int id = 0;
// Each note may consist of several buttons. // Each note may consist of several buttons.
// For example, ↑ → or ↓ → ← // For example, ↑ → or ↓ → ←

View File

@ -7,6 +7,7 @@
#include <vector> #include <vector>
class ClassicArrowNote; class ClassicArrowNote;
class SelectionManager;
class ArrowElement; class ArrowElement;
// class ClassicSliderNote; // class ClassicSliderNote;
@ -22,11 +23,14 @@ public:
virtual void display() const = 0; virtual void display() const = 0;
virtual void update(const kku::microsec& offset) = 0; virtual void update(const kku::microsec& offset) = 0;
virtual void switchSelection(ArrowElement* element) = 0;
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) = 0; virtual void update(const kku::microsec& offset, ClassicArrowNote* note) = 0;
// virtual void update(const kku::microsec& offset, ClassicSliderNote* note) = 0; // virtual void update(const kku::microsec& offset, ClassicSliderNote* note) = 0;
virtual void draw(const ClassicArrowNote * const note) const = 0; virtual void draw(const ClassicArrowNote * const note) const = 0;
// virtual void draw(ClassicSliderNote* note) const = 0; // virtual void draw(ClassicSliderNote* note) const = 0;
virtual void draw(const std::shared_ptr<SelectionManager>& selection_manager) const = 0;
protected: protected:
kku::microsec _visibility_offset; kku::microsec _visibility_offset;

View File

@ -87,6 +87,17 @@ void ClassicSceneGraphicsManager::draw(const ClassicArrowNote *const note) const
} }
} }
void ClassicSceneGraphicsManager::switchSelection(ArrowElement *element)
{
if (element->selection)
element->selection->reset();
else
{
element->selection = _factory->createSelection();
element->selection->adjustTo(element->sprite);
}
}
void ClassicSceneGraphicsManager::setGraphics( void ClassicSceneGraphicsManager::setGraphics(
std::vector<ArrowElement> &elements, kku::TimeRange &&range) std::vector<ArrowElement> &elements, kku::TimeRange &&range)
{ {

View File

@ -25,10 +25,12 @@ public:
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override; virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
virtual void draw(const ClassicArrowNote * const note) const override; virtual void draw(const ClassicArrowNote * const note) const override;
virtual void switchSelection(ArrowElement* element) override;
virtual void draw(const std::shared_ptr<SelectionManager>& selection_manager) const override;
void setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range); void setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range);
void removeGraphics(std::vector<ArrowElement>& elements); void removeGraphics(std::vector<ArrowElement>& elements);
protected: protected:
kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container; kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container;
const std::shared_ptr<const ClassicGraphicsFactory> _factory; const std::shared_ptr<const ClassicGraphicsFactory> _factory;

View File

@ -25,6 +25,9 @@ public:
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override; virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
virtual void draw(const ClassicArrowNote * const note) const override; virtual void draw(const ClassicArrowNote * const note) const override;
virtual void switchSelection(ArrowElement* element) override;
virtual void draw(const std::shared_ptr<SelectionManager>& selection_manager) const override;
protected: protected:
kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container; kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container;
const std::shared_ptr<const ClassicGraphicsFactory> _factory; const std::shared_ptr<const ClassicGraphicsFactory> _factory;