Compare commits

..

1 Commits

Author SHA1 Message Date
NaiJi ✨ 1953d2339d Implement selection functions for graphics managers 2022-07-06 00:31:02 +03:00
96 changed files with 1139 additions and 1382 deletions

View File

@ -1,18 +0,0 @@
IndentWidth: 4
BreakBeforeBraces: Allman
AlignAfterOpenBracket: Align
AlignArrayOfStructures: Right
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: None
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: true

2
.envrc
View File

@ -1,2 +0,0 @@
use flake
watch_file shell.nix

View File

@ -1,32 +0,0 @@
# project-kyoku
I am just trying to create a rhythm game inspired by project-diva
### Initial setup
- Make sure you have a compiler supporting c++17 and cmake
- Make sure you have [sfml](https://www.sfml-dev.org/) installed, either static or not, just make sure to edit impl/ CMake file, you'll see it.
- Now clone it
```
git clone https://dev.udongein.xyz/NaiJi/project-kyoku
```
- Go to the project folder
```
cd project-kyoku/
```
- Now build it!
```
cmake CMakeLists.txt -B ./build
cd ./build
make
```
### Conventional commits
This project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
`<type>(optional scope): <description>`
Example: `feat(classic-mode): Implement something great`

View File

@ -1,40 +0,0 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1663491030,
"narHash": "sha256-MVsfBhE9US5DvLtBAaTRjwYdv1tLO8xjahM8qLXTgTo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "767542707d394ff15ac1981e903e005ba69528b5",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@ -1,14 +0,0 @@
{
description = "Project Kyoku";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShell = import ./shell.nix { inherit pkgs; };
}
);
}

View File

@ -27,22 +27,20 @@ struct Area
inline kku::Point position() const noexcept inline kku::Point position() const noexcept
{ {
return kku::Point{ return kku::Point{static_cast<float>(left),
static_cast<float>(left), static_cast<float>(top) };
static_cast<float>(top),
};
} }
inline void moveBy(const kku::Vector2<T> &vector) inline void moveBy(const kku::Vector2<T>& vector)
{ {
top += vector.second; top += vector.second;
left += vector.first; left += vector.first;
} }
inline bool contains(const kku::Point &point) const inline bool contains(const kku::Point& point) const
{ {
return point.x >= left; // debug it when on computer return point.x >= left ; // debug it when on computer
} }
}; };
} // namespace kku }

View File

@ -34,10 +34,10 @@ struct BPMSection
/// by timestamp of start /// by timestamp of start
struct BPMSectionComparator struct BPMSectionComparator
{ {
bool operator()(const BPMSection &lhs, const BPMSection &rhs) const noexcept bool operator()(const BPMSection& lhs, const BPMSection& rhs) const noexcept
{ {
return lhs.offset_start < rhs.offset_start; return lhs.offset_start < rhs.offset_start;
} }
}; };
} // namespace kku }

View File

@ -14,4 +14,4 @@ struct Color
unsigned char alpha = 0; unsigned char alpha = 0;
}; };
} // namespace kku }

View File

@ -2,13 +2,13 @@
#include <memory> #include <memory>
#include "core/line.h"
#include "core/music.h" #include "core/music.h"
#include "core/rectangle.h"
#include "core/resourceholder.h"
#include "core/sprite.h"
#include "core/text.h" #include "core/text.h"
#include "core/resourceholder.h"
#include "core/rectangle.h"
#include "core/vector.h" #include "core/vector.h"
#include "core/line.h"
#include "core/sprite.h"
namespace kku namespace kku
{ {
@ -19,15 +19,14 @@ namespace kku
/// multimedia elements and data /// multimedia elements and data
class CoreFactory class CoreFactory
{ {
public: public:
virtual ~CoreFactory() = default; virtual ~CoreFactory() = default;
virtual std::shared_ptr<kku::Music> getMusic() const = 0; virtual std::shared_ptr<kku::Music> getMusic() const = 0;
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const = 0; virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const = 0;
virtual std::shared_ptr<kku::Rectangle> getRectangle() const = 0; virtual std::shared_ptr<kku::Rectangle> getRectangle() const = 0;
virtual std::shared_ptr<kku::Line> getLine() const = 0; virtual std::shared_ptr<kku::Line> getLine() const = 0;
virtual std::shared_ptr<kku::Sprite> virtual std::shared_ptr<kku::Sprite> getSprite(kku::GUISprite::Id id) const = 0;
getSprite(kku::GUISprite::Id id) const = 0;
virtual kku::Vector2<std::size_t> getRenderSize() const = 0; virtual kku::Vector2<std::size_t> getRenderSize() const = 0;
}; };
} // namespace kku }

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#include <algorithm>
#include <set> #include <set>
#include <algorithm>
#include "core/bpmsection.h"
#include "core/gameevent.h" #include "core/gameevent.h"
#include "core/updatedata.h" #include "core/updatedata.h"
#include "core/bpmsection.h"
namespace kku namespace kku
{ {
@ -16,42 +16,41 @@ namespace kku
/// logic for Editor game mode /// logic for Editor game mode
class Editor class Editor
{ {
public: public:
virtual ~Editor() = default; virtual ~Editor() = default;
virtual void input(GameEvent &&input) = 0; virtual void input(GameEvent&& input) = 0;
virtual void update(UpdateData &&updatedata) = 0; virtual void update(UpdateData&& updatedata) = 0;
virtual void display() const = 0; virtual void display() const = 0;
virtual void recalculate(const microsec &timestamp) = 0; virtual void recalculate(const microsec& timestamp) = 0;
void setBPMSections( void setBPMSections(const std::set<BPMSection, BPMSectionComparator>& sections) noexcept
const std::set<BPMSection, BPMSectionComparator> &sections) noexcept
{ {
_bpm_sections = sections; _bpm_sections = sections;
} }
void setBPMSections( void setBPMSections(std::set<BPMSection, BPMSectionComparator>&& sections) noexcept
std::set<BPMSection, BPMSectionComparator> &&sections) noexcept
{ {
_bpm_sections = std::move(sections); _bpm_sections = std::move(sections);
} }
bool insertBPMSection(const BPMSection &section) bool insertBPMSection(const BPMSection& section)
{ {
return _bpm_sections.insert(section).second; return _bpm_sections.insert(section).second;
} }
bool insertBPMSection(BPMSection &&section) bool insertBPMSection(BPMSection&& section)
{ {
return _bpm_sections.insert(section).second; return _bpm_sections.insert(section).second;
} }
bool removeBPMSectionAt(const microsec &offset) bool removeBPMSectionAt(const microsec& offset)
{ {
auto section_it = auto section_it = std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(), [offset](const auto& section)
[offset](const auto &section) {
{ return section.offset_start < offset; }); return section.offset_start < offset;
});
if (section_it != _bpm_sections.rend()) if (section_it != _bpm_sections.rend())
{ {
@ -64,12 +63,13 @@ class Editor
return false; return false;
} }
BPMSection getBPMSectionAt(const microsec &offset) const BPMSection getBPMSectionAt(const microsec& offset) const
{ {
auto section_it = auto section_it = std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(), [offset](const auto& section)
[offset](const auto &section) {
{ return section.offset_start < offset; }); return section.offset_start < offset;
});
if (section_it != _bpm_sections.rend()) if (section_it != _bpm_sections.rend())
{ {
@ -80,10 +80,13 @@ class Editor
return BPMSection(); return BPMSection();
} }
void clearBPMSections() noexcept { _bpm_sections.clear(); } void clearBPMSections() noexcept
{
_bpm_sections.clear();
}
protected: protected:
std::set<BPMSection, BPMSectionComparator> _bpm_sections; std::set<BPMSection, BPMSectionComparator> _bpm_sections;
}; };
} // namespace kku }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "core/systemevent.h"
#include <string> #include <string>
namespace kku namespace kku
@ -7,7 +8,7 @@ namespace kku
class EditorCallback class EditorCallback
{ {
public: public:
virtual ~EditorCallback() = default; virtual ~EditorCallback() = default;
struct Metadata struct Metadata
@ -22,4 +23,4 @@ class EditorCallback
virtual Metadata getMetadata() const = 0; virtual Metadata getMetadata() const = 0;
}; };
} // namespace kku }

View File

@ -8,4 +8,4 @@ namespace kku
using lambda = std::function<void(void)>; using lambda = std::function<void(void)>;
using predicate = std::function<bool(void)>; using predicate = std::function<bool(void)>;
} // namespace kku }

View File

@ -12,13 +12,13 @@ namespace kku
/// logic for actual game mode /// logic for actual game mode
class Game class Game
{ {
public: public:
virtual ~Game() = default; virtual ~Game() = default;
virtual void run() = 0; virtual void run() = 0;
virtual void input(GameEvent &&inputdata) = 0; virtual void input(GameEvent&& inputdata) = 0;
virtual void update(UpdateData &&updatedata) = 0; virtual void update(UpdateData&& updatedata) = 0;
virtual void display() const = 0; virtual void display() const = 0;
}; };
} // namespace kku }

View File

@ -12,4 +12,4 @@ struct GameEvent
const SystemEvent event; const SystemEvent event;
}; };
} // namespace kku }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "core/color.h"
#include "core/point.h" #include "core/point.h"
#include "core/color.h"
namespace kku namespace kku
{ {
@ -11,11 +11,11 @@ namespace kku
/// Graphical 2D line /// Graphical 2D line
class Line class Line
{ {
public: public:
virtual ~Line() = default; virtual ~Line() = default;
virtual void setPosition(const kku::Point &p1, const kku::Point &p2) = 0; virtual void setPosition(const kku::Point& p1, const kku::Point& p2) = 0;
virtual void setColor(const kku::Color &c1, const kku::Color &c2) = 0; virtual void setColor(const kku::Color& c1, const kku::Color& c2) = 0;
virtual void display() = 0; virtual void display() = 0;
}; };
} // namespace kku }

View File

@ -12,10 +12,10 @@ namespace kku
/// Object for streaming music file /// Object for streaming music file
class Music class Music
{ {
public: public:
virtual ~Music() = default; virtual ~Music() = default;
virtual bool open(const std::string &filepath) = 0; virtual bool open(const std::string& filepath) = 0;
virtual void play() = 0; virtual void play() = 0;
virtual void pause() = 0; virtual void pause() = 0;
@ -25,11 +25,11 @@ class Music
virtual void setVolume(float volume) = 0; virtual void setVolume(float volume) = 0;
virtual void setOffset(const kku::microsec &offset) = 0; virtual void setOffset(const kku::microsec& offset) = 0;
virtual void moveOffset(const kku::microsec &delta) = 0; virtual void moveOffset(const kku::microsec& delta) = 0;
virtual kku::microsec fetchOffset() = 0; virtual kku::microsec fetchOffset() = 0;
virtual kku::microsec getDuration() const = 0; virtual kku::microsec getDuration() const = 0;
}; };
} // namespace kku }

View File

@ -1,52 +1,55 @@
#pragma once #pragma once
#include "core/gameevent.h"
#include "core/time.h" #include "core/time.h"
#include "core/gameevent.h"
namespace kku namespace kku
{ {
class Note class Note
{ {
public: public:
explicit Note(microsec perfect_offset) : _perfect_offset(perfect_offset) {} explicit Note(microsec perfect_offset) :
_perfect_offset(perfect_offset) {}
virtual ~Note() = default; virtual ~Note() = default;
virtual bool isActive(const microsec &offset) const = 0; virtual bool isActive(const microsec& offset) const = 0;
virtual void update(const microsec &music_offset) = 0; virtual void update(const microsec& music_offset) = 0;
virtual void input(kku::GameEvent &&input) = 0; virtual void input(kku::GameEvent&& input) = 0;
inline const microsec &getPerfectOffset() const noexcept inline const microsec& getPerfectOffset() const noexcept
{ {
return _perfect_offset; return _perfect_offset;
} }
bool operator<(const Note &note) const bool operator<(const Note& note) const
{ {
return _perfect_offset < note._perfect_offset; return _perfect_offset < note._perfect_offset;
} }
bool operator==(const Note &note) const bool operator==(const Note& note) const
{ {
return _perfect_offset == note._perfect_offset; return _perfect_offset == note._perfect_offset;
} }
bool operator>(const Note &note) const bool operator>(const Note& note) const
{ {
return _perfect_offset > note._perfect_offset; return _perfect_offset > note._perfect_offset;
} }
protected: protected:
microsec _perfect_offset; microsec _perfect_offset;
}; };
struct NotePtrComparator struct NotePtrComparator
{ {
bool operator()(const Note *lhs, const Note *rhs) const noexcept bool operator()(const Note* lhs, const Note* rhs) const noexcept
{ {
return lhs->getPerfectOffset() < rhs->getPerfectOffset(); return lhs->getPerfectOffset() < rhs->getPerfectOffset();
} }
}; };
} // namespace kku }

View File

@ -8,18 +8,24 @@ struct Point
float x; float x;
float y; float y;
constexpr inline explicit Point() noexcept : x(0.), y(0.) {} constexpr inline explicit Point() noexcept :
x(0.), y(0.)
{}
constexpr inline explicit Point(int x, int y) noexcept : x(x), y(y) {} constexpr inline explicit Point(int x, int y) noexcept :
x(x), y(y)
{}
constexpr inline explicit Point(float x, float y) noexcept : x(x), y(y) {} constexpr inline explicit Point(float x, float y) noexcept :
x(x), y(y)
{}
constexpr inline Point operator+(const Point &right) const noexcept constexpr inline Point operator+(const Point& right) const noexcept
{ {
return Point{right.x + x, right.y + y}; return Point{right.x + x, right.y + y};
} }
constexpr inline Point operator-(const Point &right) const noexcept constexpr inline Point operator-(const Point& right) const noexcept
{ {
return Point{right.x - x, right.y - y}; return Point{right.x - x, right.y - y};
} }
@ -37,4 +43,4 @@ struct Point
} }
}; };
} // namespace kku }

View File

@ -1,34 +1,37 @@
#pragma once #pragma once
#include <cmath>
#include <iostream>
#include <numeric> #include <numeric>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <cmath>
#include <iostream>
#include "core/time.h" #include "core/time.h"
namespace kku namespace kku
{ {
template <typename Grade, template<typename Grade, typename = std::enable_if_t<std::is_enum<Grade>::value>>
typename = std::enable_if_t<std::is_enum<Grade>::value>>
class PrecisionEvaluator class PrecisionEvaluator
{ {
public: public:
PrecisionEvaluator(const std::vector<microsec> &intervals, microsec offset) PrecisionEvaluator(const std::vector<microsec>& intervals, microsec offset) :
: _offset(offset), _intervals(intervals) _offset(offset),
_intervals(intervals)
{ {
_start_handling_offset = _offset - intervals.back(); _start_handling_offset = _offset - intervals.back();
_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
{ {
return music_play_offset > _start_handling_offset && return music_play_offset > _start_handling_offset
music_play_offset < _end_handling_offset; && music_play_offset < _end_handling_offset;
} }
Grade calculatePrecision(microsec odds) const Grade calculatePrecision(microsec odds) const
@ -48,7 +51,7 @@ class PrecisionEvaluator
return static_cast<Grade>(raw_grade); return static_cast<Grade>(raw_grade);
} }
private: private:
microsec _offset; microsec _offset;
microsec _start_handling_offset; microsec _start_handling_offset;
microsec _end_handling_offset; microsec _end_handling_offset;
@ -63,4 +66,4 @@ class PrecisionEvaluator
const std::vector<microsec> _intervals; const std::vector<microsec> _intervals;
}; };
} // namespace kku }

View File

@ -8,20 +8,20 @@ namespace kku
class Rectangle class Rectangle
{ {
public: public:
virtual ~Rectangle() = default; virtual ~Rectangle() = default;
virtual void setRect(const Area<float> &rect) = 0; virtual void setRect(const Area<float>& rect) = 0;
virtual Area<float> getRect() const = 0; virtual Area<float> getRect() const = 0;
virtual void setPosition(const Point &position) = 0; virtual void setPosition(const Point& position) = 0;
virtual Point getPosition() const = 0; virtual Point getPosition() const = 0;
virtual void move(const kku::Vector2<float> &delta) = 0; virtual void move(const kku::Vector2<float>& delta) = 0;
virtual void setColor(const Color &color) = 0; virtual void setColor(const Color& color) = 0;
virtual kku::Color getColor() const = 0; virtual kku::Color getColor() const = 0;
virtual bool contains(const kku::Point &position) const = 0; virtual bool contains(const kku::Point& position) const = 0;
virtual void display() = 0; virtual void display() = 0;
}; };
} // namespace kku }

View File

@ -1,15 +1,16 @@
#pragma once #pragma once
#include <map>
#include <memory> #include <memory>
#include <map>
namespace kku namespace kku
{ {
template <typename Resource, typename Id> class ResourceHolder template <typename Resource, typename Id>
class ResourceHolder
{ {
public: public:
inline void load(Id id, std::unique_ptr<Resource> &&resource) noexcept inline void load(Id id, std::unique_ptr<Resource>&& resource) noexcept
{ {
_resources[id] = std::move(resource); _resources[id] = std::move(resource);
} }
@ -19,33 +20,33 @@ template <typename Resource, typename Id> class ResourceHolder
return _resources.find(id)->second; return _resources.find(id)->second;
} }
private: private:
std::map<Id, std::shared_ptr<Resource>> _resources; std::map<Id, std::shared_ptr<Resource>> _resources;
}; };
namespace Font namespace Font
{ {
enum class Id enum class Id
{ {
GUI GUI
}; };
} }
namespace Texture namespace Texture
{ {
enum class Id enum class Id
{ {
GUI GUI
}; };
} }
namespace GUISprite namespace GUISprite
{ {
enum class Id enum class Id
{ {
SFML_LOGO, SFML_LOGO,
CRYPTOPP_LOGO CRYPTOPP_LOGO
}; };
} }
} // namespace kku }

View File

@ -1,21 +1,20 @@
#pragma once #pragma once
#include "core/point.h" #include "core/area.h"
#include "core/vector.h"
namespace kku namespace kku
{ {
class Sprite class Sprite
{ {
public: public:
virtual ~Sprite() = default; virtual ~Sprite() = default;
virtual void setPosition(const Point &position) = 0; virtual void setPosition(const Point& position) = 0;
virtual Point getPosition() const = 0; virtual Point getPosition() const = 0;
virtual void move(const kku::Vector2<float> &delta) = 0; virtual void move(const kku::Vector2<float>& delta) = 0;
virtual void display() const = 0; virtual void display() const = 0;
}; };
} // namespace kku }

View File

@ -1,29 +1,28 @@
#pragma once #pragma once
#include <map>
#include <memory> #include <memory>
#include <stack> #include <stack>
#include <map>
namespace kku namespace kku
{ {
template <typename Type, class SpriteFactory, class Sprite, template<typename Type, class SpriteFactory, class Sprite,
typename = std::enable_if_t<std::is_enum<Type>::value>> typename = std::enable_if_t<std::is_enum<Type>::value>>
class SpriteContainer class SpriteContainer
{ {
public: public:
explicit SpriteContainer(std::initializer_list<Type> &&types, explicit SpriteContainer(std::initializer_list<Type>&& types,
const std::shared_ptr<SpriteFactory> &factory, const std::shared_ptr<SpriteFactory>& factory,
std::size_t reserve_size = 20) std::size_t reserve_size = 20) :
: _sprite_factory(factory), _poll_reserve_size(reserve_size) _sprite_factory(factory),
_poll_reserve_size(reserve_size)
{ {
for (const Type &type : types) for (const Type& type : types)
reallocatePoll(type); reallocatePoll(type);
} }
inline std::shared_ptr<Sprite> getSprite(Type type) inline std::shared_ptr<Sprite> getSprite(Type type)
{ {
SpritePoll &poll = _sprite_dispatcher.at(type); SpritePoll& poll = _sprite_dispatcher.at(type);
if (poll.empty()) if (poll.empty())
reallocatePoll(type); reallocatePoll(type);
@ -34,8 +33,7 @@ class SpriteContainer
return sprite; return sprite;
} }
inline void resetSprite(const std::shared_ptr<Sprite> &sprite, inline void resetSprite(const std::shared_ptr<Sprite> &sprite, Type action) noexcept
Type action) noexcept
{ {
sprite->reset(); sprite->reset();
_sprite_dispatcher[action].push(sprite); _sprite_dispatcher[action].push(sprite);
@ -43,7 +41,7 @@ class SpriteContainer
~SpriteContainer() = default; ~SpriteContainer() = default;
private: private:
inline void reallocatePoll(Type sprite_type) inline void reallocatePoll(Type sprite_type)
{ {
SpritePoll &poll = _sprite_dispatcher[sprite_type]; SpritePoll &poll = _sprite_dispatcher[sprite_type];
@ -61,4 +59,4 @@ class SpriteContainer
std::size_t _poll_reserve_size; std::size_t _poll_reserve_size;
}; };
} // namespace kku }

View File

@ -162,11 +162,10 @@ struct SystemEvent
}; };
struct None struct None
{ {};
};
Type type = Type::None; Type type = Type::None;
std::variant<Size, Key, Mouse, None> data; std::variant<Size, Key, Mouse, None> data;
}; };
} // namespace kku }

View File

@ -1,24 +1,24 @@
#pragma once #pragma once
#include <string>
#include "core/color.h" #include "core/color.h"
#include "core/point.h" #include "core/point.h"
#include "core/vector.h" #include "core/vector.h"
#include <string>
namespace kku namespace kku
{ {
class Text class Text
{ {
public: public:
virtual ~Text() = default; virtual ~Text() = default;
virtual void setString(const std::string &string) = 0; virtual void setString(const std::string& string) = 0;
virtual void setCharacterSize(std::size_t pixels) = 0; virtual void setCharacterSize(std::size_t pixels) = 0;
virtual void setPosition(const Point &point) = 0; virtual void setPosition(const Point& point) = 0;
virtual void move(const kku::Vector2<float> &delta) = 0; virtual void move(const kku::Vector2<float>& delta) = 0;
virtual void setColor(const Color &color) = 0; virtual void setColor(const Color& color) = 0;
virtual void display() = 0; virtual void display() = 0;
}; };
} // namespace kku }

View File

@ -3,41 +3,20 @@
namespace kku namespace kku
{ {
/// microsec
///
/// Primitive alias representing microseconds, which
/// is the main time measure in-game.
/// 1 second is 1000000 microseconds.
using microsec = long long; using microsec = long long;
/// TimeRange
///
/// Object representing a section of time.
/// To ensure order safety use
/// static produceValidated function.
struct TimeRange struct TimeRange
{ {
const microsec begin = 0; const microsec begin = 0;
const microsec end = 0; const microsec end = 0;
constexpr inline explicit TimeRange() noexcept : begin(0), end(0) constexpr inline explicit TimeRange() noexcept :
{ begin(0), end(0)
} {}
constexpr inline explicit TimeRange(microsec x, microsec y) noexcept constexpr inline explicit TimeRange(microsec x, microsec y) noexcept :
: begin(x), end(y) begin(x), end(y)
{ {}
}
/// produceValidated
///
/// Creates an object of TimeRange, but
/// also makes sure to place begin and end
/// in the right order to avoid confusion.
static inline TimeRange produceValidated(microsec x, microsec y) noexcept
{
return (x < y) ? TimeRange(x, y) : TimeRange(y, x);
}
}; };
} // namespace kku }

View File

@ -1,34 +1,32 @@
#pragma once #pragma once
#include <algorithm>
#include <memory>
#include <set> #include <set>
#include <memory>
#include <algorithm>
#include "core/note.h"
#include "core/time.h" #include "core/time.h"
#include "core/note.h"
namespace kku namespace kku
{ {
template <class TNote, template <class TNote, class = std::enable_if_t<std::is_base_of<Note, TNote>::value>>
class = std::enable_if_t<std::is_base_of<Note, TNote>::value>>
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;
void recalculate(const microsec &offset) void recalculate(const microsec& offset)
{ {
_current_offset = offset; _current_offset = offset;
expire(_top_note); expire(_top_note);
if (_timeline.empty()) if (!_timeline.empty())
return; {
Iterator head_iterator = _timeline.begin(); Iterator head_iterator = _timeline.begin();
while (!isExpired(head_iterator)) while (!isExpired(head_iterator))
@ -38,8 +36,7 @@ class Timeline
Iterator pre_head = head_iterator; Iterator pre_head = head_iterator;
--pre_head; --pre_head;
_top_note = _top_note = !isExpired(pre_head) && (*pre_head)->isActive(offset)
!isExpired(pre_head) && (*pre_head)->isActive(offset)
? pre_head ? pre_head
: head_iterator; : head_iterator;
break; break;
@ -51,8 +48,9 @@ class Timeline
if (isExpired(_top_note)) if (isExpired(_top_note))
_top_note = _timeline.begin(); _top_note = _timeline.begin();
} }
}
void setNotes(const std::set<TNote *, NotePtrComparator> &notes) void setNotes(const std::set<TNote*, NotePtrComparator>& notes)
{ {
_timeline = std::move(notes); _timeline = std::move(notes);
@ -62,42 +60,43 @@ class Timeline
return; return;
} }
void insertNote(TNote *note) void insertNote(TNote* note)
{ {
_top_note = _timeline.insert(note).first; _top_note = _timeline.insert(note).first;
recalculate(_current_offset); recalculate(_current_offset);
update(_current_offset); update(_current_offset);
} }
void insertNotes(const std::set<TNote *, NotePtrComparator> &notes) void insertNotes(const std::set<TNote*, NotePtrComparator>& notes)
{ {
_timeline.insert(notes.begin(), notes.end()); _timeline.insert(notes.begin(), notes.end());
recalculate(_current_offset); recalculate(_current_offset);
update(_current_offset); update(_current_offset);
} }
inline void clear() inline void clear()
{ {
for (auto &note : _timeline) for (auto& note : _timeline)
delete note; delete note;
_timeline.clear(); _timeline.clear();
} }
void update(const microsec &offset) void update(const microsec& offset)
{ {
_current_offset = offset; _current_offset = offset;
updateTopNote(_current_offset); updateTopNote(_current_offset);
} }
Iterator getActiveNote(const microsec &music_offset) noexcept Iterator getActiveNote(const microsec& music_offset) noexcept
{ {
Iterator return_note = _timeline.end(); Iterator return_note = _timeline.end();
auto note_iterator = _top_note; auto note_iterator = _top_note;
while (!isExpired(note_iterator)) while (!isExpired(note_iterator))
{ {
const auto &note = *note_iterator; const auto& note = *note_iterator;
if (note->isActive(music_offset)) if (note->isActive(music_offset))
{ {
return_note = note_iterator; return_note = note_iterator;
@ -112,20 +111,21 @@ class Timeline
return return_note; return return_note;
} }
inline Iterator getNoteBy(const microsec &music_offset) noexcept inline Iterator getNoteBy(const microsec& music_offset) noexcept
{ {
return std::find_if(_timeline.begin(), _timeline.end(), return std::find_if(_timeline.begin(), _timeline.end(),
[music_offset](const auto &note) { [music_offset](const auto& note)
{
return note->getPerfectOffset() == music_offset; return note->getPerfectOffset() == music_offset;
}); });
} }
inline bool isExpired(const Iterator &iterator) const noexcept inline bool isExpired(const Iterator& iterator) const noexcept
{ {
return iterator == _timeline.end(); return iterator == _timeline.end();
} }
inline void expire(Iterator &iterator) noexcept inline void expire(Iterator& iterator) noexcept
{ {
iterator = _timeline.end(); iterator = _timeline.end();
} }
@ -145,19 +145,19 @@ class Timeline
return _timeline.end(); return _timeline.end();
} }
private: private:
std::set<TNote *, NotePtrComparator> _timeline; std::set<TNote*, NotePtrComparator> _timeline;
microsec _current_offset; microsec _current_offset;
inline void updateTopNote(const microsec &music_offset) noexcept inline void updateTopNote(const microsec& music_offset) noexcept
{ {
if (isExpired(_top_note)) if (isExpired(_top_note))
return; return;
const auto &top_note = *_top_note; const auto& top_note = *_top_note;
bool already_played = top_note->getPerfectOffset() < music_offset && bool already_played = top_note->getPerfectOffset() < music_offset
!top_note->isActive(music_offset); && !top_note->isActive(music_offset);
if (already_played) if (already_played)
++_top_note; ++_top_note;
@ -166,4 +166,6 @@ class Timeline
Iterator _top_note; Iterator _top_note;
}; };
} // namespace kku }

View File

@ -11,4 +11,6 @@ struct UpdateData
const microsec dt; const microsec dt;
}; };
} // namespace kku }

View File

@ -9,12 +9,13 @@ namespace kku
/// ///
/// Meaning an element of a vector space in math. /// Meaning an element of a vector space in math.
/// Don't mistake for std::vector<T> /// Don't mistake for std::vector<T>
template <typename T> using Vector2 = std::pair<T, T>; template <typename T>
using Vector2 = std::pair<T, T>;
template <typename T> template <typename T>
inline constexpr auto makeVector(T &&l, T &&r) -> Vector2<T> inline constexpr auto makeVector(T&& l, T&& r) -> Vector2<T>
{ {
return std::make_pair(std::forward<T>(l), std::forward<T>(r)); return std::make_pair(std::forward<T>(l), std::forward<T>(r));
} }
} // namespace kku }

View File

@ -1,10 +0,0 @@
{
pkgs ? import <nixpkgs> {},
unstable ? import <nixos-unstable> {},
}:
with pkgs;
mkShell {
buildInputs = [ sfml ];
nativeBuildInputs = [ ccls cmake ];
}

View File

@ -7,30 +7,26 @@
class Group; class Group;
class PushButton; class PushButton;
namespace kku namespace kku { class Sprite; class Text; }
{
class Sprite;
class Text;
} // namespace kku
class About : public GUIState class About : public GUIState
{ {
public: public:
struct Callbacks struct Callbacks
{ {
kku::lambda onLeaveAboutState; kku::lambda onLeaveAboutState;
}; };
explicit About(const std::shared_ptr<kku::CoreFactory> &factory, explicit About(const std::shared_ptr<kku::CoreFactory>& factory, Callbacks&& callbacks);
Callbacks &&callbacks); virtual void input(const kku::SystemEvent& event) override;
virtual void input(const kku::SystemEvent &event) override; virtual void update(const kku::microsec& dt) override;
virtual void update(const kku::microsec &dt) override;
virtual void display() const override; virtual void display() const override;
virtual void enter() override; virtual void enter() override;
virtual void leave() override; virtual void leave() override;
private: private:
const Callbacks _callbacks; const Callbacks _callbacks;
const std::shared_ptr<kku::CoreFactory> _core_factory; const std::shared_ptr<kku::CoreFactory> _core_factory;
const std::shared_ptr<kku::Sprite> _sfml_logo; const std::shared_ptr<kku::Sprite> _sfml_logo;
@ -40,3 +36,4 @@ class About : public GUIState
std::shared_ptr<Group> _buttons; std::shared_ptr<Group> _buttons;
std::shared_ptr<PushButton> _exit_button; std::shared_ptr<PushButton> _exit_button;
}; };

View File

@ -2,37 +2,33 @@
#include "application/state.h" #include "application/state.h"
#include "core/corefactory.h" #include "core/corefactory.h"
#include "core/functional.h"
#include "core/music.h" #include "core/music.h"
#include "core/functional.h"
class BPMCalculator; class BPMCalculator;
class Group; class Group;
namespace kku namespace kku { class Editor; }
{
class Editor;
}
class EditorState : public GUIState class EditorState : public GUIState
{ {
public: public:
struct Callbacks struct Callbacks
{ {
kku::lambda onLeaveEditorState; kku::lambda onLeaveEditorState;
}; };
explicit EditorState(const std::shared_ptr<kku::CoreFactory> &core_factory, explicit EditorState(const std::shared_ptr<kku::CoreFactory>& core_factory, std::unique_ptr<kku::Editor>&& editor, Callbacks&& callbacks);
std::unique_ptr<kku::Editor> &&editor,
Callbacks &&callbacks);
virtual ~EditorState() override; virtual ~EditorState() override;
virtual void input(const kku::SystemEvent &event) override; virtual void input(const kku::SystemEvent& event) override;
virtual void update(const kku::microsec &dt) override; virtual void update(const kku::microsec& dt) override;
virtual void display() const override; virtual void display() const override;
virtual void enter() override; virtual void enter() override;
virtual void leave() override; virtual void leave() override;
private: private:
const Callbacks _callbacks; const Callbacks _callbacks;
const std::shared_ptr<kku::CoreFactory> _core_factory; const std::shared_ptr<kku::CoreFactory> _core_factory;
std::shared_ptr<kku::Music> _music; std::shared_ptr<kku::Music> _music;
@ -42,3 +38,4 @@ class EditorState : public GUIState
std::unique_ptr<kku::Editor> _editor; std::unique_ptr<kku::Editor> _editor;
}; };

View File

@ -1,33 +1,33 @@
#pragma once #pragma once
#include "state.h"
#include "core/music.h"
#include "core/game.h"
#include "core/corefactory.h" #include "core/corefactory.h"
#include "core/functional.h" #include "core/functional.h"
#include "core/game.h"
#include "core/music.h"
#include "state.h"
class Group; class Group;
class GameState : public GUIState class GameState : public GUIState
{ {
public: public:
struct Callbacks struct Callbacks
{ {
kku::lambda onLeaveGame; kku::lambda onLeaveGame;
}; };
explicit GameState(const std::shared_ptr<kku::CoreFactory> &core_factory,
const std::shared_ptr<kku::Game> &game,
Callbacks &&callbacks);
virtual void input(const kku::SystemEvent &event) override; explicit GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks);
virtual void update(const kku::microsec &dt) override;
virtual void input(const kku::SystemEvent& event) override;
virtual void update(const kku::microsec& dt) override;
virtual void display() const override; virtual void display() const override;
virtual void enter() override; virtual void enter() override;
virtual void leave() override; virtual void leave() override;
private: private:
const std::shared_ptr<kku::CoreFactory> _core_factory; const std::shared_ptr<kku::CoreFactory> _core_factory;
std::shared_ptr<kku::Music> _music; std::shared_ptr<kku::Music> _music;
std::shared_ptr<kku::Game> _game; std::shared_ptr<kku::Game> _game;
@ -35,3 +35,4 @@ class GameState : public GUIState
kku::lambda _onEnterGameCallback; kku::lambda _onEnterGameCallback;
kku::lambda _onLeaveGameCallback; kku::lambda _onLeaveGameCallback;
}; };

View File

@ -8,7 +8,8 @@ class Group;
class MainMenu : public GUIState class MainMenu : public GUIState
{ {
public: public:
struct Callbacks struct Callbacks
{ {
kku::lambda onAppendGameState; kku::lambda onAppendGameState;
@ -16,18 +17,18 @@ class MainMenu : public GUIState
kku::lambda onAppendAboutState; kku::lambda onAppendAboutState;
}; };
explicit MainMenu(const std::shared_ptr<kku::CoreFactory> &factory, explicit MainMenu(const std::shared_ptr<kku::CoreFactory>& factory, Callbacks&& callbacks);
Callbacks &&callbacks); virtual void input(const kku::SystemEvent& event) override;
virtual void input(const kku::SystemEvent &event) override; virtual void update(const kku::microsec& dt) override;
virtual void update(const kku::microsec &dt) override;
virtual void display() const override; virtual void display() const override;
virtual void enter() override; virtual void enter() override;
virtual void leave() override; virtual void leave() override;
private: private:
const Callbacks _callbacks; const Callbacks _callbacks;
const std::shared_ptr<kku::CoreFactory> _core_factory; const std::shared_ptr<kku::CoreFactory> _core_factory;
std::shared_ptr<Group> _buttons; std::shared_ptr<Group> _buttons;
}; };

View File

@ -1,17 +1,17 @@
#pragma once #pragma once
#include <memory>
#include <stack> #include <stack>
#include <memory>
#include "core/systemevent.h" #include "core/systemevent.h"
#include "core/time.h"
#include "core/vector.h" #include "core/vector.h"
#include "core/time.h"
class GUIState class GUIState
{ {
public: public:
enum Tag
{ enum Tag {
SPLASH_SCREEN, SPLASH_SCREEN,
MAIN_MENU, MAIN_MENU,
GAME_PICKER, GAME_PICKER,
@ -26,8 +26,8 @@ class GUIState
virtual ~GUIState() = default; virtual ~GUIState() = default;
virtual void input(const kku::SystemEvent &event) = 0; virtual void input(const kku::SystemEvent& event) = 0;
virtual void update(const kku::microsec &dt) = 0; virtual void update(const kku::microsec& dt) = 0;
virtual void display() const = 0; virtual void display() const = 0;
virtual void enter() = 0; virtual void enter() = 0;

View File

@ -1,24 +1,24 @@
#pragma once #pragma once
#include <array>
#include <memory>
#include <vector> #include <vector>
#include <memory>
#include <array>
#include "../../include/application/state.h" // HOW? WHY DOESN'T "application/state.h" LINK ON BY ITSELF #include "../../include/application/state.h" // HOW? WHY DOESN'T "application/state.h" LINK ON BY ITSELF
#include "core/corefactory.h" #include "core/corefactory.h"
class Application class Application
{ {
public: public:
virtual ~Application() = default; virtual ~Application() = default;
virtual bool init(); virtual bool init();
virtual void display() = 0; virtual void display() = 0;
virtual void run() = 0; virtual void run() = 0;
void input(const kku::SystemEvent &input); void input(const kku::SystemEvent& input);
void update(const kku::microsec &dt); void update(const kku::microsec& dt);
protected: protected:
std::shared_ptr<kku::CoreFactory> _core_factory; std::shared_ptr<kku::CoreFactory> _core_factory;
std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states; std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states;

View File

@ -1,64 +0,0 @@
#pragma once
#include <string>
/**
* @brief Basic logging class
*
* Defines helper functions for logging facility. Configured in
* Application::init()
*
*/
class Log
{
public:
enum LogLevel
{
FATAL,
ERROR,
WARN,
INFO,
DEBUG,
};
LogLevel level = WARN; ///< Default logging level
/**
* @brief Prints message to stdout
*
* TODO: write to configurable stream, be it stdout, stderr or even a file
*
* @param level the message level
* @param fmt the message format
* @param ... variable parameters
*/
void log(LogLevel level, const std::string &fmt, ...);
private:
inline std::string _getLabel(LogLevel level)
{
switch (level)
{
case DEBUG:
return "DEBUG";
case INFO:
return "INFO ";
case WARN:
return "WARN ";
case ERROR:
return "ERROR";
case FATAL:
return "FATAL";
default:
return "UNK ";
}
}
};
extern Log LOG; /// Global variable :(
#define INFO(fmt, ...) LOG.log(Log::INFO, fmt, ##__VA_ARGS__)
#define WARN(fmt, ...) LOG.log(Log::WARN, fmt, ##__VA_ARGS__)
#define ERROR(fmt, ...) LOG.log(Log::ERROR, fmt, ##__VA_ARGS__)
#define FATAL(fmt, ...) LOG.log(Log::FATAL, fmt, ##__VA_ARGS__)
#define DEBUG(fmt, ...) LOG.log(Log::DEBUG, fmt, ##__VA_ARGS__)

View File

@ -1,10 +1,10 @@
#include "application/about.h" #include "application/about.h"
#include "widgets/group.h"
#include "widgets/pushbutton.h" #include "widgets/pushbutton.h"
#include "widgets/group.h"
About::About(const std::shared_ptr<kku::CoreFactory> &factory, About::About(const std::shared_ptr<kku::CoreFactory>& factory, About::Callbacks&& callbacks) :
About::Callbacks &&callbacks) _callbacks(std::move(callbacks)),
: _callbacks(std::move(callbacks)), _core_factory(factory), _core_factory(factory),
_sfml_logo(factory->getSprite(kku::GUISprite::Id::SFML_LOGO)), _sfml_logo(factory->getSprite(kku::GUISprite::Id::SFML_LOGO)),
_cryptopp_logo(factory->getSprite(kku::GUISprite::Id::CRYPTOPP_LOGO)), _cryptopp_logo(factory->getSprite(kku::GUISprite::Id::CRYPTOPP_LOGO)),
_powered_by_text(factory->getText(kku::Font::Id::GUI)), _powered_by_text(factory->getText(kku::Font::Id::GUI)),
@ -16,12 +16,12 @@ About::About(const std::shared_ptr<kku::CoreFactory> &factory,
_cryptopp_logo->move(kku::Vector2<float>{250., 180}); _cryptopp_logo->move(kku::Vector2<float>{250., 180});
} }
void About::input(const kku::SystemEvent &event) void About::input(const kku::SystemEvent& event)
{ {
_buttons->input(event); _buttons->input(event);
} }
void About::update(const kku::microsec &dt) void About::update(const kku::microsec& dt)
{ {
_buttons->update(dt); _buttons->update(dt);
} }
@ -42,14 +42,12 @@ void About::enter()
if (!_exit_button) if (!_exit_button)
{ {
_exit_button = _exit_button = std::make_shared<PushButton>("Return", _core_factory, 48);
std::make_shared<PushButton>("Return", _core_factory, 48);
_exit_button->setCallback(_callbacks.onLeaveAboutState); _exit_button->setCallback(_callbacks.onLeaveAboutState);
_buttons->addChild(_exit_button); _buttons->addChild(_exit_button);
} }
_exit_button->setRect( _exit_button->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 4,
kku::Area<float>{window_width / 3.f, window_height / 7.f * 4,
window_width / 3.f, window_height / 7.f}); window_width / 3.f, window_height / 7.f});
_buttons->setVisibility(); _buttons->setVisibility();
} }
@ -58,3 +56,4 @@ void About::leave()
{ {
_buttons->setVisibility(false); _buttons->setVisibility(false);
} }

View File

@ -1,41 +1,30 @@
#include "application/application.h" #include "application/application.h"
#include "application/log.h"
#include "core/editor.h"
#include "core/gameevent.h" #include "core/gameevent.h"
#include "core/editor.h"
#include "application/about.h"
#include "application/editorstate.h"
#include "application/gamestate.h"
#include "application/mainmenu.h" #include "application/mainmenu.h"
#include "application/gamestate.h"
#include "application/editorstate.h"
#include "application/about.h"
#include "classicmode/classicfactory.h" #include "classicmode/classicfactory.h"
Log LOG;
bool Application::init() bool Application::init()
{ {
LOG.level = Log::DEBUG;
DEBUG("Initializing Application");
if (!_core_factory) if (!_core_factory)
return false; return false;
MainMenu::Callbacks callbacks = { MainMenu::Callbacks callbacks =
[&]() { pushState(GUIState::Tag::GAME); }, {
[&]() { pushState(GUIState::Tag::EDITOR); }, [&](){ pushState(GUIState::Tag::GAME); },
[&]() { pushState(GUIState::Tag::ABOUT); }, [&](){ pushState(GUIState::Tag::EDITOR); },
[&](){ pushState(GUIState::Tag::ABOUT); },
}; };
const auto main_menu = const auto main_menu = std::make_shared<MainMenu>(_core_factory, std::move(callbacks));
std::make_shared<MainMenu>(_core_factory, std::move(callbacks)); const auto game_state = std::make_shared<GameState>(_core_factory, classic::getGame(_core_factory), GameState::Callbacks{[&](){ popState(); }});
const auto game_state = std::make_shared<GameState>( const auto editor = std::make_shared<EditorState>(_core_factory, classic::getEditor(_core_factory), EditorState::Callbacks{[&](){ popState(); }});
_core_factory, classic::getGame(_core_factory), const auto about = std::make_shared<About>(_core_factory, About::Callbacks{[&](){ popState(); }});
GameState::Callbacks{[&]() { popState(); }});
const auto editor = std::make_shared<EditorState>(
_core_factory, classic::getEditor(_core_factory),
EditorState::Callbacks{[&]() { popState(); }});
const auto about = std::make_shared<About>(
_core_factory, About::Callbacks{[&]() { popState(); }});
_states[GUIState::Tag::MAIN_MENU] = main_menu; _states[GUIState::Tag::MAIN_MENU] = main_menu;
_states[GUIState::Tag::GAME] = game_state; _states[GUIState::Tag::GAME] = game_state;
@ -47,20 +36,18 @@ bool Application::init()
return true; return true;
} }
void Application::input(const kku::SystemEvent &event) void Application::input(const kku::SystemEvent& event)
{ {
_state_stack.back()->input(event); _state_stack.back()->input(event);
} }
void Application::update(const kku::microsec &dt) void Application::update(const kku::microsec& dt)
{ {
_state_stack.back()->update(dt); _state_stack.back()->update(dt);
} }
void Application::pushState(GUIState::Tag new_state) void Application::pushState(GUIState::Tag new_state)
{ {
DEBUG("Pushing state %d", new_state);
if (!_state_stack.empty()) if (!_state_stack.empty())
_state_stack.back()->leave(); _state_stack.back()->leave();
@ -70,7 +57,6 @@ void Application::pushState(GUIState::Tag new_state)
void Application::popState() void Application::popState()
{ {
DEBUG("Popping state");
_state_stack.back()->leave(); _state_stack.back()->leave();
_state_stack.pop_back(); _state_stack.pop_back();
_state_stack.back()->enter(); _state_stack.back()->enter();

View File

@ -1,32 +1,31 @@
#include "application/editorstate.h" #include "application/editorstate.h"
#include "tools/bpmcalculator.h"
#include "widgets/bpmcalculatorwidget.h"
#include "widgets/button.h" #include "widgets/button.h"
#include "widgets/editorwidget.h"
#include "widgets/group.h" #include "widgets/group.h"
#include "widgets/menubar.h" #include "widgets/menubar.h"
#include "widgets/window.h" #include "widgets/window.h"
#include "widgets/editorwidget.h"
#include "widgets/bpmcalculatorwidget.h"
#include "tools/bpmcalculator.h"
#include "core/editor.h" #include "core/editor.h"
EditorState::EditorState(const std::shared_ptr<kku::CoreFactory> &core_factory, EditorState::EditorState(const std::shared_ptr<kku::CoreFactory>& core_factory,
std::unique_ptr<kku::Editor> &&editor, std::unique_ptr<kku::Editor>&& editor,
Callbacks &&callbacks) Callbacks&& callbacks) :
: _callbacks(std::move(callbacks)), _core_factory(core_factory), _callbacks(std::move(callbacks)),
_core_factory(core_factory),
_editor(std::move(editor)) _editor(std::move(editor))
{ {}
}
EditorState::~EditorState() EditorState::~EditorState()
{ {}
}
void EditorState::input(const kku::SystemEvent &event) void EditorState::input(const kku::SystemEvent& event)
{ {
_group->input(event); _group->input(event);
} }
void EditorState::update(const kku::microsec &dt) void EditorState::update(const kku::microsec& dt)
{ {
_group->update(dt); _group->update(dt);
} }
@ -42,21 +41,19 @@ void EditorState::enter()
_music->open("resources/METEOR.flac"); _music->open("resources/METEOR.flac");
_music->setVolume(5.f); _music->setVolume(5.f);
auto &group = _group; auto& group = _group;
auto &music = _music; auto& music = _music;
auto &editor = _editor; auto& editor = _editor;
_bpm_calculator = std::make_shared<BPMCalculator>(); _bpm_calculator = std::make_shared<BPMCalculator>();
auto &bpm_calculator = _bpm_calculator; auto& bpm_calculator = _bpm_calculator;
std::shared_ptr<BPMCalculatorWidget> bpm_widget = std::shared_ptr<BPMCalculatorWidget> bpm_widget = std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _core_factory);
std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _core_factory);
auto button_start = std::make_shared<PushButton>("Start", _core_factory); auto button_start = std::make_shared<PushButton>("Start", _core_factory);
auto button_stop = std::make_shared<PushButton>("Stop", _core_factory); auto button_stop = std::make_shared<PushButton>("Stop", _core_factory);
auto button_apply = std::make_shared<PushButton>("Apply", _core_factory); auto button_apply = std::make_shared<PushButton>("Apply", _core_factory);
button_start->setCallback( button_start->setCallback([bpm_calculator, button_start, button_stop, &music]()
[bpm_calculator, button_start, button_stop, &music]()
{ {
music->play(); music->play();
bpm_calculator->start(); bpm_calculator->start();
@ -64,8 +61,7 @@ void EditorState::enter()
button_stop->setVisibility(true); button_stop->setVisibility(true);
}); });
button_stop->setCallback( button_stop->setCallback([bpm_calculator, button_start, button_stop, &music]()
[bpm_calculator, button_start, button_stop, &music]()
{ {
music->stop(); music->stop();
bpm_calculator->stop(); bpm_calculator->stop();
@ -73,11 +69,10 @@ void EditorState::enter()
button_stop->setVisibility(false); button_stop->setVisibility(false);
}); });
button_apply->setCallback( button_apply->setCallback([&editor, bpm_calculator]()
[&editor, bpm_calculator]()
{ {
kku::BPMSection section; kku::BPMSection section;
const auto &info = bpm_calculator->fetchApproximatedInfo(); const auto& info = bpm_calculator->fetchApproximatedInfo();
section.bpm = info.BPM; section.bpm = info.BPM;
section.interval = info.interval; section.interval = info.interval;
section.fraction = 2; section.fraction = 2;
@ -90,11 +85,10 @@ void EditorState::enter()
bpm_widget_init.stop = button_stop; bpm_widget_init.stop = button_stop;
bpm_widget_init.apply = button_apply; bpm_widget_init.apply = button_apply;
bpm_widget_init.start = button_start; bpm_widget_init.start = button_start;
bpm_widget_init.current_time = [&music]() -> kku::microsec bpm_widget_init.current_time = [&music]() -> kku::microsec { return music->fetchOffset(); };
{ return music->fetchOffset(); };
bpm_widget->init(std::move(bpm_widget_init)); bpm_widget->init(std::move(bpm_widget_init));
const auto bpm_widget_callback = [&group, bpm_widget = bpm_widget, &music]() const auto bpm_widget_callback = [&group, bpm_widget=bpm_widget, &music]()
{ {
music->stop(); music->stop();
bpm_widget->setVisibility(false); bpm_widget->setVisibility(false);
@ -106,18 +100,15 @@ void EditorState::enter()
auto menu_bar = std::make_shared<MenuBar>(_core_factory); auto menu_bar = std::make_shared<MenuBar>(_core_factory);
auto bpm_button = auto bpm_button = std::make_shared<PushButton>("Calculate BPM", _core_factory);
std::make_shared<PushButton>("Calculate BPM", _core_factory);
bpm_button->setCallback( bpm_button->setCallback([&group, bpm_widget=bpm_widget]()
[&group, bpm_widget = bpm_widget]()
{ {
group->blockBy(bpm_widget); group->blockBy(bpm_widget);
bpm_widget->setVisibility(true); bpm_widget->setVisibility(true);
}); });
bpm_widget->setRect( bpm_widget->setRect(kku::Area<float>{render_size.first / 3.f, render_size.second / 3.f,
kku::Area<float>{render_size.first / 3.f, render_size.second / 3.f,
render_size.first / 3.f, render_size.second / 3.f}); render_size.first / 3.f, render_size.second / 3.f});
bpm_widget->addBarButton("X", bpm_widget_callback); bpm_widget->addBarButton("X", bpm_widget_callback);
@ -129,11 +120,9 @@ void EditorState::enter()
auto test_menu_3 = std::make_shared<MenuDrop>(_core_factory); auto test_menu_3 = std::make_shared<MenuDrop>(_core_factory);
test_menu_3->setRect(kku::Area<float>{0., 0., 200., 27. * 5.}); test_menu_3->setRect(kku::Area<float>{0., 0., 200., 27. * 5.});
auto test_cascade_button = auto test_cascade_button = std::make_shared<CascadeMenuButton>("Show submenu", _core_factory);
std::make_shared<CascadeMenuButton>("Show submenu", _core_factory);
auto test_cascade_button_2 = auto test_cascade_button_2 = std::make_shared<CascadeMenuButton>("Show submenu 2", _core_factory);
std::make_shared<CascadeMenuButton>("Show submenu 2", _core_factory);
auto quit_button = std::make_shared<PushButton>("Quit", _core_factory); auto quit_button = std::make_shared<PushButton>("Quit", _core_factory);
quit_button->setCallback(_callbacks.onLeaveEditorState); quit_button->setCallback(_callbacks.onLeaveEditorState);
@ -161,18 +150,19 @@ void EditorState::enter()
menu_bar->setVisibility(true); menu_bar->setVisibility(true);
EditorWidget::Callbacks callbacks; EditorWidget::Callbacks callbacks;
callbacks.onDisplay = [&editor]() { editor->display(); }; callbacks.onDisplay = [&editor]()
callbacks.onInput = [&editor, &music](const kku::SystemEvent &event)
{ {
if (event.type == kku::SystemEvent::Type::KeyRelease && editor->display();
std::get<kku::SystemEvent::Key>(event.data).view == };
kku::SystemEvent::Key::Code::Space)
callbacks.onInput = [&editor, &music](const kku::SystemEvent& event)
{
if (event.type == kku::SystemEvent::Type::KeyRelease
&& std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
music->isPlaying() ? music->pause() : music->play(); music->isPlaying() ? music->pause() : music->play();
else if (event.type == kku::SystemEvent::Type::MouseWheelScroll) else if (event.type == kku::SystemEvent::Type::MouseWheelScroll)
{ {
const auto &up = const auto& up = std::get<kku::SystemEvent::Mouse>(event.data).scrolled_up;
std::get<kku::SystemEvent::Mouse>(event.data).scrolled_up;
music->moveOffset(up ? 500000 : -500000); music->moveOffset(up ? 500000 : -500000);
editor->recalculate(music->fetchOffset()); editor->recalculate(music->fetchOffset());
} }
@ -180,7 +170,8 @@ void EditorState::enter()
editor->input(kku::GameEvent{music->fetchOffset(), event}); editor->input(kku::GameEvent{music->fetchOffset(), event});
}; };
callbacks.onUpdate = [&editor, &music](const kku::microsec &dt) { callbacks.onUpdate = [&editor, &music](const kku::microsec& dt)
{
editor->update(kku::UpdateData{music->fetchOffset(), dt}); editor->update(kku::UpdateData{music->fetchOffset(), dt});
}; };

View File

@ -4,15 +4,14 @@
#include "core/game.h" #include "core/game.h"
GameState::GameState(const std::shared_ptr<kku::CoreFactory> &core_factory, GameState::GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks) :
const std::shared_ptr<kku::Game> &game, _core_factory(core_factory),
Callbacks &&callbacks) _game(game),
: _core_factory(core_factory), _game(game),
_onLeaveGameCallback(callbacks.onLeaveGame) _onLeaveGameCallback(callbacks.onLeaveGame)
{ {
} }
void GameState::input(const kku::SystemEvent &event) void GameState::input(const kku::SystemEvent& event)
{ {
switch (event.type) switch (event.type)
{ {
@ -34,7 +33,7 @@ void GameState::input(const kku::SystemEvent &event)
_game->input(kku::GameEvent{_music->fetchOffset(), event}); _game->input(kku::GameEvent{_music->fetchOffset(), event});
} }
void GameState::update(const kku::microsec &dt) void GameState::update(const kku::microsec& dt)
{ {
_game->update(kku::UpdateData{_music->fetchOffset(), dt}); _game->update(kku::UpdateData{_music->fetchOffset(), dt});
} }

View File

@ -1,27 +0,0 @@
#include <cstdarg>
#include <iostream>
#include <vector>
#include "application/log.h"
void Log::log(LogLevel level, const std::string &fmt, ...)
{
if (level > this->level)
return;
va_list args;
// First va_start: count how many characters are needed for formatting
va_start(args, fmt);
size_t len = std::vsnprintf(NULL, 0, fmt.c_str(), args);
va_end(args);
std::vector<char> buf(len + 1);
// Second va_start: actually write formatted message to buffer
va_start(args, fmt);
std::vsnprintf(&buf[0], len + 1, fmt.c_str(), args);
va_end(args);
std::cout << this->_getLabel(level) << " " << &buf[0] << std::endl;
}

View File

@ -1,20 +1,20 @@
#include "application/mainmenu.h" #include "application/mainmenu.h"
#include "widgets/group.h"
#include "widgets/pushbutton.h" #include "widgets/pushbutton.h"
#include "widgets/group.h"
MainMenu::MainMenu(const std::shared_ptr<kku::CoreFactory> &factory, MainMenu::MainMenu(const std::shared_ptr<kku::CoreFactory>& factory, MainMenu::Callbacks&& callbacks) :
MainMenu::Callbacks &&callbacks) _callbacks(std::move(callbacks)),
: _callbacks(std::move(callbacks)), _core_factory(factory), _core_factory(factory),
_buttons(std::make_shared<Group>()) _buttons(std::make_shared<Group>())
{ {
} }
void MainMenu::input(const kku::SystemEvent &event) void MainMenu::input(const kku::SystemEvent& event)
{ {
_buttons->input(event); _buttons->input(event);
} }
void MainMenu::update(const kku::microsec &dt) void MainMenu::update(const kku::microsec& dt)
{ {
_buttons->update(dt); _buttons->update(dt);
} }
@ -30,24 +30,18 @@ void MainMenu::enter()
const float window_width = render_size.first; const float window_width = render_size.first;
const float window_height = render_size.second; const float window_height = render_size.second;
auto button_start = auto button_start = std::make_shared<PushButton>("Start", _core_factory, 48);
std::make_shared<PushButton>("Start", _core_factory, 48); button_start->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f,
button_start->setRect(
kku::Area<float>{window_width / 3.f, window_height / 7.f,
window_width / 3.f, window_height / 7.f}); window_width / 3.f, window_height / 7.f});
button_start->setCallback(_callbacks.onAppendGameState); button_start->setCallback(_callbacks.onAppendGameState);
auto button_editor = auto button_editor = std::make_shared<PushButton>("Editor", _core_factory, 48);
std::make_shared<PushButton>("Editor", _core_factory, 48); button_editor->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 3,
button_editor->setRect(
kku::Area<float>{window_width / 3.f, window_height / 7.f * 3,
window_width / 3.f, window_height / 7.f}); window_width / 3.f, window_height / 7.f});
button_editor->setCallback(_callbacks.onAppendEditorState); button_editor->setCallback(_callbacks.onAppendEditorState);
auto button_about = auto button_about = std::make_shared<PushButton>("About", _core_factory, 48);
std::make_shared<PushButton>("About", _core_factory, 48); button_about->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 5,
button_about->setRect(
kku::Area<float>{window_width / 3.f, window_height / 7.f * 5,
window_width / 3.f, window_height / 7.f}); window_width / 3.f, window_height / 7.f});
button_about->setCallback(_callbacks.onAppendAboutState); button_about->setCallback(_callbacks.onAppendAboutState);
@ -62,3 +56,4 @@ void MainMenu::leave()
{ {
_buttons->setVisibility(false); _buttons->setVisibility(false);
} }

View File

@ -1,14 +1,14 @@
#include "bpmcalculatorwidget.h" #include "bpmcalculatorwidget.h"
#include "core/editor.h"
#include "tools/bpmcalculator.h" #include "tools/bpmcalculator.h"
#include "core/editor.h"
#include <iostream> #include <iostream>
BPMCalculatorWidget::BPMCalculatorWidget( BPMCalculatorWidget::BPMCalculatorWidget(const std::shared_ptr<BPMCalculator>& bpm_calculator, const std::shared_ptr<kku::CoreFactory>& factory) :
const std::shared_ptr<BPMCalculator> &bpm_calculator, Window(factory, "BPM Calculation"),
const std::shared_ptr<kku::CoreFactory> &factory) _bpm_calculator(bpm_calculator),
: Window(factory, "BPM Calculation"), _bpm_calculator(bpm_calculator), _slider(std::make_shared<BPMSlider>(factory)),
_slider(std::make_shared<BPMSlider>(factory)), _core_factory(factory), _core_factory(factory),
_ticked(false) _ticked(false)
{ {
_bpm_value = _core_factory->getText(kku::Font::Id::GUI); _bpm_value = _core_factory->getText(kku::Font::Id::GUI);
@ -20,7 +20,7 @@ BPMCalculatorWidget::BPMCalculatorWidget(
_slap.setVolume(30.);*/ _slap.setVolume(30.);*/
} }
void BPMCalculatorWidget::input(const kku::SystemEvent &event) void BPMCalculatorWidget::input(const kku::SystemEvent& event)
{ {
switch (event.type) switch (event.type)
{ {
@ -29,8 +29,7 @@ void BPMCalculatorWidget::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::KeyPress: case kku::SystemEvent::Type::KeyPress:
{ {
if (std::get<kku::SystemEvent::Key>(event.data).view == if (std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
kku::SystemEvent::Key::Code::Space)
{ {
_bpm_calculator->click(_current_time()); _bpm_calculator->click(_current_time());
} }
@ -41,7 +40,7 @@ void BPMCalculatorWidget::input(const kku::SystemEvent &event)
Window::input(event); Window::input(event);
} }
void BPMCalculatorWidget::update(const kku::microsec &dt) void BPMCalculatorWidget::update(const kku::microsec& dt)
{ {
Window::update(dt); Window::update(dt);
@ -50,15 +49,12 @@ void BPMCalculatorWidget::update(const kku::microsec &dt)
{ {
_bpm_value->setString(std::to_string(static_cast<int>(beat_info.BPM))); _bpm_value->setString(std::to_string(static_cast<int>(beat_info.BPM)));
const kku::microsec until_beat = const kku::microsec until_beat = _bpm_calculator->fetchTimeUntilNextBeat(_current_time());
_bpm_calculator->fetchTimeUntilNextBeat(_current_time()); const auto time_relation = static_cast<long double>(beat_info.interval) / static_cast<long double>(until_beat);
const auto time_relation =
static_cast<long double>(beat_info.interval) /
static_cast<long double>(until_beat);
const auto slider_path_left = _slider->getRect().width / time_relation; const auto slider_path_left = _slider->getRect().width / time_relation;
if (slider_path_left < 50) if (slider_path_left < 50)
{ {
// if (!_ticked) //if (!_ticked)
//_slap.play(); //_slap.play();
_ticked = true; _ticked = true;
} }
@ -83,38 +79,30 @@ void BPMCalculatorWidget::display() const
} }
} }
void BPMCalculatorWidget::setRect(const kku::Area<float> &rect) void BPMCalculatorWidget::setRect(const kku::Area<float>& rect)
{ {
Window::setRect(rect); Window::setRect(rect);
_slider->setRect(kku::Area<float>{0, 0, rect.width / 8 * 6, 100}); _slider->setRect(kku::Area<float>{0, 0, rect.width / 8 * 6, 100});
_slider->setPosition( _slider->setPosition(kku::Point{_window_content->getRect().left + rect.width / 8,
kku::Point{_window_content->getRect().left + rect.width / 8,
_window_content->getRect().top + rect.height / 8 * 3}); _window_content->getRect().top + rect.height / 8 * 3});
_button_start->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30}); _button_start->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
_button_start->setPosition( _button_start->setPosition(kku::Point{_window_content->getRect().left + rect.width / 7,
kku::Point{_window_content->getRect().left + rect.width / 7, _window_content->getRect().top + _window_content->getRect().height - 40});
_window_content->getRect().top +
_window_content->getRect().height - 40});
_button_stop->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30}); _button_stop->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
_button_stop->setPosition( _button_stop->setPosition(kku::Point{_window_content->getRect().left + rect.width / 7,
kku::Point{_window_content->getRect().left + rect.width / 7, _window_content->getRect().top + _window_content->getRect().height - 40});
_window_content->getRect().top +
_window_content->getRect().height - 40});
_button_apply->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30}); _button_apply->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
_button_apply->setPosition(kku::Point{ _button_apply->setPosition(kku::Point{_window_content->getRect().left + 50 + (2 * (rect.width / 7)),
_window_content->getRect().left + 50 + (2 * (rect.width / 7)), _window_content->getRect().top + _window_content->getRect().height - 40});
_window_content->getRect().top + _window_content->getRect().height -
40});
_bpm_value->setPosition( _bpm_value->setPosition(kku::Point{_window_content->getRect().left + rect.width / 8,
kku::Point{_window_content->getRect().left + rect.width / 8, _window_content->getRect().top + rect.height / 8 });
_window_content->getRect().top + rect.height / 8});
} }
void BPMCalculatorWidget::move(const kku::Vector2<float> &delta) void BPMCalculatorWidget::move(const kku::Vector2<float>& delta)
{ {
Window::move(delta); Window::move(delta);
@ -122,7 +110,7 @@ void BPMCalculatorWidget::move(const kku::Vector2<float> &delta)
_bpm_value->move(delta); _bpm_value->move(delta);
} }
void BPMCalculatorWidget::setPosition(const kku::Point &position) void BPMCalculatorWidget::setPosition(const kku::Point& position)
{ {
Window::setPosition(position); Window::setPosition(position);
} }

View File

@ -9,12 +9,12 @@ BPMSlider::BPMSlider(const std::shared_ptr<kku::CoreFactory> &factory)
_slider_tick->setColor(kku::Color{255, 0, 0, 255}); _slider_tick->setColor(kku::Color{255, 0, 0, 255});
} }
void BPMSlider::input(const kku::SystemEvent &event) void BPMSlider::input(const kku::SystemEvent& event)
{ {
Widget::input(event); Widget::input(event);
} }
void BPMSlider::update(const kku::microsec &dt) void BPMSlider::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -26,26 +26,28 @@ void BPMSlider::display() const
Widget::display(); Widget::display();
} }
void BPMSlider::setRect(const kku::Area<float> &rect) void BPMSlider::setRect(const kku::Area<float>& rect)
{ {
_slider_background->setRect(rect); _slider_background->setRect(rect);
_slider_tick->setRect( _slider_tick->setRect(kku::Area<float>{rect.left,
kku::Area<float>{rect.left, rect.top, rect.width / 30.f, rect.height}); rect.top,
rect.width / 30.f,
rect.height});
} }
void BPMSlider::setPosition(const kku::Point &position) void BPMSlider::setPosition(const kku::Point& position)
{ {
_slider_background->setPosition(position); _slider_background->setPosition(position);
_slider_tick->setPosition(position); _slider_tick->setPosition(position);
} }
void BPMSlider::move(const kku::Vector2<float> &delta) void BPMSlider::move(const kku::Vector2<float>& delta)
{ {
_slider_background->move(delta); _slider_background->move(delta);
_slider_tick->move(delta); _slider_tick->move(delta);
} }
bool BPMSlider::isUnderMouse(const kku::Point &position) const bool BPMSlider::isUnderMouse(const kku::Point& position) const
{ {
return _slider_background->contains(position); return _slider_background->contains(position);
} }
@ -62,7 +64,6 @@ kku::Point BPMSlider::getPosition() const
void BPMSlider::setTickPosition(float x_position) void BPMSlider::setTickPosition(float x_position)
{ {
_slider_tick->setPosition( _slider_tick->setPosition(kku::Point{_slider_background->getPosition().x + x_position,
kku::Point{_slider_background->getPosition().x + x_position,
_slider_tick->getPosition().y}); _slider_tick->getPosition().y});
} }

View File

@ -1,10 +1,8 @@
#include "button.h" #include "button.h"
#include <iostream> #include <iostream>
Button::Button(const std::string &text, Button::Button(const std::string &text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
const std::shared_ptr<kku::CoreFactory> &factory, _core_factory(factory)
unsigned int font_size)
: _core_factory(factory)
{ {
_button_text = _core_factory->getText(kku::Font::Id::GUI); _button_text = _core_factory->getText(kku::Font::Id::GUI);
_button_text->setString(text); _button_text->setString(text);
@ -12,7 +10,7 @@ Button::Button(const std::string &text,
_button_text->setCharacterSize(font_size); _button_text->setCharacterSize(font_size);
} }
void Button::update(const kku::microsec &dt) void Button::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -28,13 +26,14 @@ void Button::display() const
Widget::display(); Widget::display();
} }
void Button::setRect(const kku::Area<float> &rect) void Button::setRect(const kku::Area<float>& rect)
{ {
_button_content->setRect(rect); _button_content->setRect(rect);
_button_text->setPosition(kku::Point{rect.left + 5, rect.top + 5}); _button_text->setPosition(kku::Point{rect.left + 5,
rect.top + 5});
} }
void Button::setPosition(const kku::Point &position) void Button::setPosition(const kku::Point& position)
{ {
_button_content->setPosition(position); _button_content->setPosition(position);
@ -43,19 +42,19 @@ void Button::setPosition(const kku::Point &position)
_button_text->setPosition(new_point); _button_text->setPosition(new_point);
} }
void Button::move(const kku::Vector2<float> &delta) void Button::move(const kku::Vector2<float>& delta)
{ {
_button_content->move(delta); _button_content->move(delta);
_button_text->move(delta); _button_text->move(delta);
Widget::move(delta); Widget::move(delta);
} }
bool Button::isUnderMouse(const kku::Point &position) const bool Button::isUnderMouse(const kku::Point& position) const
{ {
return _is_visible && _button_content->contains(position); return _is_visible && _button_content->contains(position);
} }
void Button::setText(const std::string &text) void Button::setText(const std::string& text)
{ {
_button_text->setString(text); _button_text->setString(text);
} }

View File

@ -1,10 +1,8 @@
#include "cascademenubutton.h" #include "cascademenubutton.h"
#include "menudrop.h" #include "menudrop.h"
CascadeMenuButton::CascadeMenuButton( CascadeMenuButton::CascadeMenuButton(const std::string& text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
const std::string &text, const std::shared_ptr<kku::CoreFactory> &factory, Button(text, factory, font_size)
unsigned int font_size)
: Button(text, factory, font_size)
{ {
_color_idle = kku::Color{230, 230, 230, 255}; _color_idle = kku::Color{230, 230, 230, 255};
_color_hover = kku::Color{84, 158, 253, 255}; _color_hover = kku::Color{84, 158, 253, 255};
@ -13,7 +11,7 @@ CascadeMenuButton::CascadeMenuButton(
_button_content->setColor(_color_idle); _button_content->setColor(_color_idle);
} }
void CascadeMenuButton::input(const kku::SystemEvent &event) void CascadeMenuButton::input(const kku::SystemEvent& event)
{ {
if (!_submenu) if (!_submenu)
return; return;
@ -25,8 +23,7 @@ void CascadeMenuButton::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MouseMove: case kku::SystemEvent::Type::MouseMove:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (isUnderMouse(position)) if (isUnderMouse(position))
{ {
_button_content->setColor(_color_hover); _button_content->setColor(_color_hover);
@ -43,16 +40,17 @@ void CascadeMenuButton::input(const kku::SystemEvent &event)
} }
break; break;
} }
} }
} }
void CascadeMenuButton::setRect(const kku::Area<float> &rect) void CascadeMenuButton::setRect(const kku::Area<float>& rect)
{ {
Button::setRect(rect); Button::setRect(rect);
resetRect(); resetRect();
} }
void CascadeMenuButton::setSubmenu(const std::shared_ptr<MenuDrop> &submenu) void CascadeMenuButton::setSubmenu(const std::shared_ptr<MenuDrop>& submenu)
{ {
_submenu = submenu; _submenu = submenu;
resetRect(); resetRect();
@ -67,14 +65,12 @@ void CascadeMenuButton::resetRect()
{ {
if (_submenu) if (_submenu)
{ {
_submenu->setPosition(kku::Point{_button_content->getPosition().x + _submenu->setPosition(kku::Point{_button_content->getPosition().x + _button_content->getRect().width,
_button_content->getRect().width,
_button_content->getPosition().y}); _button_content->getPosition().y});
} }
} }
void CascadeMenuButton::setFillColors(kku::Color &&idle_color, void CascadeMenuButton::setFillColors(kku::Color&& idle_color, kku::Color&& hover_color)
kku::Color &&hover_color)
{ {
_color_idle = idle_color; _color_idle = idle_color;
_color_hover = hover_color; _color_hover = hover_color;

View File

@ -1,19 +1,18 @@
#include "editorwidget.h" #include "editorwidget.h"
#include "core/editor.h" #include "core/editor.h"
EditorWidget::EditorWidget(Callbacks &&callbacks) EditorWidget::EditorWidget(Callbacks&& callbacks) :
: _input(std::move(callbacks.onInput)), _input(std::move(callbacks.onInput)),
_update(std::move(callbacks.onUpdate)), _update(std::move(callbacks.onUpdate)),
_draw(std::move(callbacks.onDisplay)) _draw(std::move(callbacks.onDisplay))
{ {}
}
void EditorWidget::input(const kku::SystemEvent &event) void EditorWidget::input(const kku::SystemEvent& event)
{ {
_input(event); _input(event);
} }
void EditorWidget::update(const kku::microsec &dt) void EditorWidget::update(const kku::microsec& dt)
{ {
_update(dt); _update(dt);
} }
@ -23,18 +22,18 @@ void EditorWidget::display() const
_draw(); _draw();
} }
void EditorWidget::move(const kku::Vector2<float> &delta) void EditorWidget::move(const kku::Vector2<float>& delta)
{ {
(void)delta; (void)delta;
// delegate to children // delegate to children
} }
bool EditorWidget::isUnderMouse(const kku::Point &position) const bool EditorWidget::isUnderMouse(const kku::Point& position) const
{ {
return _parent->isUnderMouse(position); return _parent->isUnderMouse(position);
} }
void EditorWidget::setRect(const kku::Area<float> &rect) void EditorWidget::setRect(const kku::Area<float>& rect)
{ {
(void)rect; (void)rect;
// basically useless beacuse editor widget fills the entire screen // basically useless beacuse editor widget fills the entire screen
@ -45,7 +44,7 @@ kku::Area<float> EditorWidget::getRect() const
return {}; return {};
} }
void EditorWidget::setPosition(const kku::Point &position) void EditorWidget::setPosition(const kku::Point& position)
{ {
(void)position; (void)position;
} }

View File

@ -1,11 +1,11 @@
#include "group.h" #include "group.h"
void Group::input(const kku::SystemEvent &event) void Group::input(const kku::SystemEvent& event)
{ {
Widget::input(event); Widget::input(event);
} }
void Group::update(const kku::microsec &dt) void Group::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -15,18 +15,18 @@ void Group::display() const
Widget::display(); Widget::display();
} }
void Group::setRect(const kku::Area<float> &rect) void Group::setRect(const kku::Area<float>& rect)
{ {
_rect = rect; _rect = rect;
} }
void Group::setPosition(const kku::Point &position) void Group::setPosition(const kku::Point& position)
{ {
_rect.top = position.y; _rect.top = position.y;
_rect.left = position.x; _rect.left = position.x;
} }
void Group::move(const kku::Vector2<float> &delta) void Group::move(const kku::Vector2<float>& delta)
{ {
_rect.top += delta.first; _rect.top += delta.first;
_rect.left += delta.second; _rect.left += delta.second;
@ -34,7 +34,7 @@ void Group::move(const kku::Vector2<float> &delta)
Widget::move(delta); Widget::move(delta);
} }
bool Group::isUnderMouse(const kku::Point &position) const bool Group::isUnderMouse(const kku::Point& position) const
{ {
return _rect.contains(position); return _rect.contains(position);
} }
@ -46,5 +46,10 @@ kku::Area<float> Group::getRect() const
kku::Point Group::getPosition() const kku::Point Group::getPosition() const
{ {
return kku::Point{_rect.top, _rect.left}; return kku::Point
{
_rect.top,
_rect.left
};
} }

View File

@ -1,8 +1,10 @@
#include "menubar.h" #include "menubar.h"
MenuBar::MenuBar(const std::shared_ptr<kku::CoreFactory> &factory) MenuBar::MenuBar(const std::shared_ptr<kku::CoreFactory>& factory) :
: _core_factory(factory), _bar_rect(factory->getRectangle()), _core_factory(factory),
_amount_buttons(0), _button_width(170) _bar_rect(factory->getRectangle()),
_amount_buttons(0),
_button_width(170)
{ {
_bar_rect->setColor(kku::Color{88, 57, 107, 255}); _bar_rect->setColor(kku::Color{88, 57, 107, 255});
} }
@ -16,11 +18,10 @@ void MenuBar::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MouseRelease: case kku::SystemEvent::Type::MouseRelease:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (!isUnderMouse(position)) if (!isUnderMouse(position))
{ {
for (auto &submenu : _submenus) for (auto& submenu : _submenus)
submenu->unlock(); submenu->unlock();
} }
break; break;
@ -30,7 +31,7 @@ void MenuBar::input(const kku::SystemEvent &event)
Widget::input(event); Widget::input(event);
} }
void MenuBar::update(const kku::microsec &dt) void MenuBar::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -43,57 +44,57 @@ void MenuBar::display() const
Widget::display(); Widget::display();
} }
void MenuBar::setRect(const kku::Area<float> &rect) void MenuBar::setRect(const kku::Area<float>& rect)
{ {
_bar_rect->setRect(rect); _bar_rect->setRect(rect);
// Buttons will not resize // Buttons will not resize
} }
void MenuBar::setPosition(const kku::Point &position) void MenuBar::setPosition(const kku::Point& position)
{ {
_bar_rect->setPosition(position); _bar_rect->setPosition(position);
} }
void MenuBar::move(const kku::Vector2<float> &delta) void MenuBar::move(const kku::Vector2<float>& delta)
{ {
_bar_rect->move(delta); _bar_rect->move(delta);
Widget::move(delta); Widget::move(delta);
for (auto &menu : _submenus) for (auto& menu : _submenus)
menu->move(delta); menu->move(delta);
} }
bool MenuBar::isUnderMouse(const kku::Point &position) const bool MenuBar::isUnderMouse(const kku::Point& position) const
{ {
bool bar_under_mouse = _bar_rect->contains(position); bool bar_under_mouse = _bar_rect->contains(position);
bool submenus_under_mouse = std::any_of(_children.begin(), _children.end(), bool submenus_under_mouse = std::any_of(_children.begin(), _children.end(),
[p = position](const auto &child) [p=position](const auto& child)
{ return child->isUnderMouse(p); }); {
return child->isUnderMouse(p);
});
return bar_under_mouse || submenus_under_mouse; return bar_under_mouse || submenus_under_mouse;
} }
void MenuBar::addRootSubMenu(std::string name, void MenuBar::addRootSubMenu(std::string name, const std::shared_ptr<MenuDrop>& submenu)
const std::shared_ptr<MenuDrop> &submenu)
{ {
const auto new_button = std::make_shared<PushButton>(name, _core_factory); const auto new_button = std::make_shared<PushButton>(name, _core_factory);
std::size_t current_index = _amount_buttons; std::size_t current_index = _amount_buttons;
new_button->setRect(kku::Area<float>{ new_button->setRect(kku::Area<float>{static_cast<float>(current_index * _button_width),
static_cast<float>(current_index * _button_width), 0.f, 0.f,
static_cast<float>(_button_width), _bar_rect->getRect().height}); static_cast<float>(_button_width),
new_button->setCallback( _bar_rect->getRect().height});
[submenu = submenu]() new_button->setCallback([submenu=submenu]()
{ {
submenu->setVisibility(true); submenu->setVisibility(true);
submenu->lock(); submenu->lock();
}); });
submenu->setPosition( submenu->setPosition(kku::Point{static_cast<float>(current_index * _button_width),
kku::Point{static_cast<float>(current_index * _button_width),
_bar_rect->getRect().height}); _bar_rect->getRect().height});
new_button->setColors(kku::Color{171, 141, 189, 255}, new_button->setColors(kku::Color{171, 141, 189, 255},
@ -115,7 +116,7 @@ void MenuBar::setVisibility(bool is_visible)
{ {
Widget::setVisibility(is_visible); Widget::setVisibility(is_visible);
for (auto &submenu : _submenus) for (auto& submenu : _submenus)
submenu->setVisibility(false); submenu->setVisibility(false);
} }

View File

@ -1,15 +1,17 @@
#include "menudrop.h" #include "menudrop.h"
#include "core/corefactory.h" #include "core/corefactory.h"
MenuDrop::MenuDrop(const std::shared_ptr<kku::CoreFactory> &factory) MenuDrop::MenuDrop(const std::shared_ptr<kku::CoreFactory>& factory) :
: _is_locked(false), _button_height(27), _button_index(0) _is_locked(false),
_button_height(27),
_button_index(0)
{ {
_is_visible = false; _is_visible = false;
_content_rect = factory->getRectangle(); _content_rect = factory->getRectangle();
_content_rect->setColor(kku::Color{200, 200, 200, 255}); _content_rect->setColor(kku::Color{200, 200, 200, 255});
} }
void MenuDrop::input(const kku::SystemEvent &event) void MenuDrop::input(const kku::SystemEvent& event)
{ {
if (!_is_visible) if (!_is_visible)
return; return;
@ -23,12 +25,11 @@ void MenuDrop::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MouseRelease: case kku::SystemEvent::Type::MouseRelease:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (isUnderMouse(position)) if (isUnderMouse(position))
{ {
setVisibility(false); setVisibility(false);
for (auto &submenu : _submenus) for (auto& submenu : _submenus)
{ {
submenu->unlock(); submenu->unlock();
submenu->setVisibility(false); submenu->setVisibility(false);
@ -39,8 +40,7 @@ void MenuDrop::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MouseMove: case kku::SystemEvent::Type::MouseMove:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (!isUnderMouse(position)) if (!isUnderMouse(position))
{ {
if (!isLocked() && !hasActiveSubmenus()) if (!isLocked() && !hasActiveSubmenus())
@ -54,11 +54,13 @@ void MenuDrop::input(const kku::SystemEvent &event)
bool MenuDrop::hasActiveSubmenus() const bool MenuDrop::hasActiveSubmenus() const
{ {
return std::any_of(_submenus.begin(), _submenus.end(), return std::any_of(_submenus.begin(), _submenus.end(),
[](const auto &submenu) -> bool [](const auto& submenu) -> bool
{ return submenu->_is_visible; }); {
return submenu->_is_visible;
});
} }
void MenuDrop::update(const kku::microsec &dt) void MenuDrop::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -71,27 +73,27 @@ void MenuDrop::display() const
Widget::display(); Widget::display();
} }
void MenuDrop::setRect(const kku::Area<float> &rect) void MenuDrop::setRect(const kku::Area<float>& rect)
{ {
_content_rect->setRect(rect); _content_rect->setRect(rect);
} }
void MenuDrop::setPosition(const kku::Point &position) void MenuDrop::setPosition(const kku::Point& position)
{ {
_content_rect->setPosition(position); _content_rect->setPosition(position);
} }
void MenuDrop::move(const kku::Vector2<float> &delta) void MenuDrop::move(const kku::Vector2<float>& delta)
{ {
_content_rect->move(delta); _content_rect->move(delta);
Widget::move(delta); Widget::move(delta);
for (auto &submenu : _submenus) for (auto& submenu : _submenus)
submenu->move(delta); submenu->move(delta);
} }
bool MenuDrop::isUnderMouse(const kku::Point &position) const bool MenuDrop::isUnderMouse(const kku::Point& position) const
{ {
return _is_visible && _content_rect->contains(position); return _is_visible && _content_rect->contains(position);
} }
@ -104,34 +106,33 @@ void MenuDrop::setVisibility(bool is_visible)
_is_locked = false; _is_locked = false;
} }
void MenuDrop::addPushButton(const std::shared_ptr<PushButton> &button) void MenuDrop::addPushButton(const std::shared_ptr<PushButton>& button)
{ {
add(button); add(button);
} }
void MenuDrop::addCascadeButton( void MenuDrop::addCascadeButton(const std::shared_ptr<CascadeMenuButton>& button)
const std::shared_ptr<CascadeMenuButton> &button)
{ {
auto &submenu = button->submenu(); auto& submenu = button->submenu();
_submenus.emplace_back(submenu); _submenus.emplace_back(submenu);
add(button); add(button);
submenu->setParent(_parent); submenu->setParent(_parent);
} }
void MenuDrop::addSeparator(const std::shared_ptr<MenuSeparator> &separator) void MenuDrop::addSeparator(const std::shared_ptr<MenuSeparator>& separator)
{ {
add(separator); add(separator);
} }
void MenuDrop::add(const std::shared_ptr<Widget> &widget) void MenuDrop::add(const std::shared_ptr<Widget> &widget)
{ {
const auto &parent_rect = _content_rect->getRect(); const auto& parent_rect = _content_rect->getRect();
widget->setRect(kku::Area<float>{ widget->setRect(kku::Area<float>{parent_rect.left,
parent_rect.left,
parent_rect.top + (parent_rect.height * _button_index), parent_rect.top + (parent_rect.height * _button_index),
parent_rect.width, static_cast<float>(_button_height)}); parent_rect.width,
static_cast<float>(_button_height)});
addChild(widget); addChild(widget);
++_button_index; ++_button_index;

View File

@ -1,11 +1,11 @@
#include "menuseparator.h" #include "menuseparator.h"
void MenuSeparator::input(const kku::SystemEvent &event) void MenuSeparator::input(const kku::SystemEvent& event)
{ {
Widget::input(event); Widget::input(event);
} }
void MenuSeparator::update(const kku::microsec &dt) void MenuSeparator::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -15,24 +15,24 @@ void MenuSeparator::display() const
_line->display(); _line->display();
} }
void MenuSeparator::setRect(const kku::Area<float> &rect) void MenuSeparator::setRect(const kku::Area<float>& rect)
{ {
_rect = rect; _rect = rect;
//_line //_line
} }
void MenuSeparator::setPosition(const kku::Point &position) void MenuSeparator::setPosition(const kku::Point& position)
{ {
(void)position; (void)position;
} }
void MenuSeparator::move(const kku::Vector2<float> &delta) void MenuSeparator::move(const kku::Vector2<float>& delta)
{ {
(void)delta; (void)delta;
} }
bool MenuSeparator::isUnderMouse(const kku::Point &position) const bool MenuSeparator::isUnderMouse(const kku::Point& position) const
{ {
return _is_visible && _rect.contains(position); return _is_visible && _rect.contains(position);
} }

View File

@ -1,9 +1,8 @@
#include "pushbutton.h" #include "pushbutton.h"
PushButton::PushButton(const std::string &text, PushButton::PushButton(const std::string& text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
const std::shared_ptr<kku::CoreFactory> &factory, Button(text, factory, font_size),
unsigned int font_size) _pressed(false)
: Button(text, factory, font_size), _pressed(false)
{ {
_color_idle = kku::Color{230, 230, 230, 255}; _color_idle = kku::Color{230, 230, 230, 255};
_color_pressed = kku::Color{200, 200, 200, 255}; _color_pressed = kku::Color{200, 200, 200, 255};
@ -11,7 +10,7 @@ PushButton::PushButton(const std::string &text,
_button_content->setColor(_color_idle); _button_content->setColor(_color_idle);
} }
void PushButton::input(const kku::SystemEvent &event) void PushButton::input(const kku::SystemEvent& event)
{ {
switch (event.type) switch (event.type)
{ {
@ -20,8 +19,7 @@ void PushButton::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MousePress: case kku::SystemEvent::Type::MousePress:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (isUnderMouse(position)) if (isUnderMouse(position))
{ {
_pressed = true; _pressed = true;
@ -34,8 +32,7 @@ void PushButton::input(const kku::SystemEvent &event)
{ {
if (_pressed) if (_pressed)
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
_button_content->setColor(_color_idle); _button_content->setColor(_color_idle);
_pressed = false; _pressed = false;
if (isUnderMouse(position)) if (isUnderMouse(position))
@ -51,7 +48,7 @@ void PushButton::setCallback(kku::lambda callback)
_on_click_callback = callback; _on_click_callback = callback;
} }
void PushButton::setColors(kku::Color &&idle_color, kku::Color &&pressed_color) void PushButton::setColors(kku::Color&& idle_color, kku::Color&& pressed_color)
{ {
_color_idle = idle_color; _color_idle = idle_color;
_color_pressed = pressed_color; _color_pressed = pressed_color;

View File

@ -7,33 +7,33 @@ void Widget::input(const kku::SystemEvent &event)
_blocker->input(event); _blocker->input(event);
else else
{ {
for (auto &child : _children) for (auto& child : _children)
child->input(event); child->input(event);
} }
} }
void Widget::update(const kku::microsec &dt) void Widget::update(const kku::microsec& dt)
{ {
for (auto &child : _children) for (auto& child : _children)
child->update(dt); child->update(dt);
} }
void Widget::display() const void Widget::display() const
{ {
for (const auto &child : _children) for (const auto& child : _children)
child->display(); child->display();
} }
void Widget::move(const kku::Vector2<float> &delta) void Widget::move(const kku::Vector2<float>& delta)
{ {
for (auto &child : _children) for (auto& child : _children)
child->move(delta); child->move(delta);
} }
void Widget::setVisibility(bool is_visible) void Widget::setVisibility(bool is_visible)
{ {
_is_visible = is_visible; _is_visible = is_visible;
for (auto &child : _children) for (auto& child : _children)
child->setVisibility(_is_visible); child->setVisibility(_is_visible);
} }
@ -42,7 +42,7 @@ bool Widget::isVisible() const
return _is_visible; return _is_visible;
} }
void Widget::addChild(const std::shared_ptr<Widget> &child) void Widget::addChild(const std::shared_ptr<Widget>& child)
{ {
child->setParent(shared_from_this()); child->setParent(shared_from_this());
@ -51,7 +51,7 @@ void Widget::addChild(const std::shared_ptr<Widget> &child)
_children.emplace_back(child); _children.emplace_back(child);
} }
void Widget::setParent(const std::shared_ptr<Widget> &parent) void Widget::setParent(const std::shared_ptr<Widget>& parent)
{ {
if (_parent != parent) if (_parent != parent)
{ {
@ -60,7 +60,7 @@ void Widget::setParent(const std::shared_ptr<Widget> &parent)
} }
} }
void Widget::blockBy(const std::shared_ptr<Widget> &blocker) void Widget::blockBy(const std::shared_ptr<Widget>& blocker)
{ {
_blocker = blocker; _blocker = blocker;
} }

View File

@ -1,8 +1,8 @@
#include "window.h" #include "window.h"
Window::Window(const std::shared_ptr<kku::CoreFactory> &factory, Window::Window(const std::shared_ptr<kku::CoreFactory>& factory, const std::string& title) :
const std::string &title) _core_factory(factory),
: _core_factory(factory), _is_dragging(false) _is_dragging(false)
{ {
_bar_title = _core_factory->getText(kku::Font::Id::GUI); _bar_title = _core_factory->getText(kku::Font::Id::GUI);
_bar_title->setString(title); _bar_title->setString(title);
@ -16,7 +16,7 @@ Window::Window(const std::shared_ptr<kku::CoreFactory> &factory,
_window_content->setColor(kku::Color{188, 157, 207, 255}); _window_content->setColor(kku::Color{188, 157, 207, 255});
} }
void Window::input(const kku::SystemEvent &event) void Window::input(const kku::SystemEvent& event)
{ {
Widget::input(event); Widget::input(event);
@ -27,8 +27,7 @@ void Window::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MousePress: case kku::SystemEvent::Type::MousePress:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (_bar->contains(position)) if (_bar->contains(position))
{ {
_is_dragging = true; _is_dragging = true;
@ -43,8 +42,7 @@ void Window::input(const kku::SystemEvent &event)
case kku::SystemEvent::Type::MouseMove: case kku::SystemEvent::Type::MouseMove:
{ {
const auto position = const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
if (_is_dragging) if (_is_dragging)
{ {
float x_mouse_diff = position.x - _previous_click_position.x; float x_mouse_diff = position.x - _previous_click_position.x;
@ -59,7 +57,7 @@ void Window::input(const kku::SystemEvent &event)
} }
} }
void Window::update(const kku::microsec &dt) void Window::update(const kku::microsec& dt)
{ {
Widget::update(dt); Widget::update(dt);
} }
@ -75,17 +73,18 @@ void Window::display() const
} }
} }
void Window::setRect(const kku::Area<float> &rect) void Window::setRect(const kku::Area<float>& rect)
{ {
_window_content->setRect(rect); _window_content->setRect(rect);
kku::Area<float> bar_rect = {rect.left, rect.top, rect.width, 30}; kku::Area<float> bar_rect = {rect.left, rect.top, rect.width, 30};
_bar->setRect(bar_rect); _bar->setRect(bar_rect);
_bar_title->setPosition(kku::Point{rect.left + 5, rect.top + 5}); _bar_title->setPosition(kku::Point{rect.left + 5,
rect.top + 5});
} }
void Window::setPosition(const kku::Point &position) void Window::setPosition(const kku::Point& position)
{ {
_window_content->setPosition(position); _window_content->setPosition(position);
_bar->setPosition(position); _bar->setPosition(position);
@ -95,7 +94,7 @@ void Window::setPosition(const kku::Point &position)
_bar_title->setPosition(new_position); _bar_title->setPosition(new_position);
} }
void Window::move(const kku::Vector2<float> &delta) void Window::move(const kku::Vector2<float>& delta)
{ {
_window_content->move(delta); _window_content->move(delta);
_bar->move(delta); _bar->move(delta);
@ -104,7 +103,7 @@ void Window::move(const kku::Vector2<float> &delta)
Widget::move(delta); Widget::move(delta);
} }
bool Window::isUnderMouse(const kku::Point &position) const bool Window::isUnderMouse(const kku::Point& position) const
{ {
return _is_visible && _window_content->contains(position); return _is_visible && _window_content->contains(position);
} }
@ -115,7 +114,8 @@ void Window::addBarButton(const std::string &text, kku::lambda callback)
auto b = std::make_shared<PushButton>(text, _core_factory, 20); auto b = std::make_shared<PushButton>(text, _core_factory, 20);
b->setCallback(callback); b->setCallback(callback);
b->setRect({area.left + area.width - 35, area.top, 30, 30}); b->setRect({area.left + area.width - 35,
area.top, 30, 30});
Widget::addChild(b); Widget::addChild(b);
} }

View File

@ -1,13 +1,13 @@
#include "applicationsfml.h" #include "applicationsfml.h"
#include "sfml/application/inputconvertersfml.h"
#include "sfml/corefactorysfml.h" #include "sfml/corefactorysfml.h"
#include "sfml/application/inputconvertersfml.h"
#include <SFML/System/Clock.hpp> #include <SFML/System/Clock.hpp>
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f); const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f);
ApplicationSFML::ApplicationSFML(sf::RenderWindow *const render_window) ApplicationSFML::ApplicationSFML(sf::RenderWindow * const render_window) :
: _render_window(render_window) _render_window(render_window)
{ {
_render_window->setFramerateLimit(60); _render_window->setFramerateLimit(60);
_render_window->setKeyRepeatEnabled(false); _render_window->setKeyRepeatEnabled(false);
@ -21,7 +21,7 @@ void ApplicationSFML::display()
{ {
_render_window->clear(); _render_window->clear();
for (const auto &state : _state_stack) for (const auto& state : _state_stack)
state->display(); state->display();
_render_window->display(); _render_window->display();
@ -39,7 +39,7 @@ void ApplicationSFML::run()
sf::Event event; sf::Event event;
while (_render_window->pollEvent(event)) while (_render_window->pollEvent(event))
{ {
switch (event.type) switch(event.type)
{ {
case sf::Event::Closed: case sf::Event::Closed:
_render_window->close(); _render_window->close();

View File

@ -7,11 +7,11 @@
class ApplicationSFML : public Application class ApplicationSFML : public Application
{ {
public: public:
explicit ApplicationSFML(sf::RenderWindow *const _render_window); explicit ApplicationSFML(sf::RenderWindow * const _render_window);
virtual void display() override; virtual void display() override;
virtual void run() override; virtual void run() override;
private: private:
sf::RenderWindow *const _render_window; sf::RenderWindow * const _render_window;
}; };

View File

@ -11,7 +11,7 @@ constexpr kku::SystemEvent::Key::Code convert(sf::Keyboard::Key key) noexcept
return kku::SystemEvent::Key::Code{int(key)}; return kku::SystemEvent::Key::Code{int(key)};
} }
constexpr kku::SystemEvent convert(const sf::Event &event) noexcept constexpr kku::SystemEvent convert(const sf::Event& event) noexcept
{ {
switch (event.type) switch (event.type)
{ {
@ -19,64 +19,120 @@ constexpr kku::SystemEvent convert(const sf::Event &event) noexcept
break; break;
case sf::Event::Resized: case sf::Event::Resized:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::Resize, kku::SystemEvent::Type::Resize,
kku::SystemEvent::Size{event.size.width, event.size.height}}; kku::SystemEvent::Size
{
event.size.width,
event.size.height
}
};
case sf::Event::KeyPressed: case sf::Event::KeyPressed:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::KeyPress, kku::SystemEvent::Type::KeyPress,
kku::SystemEvent::Key{kku::convert(event.key.code), event.key.alt, kku::SystemEvent::Key
event.key.control, event.key.shift}}; {
kku::convert(event.key.code),
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::KeyReleased: case sf::Event::KeyReleased:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::KeyRelease, kku::SystemEvent::Type::KeyRelease,
kku::SystemEvent::Key{kku::convert(event.key.code), event.key.alt, kku::SystemEvent::Key
event.key.control, event.key.shift}}; {
kku::convert(event.key.code),
event.key.alt,
event.key.control,
event.key.shift
}
};
case sf::Event::MouseWheelScrolled: case sf::Event::MouseWheelScrolled:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::MouseWheelScroll, kku::SystemEvent::Type::MouseWheelScroll,
kku::SystemEvent::Mouse{ kku::SystemEvent::Mouse
kku::Point{event.mouseWheelScroll.x, event.mouseWheelScroll.y}, {
kku::Point
{
event.mouseWheelScroll.x,
event.mouseWheelScroll.y
},
(event.mouseWheelScroll.delta > 0), (event.mouseWheelScroll.delta > 0),
kku::SystemEvent::Mouse::Button::Wheel}}; kku::SystemEvent::Mouse::Button::Wheel
}
};
case sf::Event::MouseMoved: case sf::Event::MouseMoved:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::MouseMove, kku::SystemEvent::Type::MouseMove,
kku::SystemEvent::Mouse{ kku::SystemEvent::Mouse
kku::Point{event.mouseMove.x, event.mouseMove.y}, {
kku::Point
{
event.mouseMove.x,
event.mouseMove.y
},
false, kku::SystemEvent::Mouse::Button::None}}; false,
kku::SystemEvent::Mouse::Button::None
}
};
case sf::Event::MouseButtonPressed: case sf::Event::MouseButtonPressed:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::MousePress, kku::SystemEvent::Type::MousePress,
kku::SystemEvent::Mouse{ kku::SystemEvent::Mouse
kku::Point{event.mouseButton.x, event.mouseButton.y}, {
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false, false,
((event.mouseButton.button == sf::Mouse::Button::Left) ((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left ? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)}}; : kku::SystemEvent::Mouse::Button::Right)
}
};
case sf::Event::MouseButtonReleased: case sf::Event::MouseButtonReleased:
return kku::SystemEvent{ return kku::SystemEvent
{
kku::SystemEvent::Type::MouseRelease, kku::SystemEvent::Type::MouseRelease,
kku::SystemEvent::Mouse{ kku::SystemEvent::Mouse
kku::Point{event.mouseButton.x, event.mouseButton.y}, {
kku::Point
{
event.mouseButton.x,
event.mouseButton.y
},
false, false,
((event.mouseButton.button == sf::Mouse::Button::Left) ((event.mouseButton.button == sf::Mouse::Button::Left)
? kku::SystemEvent::Mouse::Button::Left ? kku::SystemEvent::Mouse::Button::Left
: kku::SystemEvent::Mouse::Button::Right)}}; : kku::SystemEvent::Mouse::Button::Right)
}
};
} }
return kku::SystemEvent{kku::SystemEvent::Type::None, return kku::SystemEvent
kku::SystemEvent::None{}}; {
kku::SystemEvent::Type::None,
kku::SystemEvent::None{}
};
} }
} // namespace kku }

View File

@ -1,13 +1,13 @@
#include "corefactorysfml.h" #include "corefactorysfml.h"
#include "linesfml.h"
#include "musicsfml.h"
#include "rectanglesfml.h" #include "rectanglesfml.h"
#include "spritesfml.h" #include "musicsfml.h"
#include "textsfml.h" #include "textsfml.h"
#include "linesfml.h"
#include "spritesfml.h"
CoreFactorySFML::CoreFactorySFML(sf::RenderTarget *const render_target) CoreFactorySFML::CoreFactorySFML(sf::RenderTarget * const render_target) :
: _render_target(render_target) _render_target(render_target)
{ {
auto gui_font = std::make_unique<sf::Font>(); auto gui_font = std::make_unique<sf::Font>();
gui_font->loadFromFile("resources/SourceCodePro-Regular.ttf"); gui_font->loadFromFile("resources/SourceCodePro-Regular.ttf");
@ -33,14 +33,13 @@ std::shared_ptr<kku::Rectangle> CoreFactorySFML::getRectangle() const
return std::make_unique<RectangleSFML>(_render_target); return std::make_unique<RectangleSFML>(_render_target);
} }
std::shared_ptr<kku::Line> CoreFactorySFML::getLine() const std::shared_ptr<kku::Line> CoreFactorySFML::getLine() const
{ {
return std::make_unique<LineSFML>(_render_target); return std::make_unique<LineSFML>(_render_target);
} }
std::shared_ptr<kku::Sprite> std::shared_ptr<kku::Sprite> CoreFactorySFML::getSprite(kku::GUISprite::Id id) const
CoreFactorySFML::getSprite(kku::GUISprite::Id id) const {
{
const auto texture = _texture_holder.get(kku::Texture::Id::GUI); const auto texture = _texture_holder.get(kku::Texture::Id::GUI);
switch (id) switch (id)
{ {
@ -49,18 +48,16 @@ CoreFactorySFML::getSprite(kku::GUISprite::Id id) const
break; break;
case kku::GUISprite::Id::SFML_LOGO: case kku::GUISprite::Id::SFML_LOGO:
return std::make_unique<SpriteSFML>( return std::make_unique<SpriteSFML>(_render_target, _texture_holder.get(kku::Texture::Id::GUI),
_render_target, _texture_holder.get(kku::Texture::Id::GUI),
kku::Area<unsigned int>{0, 0, 252, 81}); kku::Area<unsigned int>{0, 0, 252, 81});
break; break;
case kku::GUISprite::Id::CRYPTOPP_LOGO: case kku::GUISprite::Id::CRYPTOPP_LOGO:
return std::make_unique<SpriteSFML>( return std::make_unique<SpriteSFML>(_render_target, _texture_holder.get(kku::Texture::Id::GUI),
_render_target, _texture_holder.get(kku::Texture::Id::GUI),
kku::Area<unsigned int>{252, 0, 135, 36}); kku::Area<unsigned int>{252, 0, 135, 36});
break; break;
} }
} }
kku::Vector2<std::size_t> CoreFactorySFML::getRenderSize() const kku::Vector2<std::size_t> CoreFactorySFML::getRenderSize() const
{ {

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/RectangleShape.hpp> #include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/RenderTarget.hpp> #include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Texture.hpp> #include <SFML/Graphics/Texture.hpp>
@ -10,18 +10,17 @@
class CoreFactorySFML : public kku::CoreFactory class CoreFactorySFML : public kku::CoreFactory
{ {
public: public:
explicit CoreFactorySFML(sf::RenderTarget *const render_target); explicit CoreFactorySFML(sf::RenderTarget * const render_target);
virtual std::shared_ptr<kku::Music> getMusic() const override; virtual std::shared_ptr<kku::Music> getMusic() const override;
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const override; virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const override;
virtual std::shared_ptr<kku::Rectangle> getRectangle() const override; virtual std::shared_ptr<kku::Rectangle> getRectangle() const override;
virtual std::shared_ptr<kku::Line> getLine() const override; virtual std::shared_ptr<kku::Line> getLine() const override;
virtual std::shared_ptr<kku::Sprite> virtual std::shared_ptr<kku::Sprite> getSprite(kku::GUISprite::Id id) const override;
getSprite(kku::GUISprite::Id id) const override;
virtual kku::Vector2<std::size_t> getRenderSize() const override; virtual kku::Vector2<std::size_t> getRenderSize() const override;
private: private:
sf::RenderTarget *const _render_target; sf::RenderTarget * const _render_target;
kku::ResourceHolder<sf::Font, kku::Font::Id> _font_holder; kku::ResourceHolder<sf::Font, kku::Font::Id> _font_holder;
kku::ResourceHolder<sf::Texture, kku::Texture::Id> _texture_holder; kku::ResourceHolder<sf::Texture, kku::Texture::Id> _texture_holder;
}; };

View File

@ -1,18 +1,18 @@
#include "linesfml.h" #include "linesfml.h"
LineSFML::LineSFML(sf::RenderTarget *const render_target) LineSFML::LineSFML(sf::RenderTarget * const render_target) :
: _render_target(render_target) _render_target(render_target)
{ {
_vertex = sf::VertexArray(sf::LinesStrip, 2); _vertex = sf::VertexArray(sf::LinesStrip, 2);
} }
void LineSFML::setPosition(const kku::Point &p1, const kku::Point &p2) void LineSFML::setPosition(const kku::Point& p1, const kku::Point& p2)
{ {
_vertex[0].position = {p1.x, p1.y}; _vertex[0].position = {p1.x, p1.y};
_vertex[1].position = {p2.x, p2.y}; _vertex[1].position = {p2.x, p2.y};
} }
void LineSFML::setColor(const kku::Color &c1, const kku::Color &c2) void LineSFML::setColor(const kku::Color& c1, const kku::Color& c2)
{ {
_vertex[0].color = sf::Color{c1.red, c1.green, c1.blue, c1.alpha}; _vertex[0].color = sf::Color{c1.red, c1.green, c1.blue, c1.alpha};
_vertex[1].color = sf::Color{c2.red, c2.green, c2.blue, c2.alpha}; _vertex[1].color = sf::Color{c2.red, c2.green, c2.blue, c2.alpha};

View File

@ -8,14 +8,13 @@
class LineSFML : public kku::Line class LineSFML : public kku::Line
{ {
public: public:
explicit LineSFML(sf::RenderTarget *const render_target); explicit LineSFML(sf::RenderTarget * const render_target);
virtual void setPosition(const kku::Point &p1, virtual void setPosition(const kku::Point& p1, const kku::Point& p2) override;
const kku::Point &p2) override; virtual void setColor(const kku::Color& c1, const kku::Color& c2) override;
virtual void setColor(const kku::Color &c1, const kku::Color &c2) override;
virtual void display() override; virtual void display() override;
private: private:
sf::RenderTarget *const _render_target; sf::RenderTarget * const _render_target;
sf::VertexArray _vertex; sf::VertexArray _vertex;
}; };

View File

@ -1,11 +1,12 @@
#include "musicsfml.h" #include "musicsfml.h"
MusicSFML::MusicSFML() MusicSFML::MusicSFML() :
: _sfml_music_offset(0), _previous_frame_offset(0), _absolute_offset(0) _sfml_music_offset(0),
{ _previous_frame_offset(0),
} _absolute_offset(0)
{}
bool MusicSFML::open(const std::string &filepath) bool MusicSFML::open(const std::string& filepath)
{ {
return _music.openFromFile(filepath); return _music.openFromFile(filepath);
} }
@ -36,7 +37,7 @@ void MusicSFML::setVolume(float volume)
_music.setVolume(volume); _music.setVolume(volume);
} }
void MusicSFML::setOffset(const kku::microsec &offset) void MusicSFML::setOffset(const kku::microsec& offset)
{ {
//_previous_frame_offset += (offset - _absolute_offset); //_previous_frame_offset += (offset - _absolute_offset);
_music.setPlayingOffset(sf::microseconds(offset)); _music.setPlayingOffset(sf::microseconds(offset));
@ -47,8 +48,7 @@ kku::microsec MusicSFML::fetchOffset()
if (_music.getStatus() != sf::Music::Status::Playing) if (_music.getStatus() != sf::Music::Status::Playing)
return _absolute_offset; return _absolute_offset;
const auto interpolator_timestamp = const auto interpolator_timestamp = _offset_interpolator.getElapsedTime().asMicroseconds();
_offset_interpolator.getElapsedTime().asMicroseconds();
const auto sfml_new_offset = _music.getPlayingOffset().asMicroseconds(); const auto sfml_new_offset = _music.getPlayingOffset().asMicroseconds();
_absolute_offset += (interpolator_timestamp - _previous_frame_offset); _absolute_offset += (interpolator_timestamp - _previous_frame_offset);
@ -62,7 +62,7 @@ kku::microsec MusicSFML::fetchOffset()
return _absolute_offset; return _absolute_offset;
} }
void MusicSFML::moveOffset(const kku::microsec &delta) void MusicSFML::moveOffset(const kku::microsec& delta)
{ {
const auto offset = fetchOffset(); const auto offset = fetchOffset();
const auto result = offset + delta; const auto result = offset + delta;
@ -86,3 +86,4 @@ kku::microsec MusicSFML::getDuration() const
{ {
return _music.getDuration().asMicroseconds(); return _music.getDuration().asMicroseconds();
} }

View File

@ -7,9 +7,9 @@
class MusicSFML : public kku::Music class MusicSFML : public kku::Music
{ {
public: public:
explicit MusicSFML(); explicit MusicSFML();
virtual bool open(const std::string &filepath) override; virtual bool open(const std::string& filepath) override;
virtual void play() override; virtual void play() override;
virtual void pause() override; virtual void pause() override;
@ -19,13 +19,13 @@ class MusicSFML : public kku::Music
virtual void setVolume(float volume) override; virtual void setVolume(float volume) override;
virtual void setOffset(const kku::microsec &offset) override; virtual void setOffset(const kku::microsec& offset) override;
virtual void moveOffset(const kku::microsec &delta) override; virtual void moveOffset(const kku::microsec& delta) override;
virtual kku::microsec fetchOffset() override; virtual kku::microsec fetchOffset() override;
virtual kku::microsec getDuration() const override; virtual kku::microsec getDuration() const override;
private: private:
sf::Music _music; sf::Music _music;
sf::Clock _offset_interpolator; sf::Clock _offset_interpolator;

View File

@ -1,11 +1,10 @@
#include "rectanglesfml.h" #include "rectanglesfml.h"
RectangleSFML::RectangleSFML(sf::RenderTarget *const render_target) RectangleSFML::RectangleSFML(sf::RenderTarget * const render_target) :
: _render_target(render_target) _render_target(render_target)
{ {}
}
void RectangleSFML::setRect(const kku::Area<float> &rect) void RectangleSFML::setRect(const kku::Area<float>& rect)
{ {
_rectangle.setPosition(rect.left, rect.top); _rectangle.setPosition(rect.left, rect.top);
_rectangle.setSize({rect.width, rect.height}); _rectangle.setSize({rect.width, rect.height});
@ -19,12 +18,12 @@ kku::Area<float> RectangleSFML::getRect() const
return kku::Area<float>{position.x, position.y, size.x, size.y}; return kku::Area<float>{position.x, position.y, size.x, size.y};
} }
void RectangleSFML::move(const kku::Vector2<float> &delta) void RectangleSFML::move(const kku::Vector2<float>& delta)
{ {
_rectangle.move({delta.first, delta.second}); _rectangle.move({delta.first, delta.second});
} }
void RectangleSFML::setPosition(const kku::Point &position) void RectangleSFML::setPosition(const kku::Point& position)
{ {
_rectangle.setPosition({position.x, position.y}); _rectangle.setPosition({position.x, position.y});
} }
@ -35,10 +34,10 @@ kku::Point RectangleSFML::getPosition() const
return kku::Point{position.x, position.y}; return kku::Point{position.x, position.y};
} }
void RectangleSFML::setColor(const kku::Color &color) void RectangleSFML::setColor(const kku::Color& color)
{ {
_rectangle.setFillColor( _rectangle.setFillColor(sf::Color{color.red, color.green,
sf::Color{color.red, color.green, color.blue, color.alpha}); color.blue, color.alpha});
} }
kku::Color RectangleSFML::getColor() const kku::Color RectangleSFML::getColor() const
@ -47,7 +46,7 @@ kku::Color RectangleSFML::getColor() const
return kku::Color{color.r, color.g, color.b, color.a}; return kku::Color{color.r, color.g, color.b, color.a};
} }
bool RectangleSFML::contains(const kku::Point &position) const bool RectangleSFML::contains(const kku::Point& position) const
{ {
return _rectangle.getGlobalBounds().contains(position.x, position.y); return _rectangle.getGlobalBounds().contains(position.x, position.y);
} }

View File

@ -1,29 +1,29 @@
#pragma once #pragma once
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/RenderTarget.hpp> #include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <memory> #include <memory>
#include "core/rectangle.h" #include "core/rectangle.h"
class RectangleSFML : public kku::Rectangle class RectangleSFML : public kku::Rectangle
{ {
public: public:
explicit RectangleSFML(sf::RenderTarget *const render_target); explicit RectangleSFML(sf::RenderTarget * const render_target);
virtual void setRect(const kku::Area<float> &rect) override; virtual void setRect(const kku::Area<float>& rect) override;
virtual kku::Area<float> getRect() const override; virtual kku::Area<float> getRect() const override;
virtual void setPosition(const kku::Point &position) override; virtual void setPosition(const kku::Point& position) override;
virtual kku::Point getPosition() const override; virtual kku::Point getPosition() const override;
virtual void move(const kku::Vector2<float> &delta) override; virtual void move(const kku::Vector2<float>& delta) override;
virtual void setColor(const kku::Color &color) override; virtual void setColor(const kku::Color& color) override;
virtual kku::Color getColor() const override; virtual kku::Color getColor() const override;
virtual bool contains(const kku::Point &position) const override; virtual bool contains(const kku::Point& position) const override;
virtual void display() override; virtual void display() override;
private: private:
sf::RenderTarget *const _render_target; sf::RenderTarget * const _render_target;
sf::RectangleShape _rectangle; sf::RectangleShape _rectangle;
}; };

View File

@ -1,26 +1,28 @@
#include "spritesfml.h" #include "spritesfml.h"
SpriteSFML::SpriteSFML(sf::RenderTarget *const render_target, SpriteSFML::SpriteSFML(sf::RenderTarget * const render_target,
const std::shared_ptr<sf::Texture> &texture, const std::shared_ptr<sf::Texture>& texture,
const kku::Area<unsigned int> &cropping) const kku::Area<unsigned int> &cropping) :
: _render_target(render_target), _render_target(render_target),
_sprite(*texture, sf::IntRect(cropping.left, cropping.top, cropping.width, _sprite(*texture, sf::IntRect(cropping.left, cropping.top, cropping.width, cropping.height))
cropping.height)) {}
{
}
void SpriteSFML::setPosition(const kku::Point &position) void SpriteSFML::setPosition(const kku::Point& position)
{ {
_sprite.setPosition(position.x, position.y); _sprite.setPosition(position.x, position.y);
} }
kku::Point SpriteSFML::getPosition() const kku::Point SpriteSFML::getPosition() const
{ {
const auto &position = _sprite.getPosition(); const auto& position = _sprite.getPosition();
return kku::Point{position.x, position.y}; return kku::Point
{
position.x,
position.y
};
} }
void SpriteSFML::move(const kku::Vector2<float> &delta) void SpriteSFML::move(const kku::Vector2<float>& delta)
{ {
_sprite.move({delta.first, delta.second}); _sprite.move({delta.first, delta.second});
} }

View File

@ -4,23 +4,22 @@
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include <memory> #include <memory>
#include "core/area.h"
#include "core/sprite.h" #include "core/sprite.h"
class SpriteSFML : public kku::Sprite class SpriteSFML : public kku::Sprite
{ {
public: public:
explicit SpriteSFML(sf::RenderTarget *const render_target, explicit SpriteSFML(sf::RenderTarget * const render_target,
const std::shared_ptr<sf::Texture> &texture, const std::shared_ptr<sf::Texture> &texture,
const kku::Area<unsigned int> &cropping); const kku::Area<unsigned int>& cropping);
virtual void setPosition(const kku::Point &position) override; virtual void setPosition(const kku::Point& position) override;
virtual kku::Point getPosition() const override; virtual kku::Point getPosition() const override;
virtual void move(const kku::Vector2<float> &delta) override; virtual void move(const kku::Vector2<float>& delta) override;
virtual void display() const override; virtual void display() const override;
protected: protected:
sf::RenderTarget *const _render_target; sf::RenderTarget * const _render_target;
sf::Sprite _sprite; sf::Sprite _sprite;
}; };

View File

@ -1,13 +1,13 @@
#include "textsfml.h" #include "textsfml.h"
TextSFML::TextSFML(sf::RenderTarget *const render_target, TextSFML::TextSFML(sf::RenderTarget * const render_target,
const std::shared_ptr<const sf::Font> &font) const std::shared_ptr<const sf::Font>& font) :
: _render_target(render_target) _render_target(render_target)
{ {
_text.setFont(*font); _text.setFont(*font);
} }
void TextSFML::setString(const std::string &string) void TextSFML::setString(const std::string& string)
{ {
_text.setString(string); _text.setString(string);
} }
@ -17,20 +17,19 @@ void TextSFML::setCharacterSize(std::size_t pixels)
_text.setCharacterSize(pixels); _text.setCharacterSize(pixels);
} }
void TextSFML::setPosition(const kku::Point &point) void TextSFML::setPosition(const kku::Point& point)
{ {
_text.setPosition(point.x, point.y); _text.setPosition(point.x, point.y);
} }
void TextSFML::move(const kku::Vector2<float> &delta) void TextSFML::move(const kku::Vector2<float>& delta)
{ {
_text.move({delta.first, delta.second}); _text.move({delta.first, delta.second});
} }
void TextSFML::setColor(const kku::Color &color) void TextSFML::setColor(const kku::Color& color)
{ {
_text.setFillColor( _text.setFillColor(sf::Color{color.red, color.green, color.blue, color.alpha});
sf::Color{color.red, color.green, color.blue, color.alpha});
} }
void TextSFML::display() void TextSFML::display()

View File

@ -1,27 +1,27 @@
#pragma once #pragma once
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/RenderTarget.hpp> #include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/Text.hpp> #include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/Font.hpp>
#include <memory> #include <memory>
#include "core/text.h" #include "core/text.h"
class TextSFML : public kku::Text class TextSFML : public kku::Text
{ {
public: public:
explicit TextSFML(sf::RenderTarget *const render_target, explicit TextSFML(sf::RenderTarget * const render_target,
const std::shared_ptr<const sf::Font> &font); const std::shared_ptr<const sf::Font>& font);
virtual void setString(const std::string &string) override; virtual void setString(const std::string& string) override;
virtual void setCharacterSize(std::size_t pixels) override; virtual void setCharacterSize(std::size_t pixels) override;
virtual void setPosition(const kku::Point &point) override; virtual void setPosition(const kku::Point& point) override;
virtual void move(const kku::Vector2<float> &delta) override; virtual void move(const kku::Vector2<float>& delta) override;
virtual void setColor(const kku::Color &color) override; virtual void setColor(const kku::Color& color) override;
virtual void display() override; virtual void display() override;
protected: protected:
sf::RenderTarget *const _render_target; sf::RenderTarget * const _render_target;
sf::Text _text; sf::Text _text;
}; };

View File

@ -2,9 +2,7 @@
int main() int main()
{ {
sf::RenderWindow window(sf::VideoMode{1280, 720}, "Project Kyoku", sf::RenderWindow window(sf::VideoMode{1280, 720}, "Project Kyoku", sf::Style::Default);
sf::Style::Default);
ApplicationSFML app(&window); ApplicationSFML app(&window);
if (app.init()) if (app.init())
app.run(); app.run();

View File

@ -1,53 +1,44 @@
#include "classicmode/classicfactory.h" #include "classicmode/classicfactory.h"
#include "graphics/classicgraphicsfactory.h"
#include "graphics/classicscenegraphicsmanager.h" #include "graphics/classicscenegraphicsmanager.h"
#include "graphics/classictimelinegraphicsmanager.h" #include "graphics/classictimelinegraphicsmanager.h"
#include "graphics/classicgraphicsfactory.h"
#include "core/timeline.h" #include "core/timeline.h"
#include "editor/classiceditor.h"
#include "editor/editorcontext.h"
#include "editor/selectionmanager.h"
#include "game/classicgame.h" #include "game/classicgame.h"
#include "game/gamecontext.h" #include "game/gamecontext.h"
#include "game/holdmanager.h" #include "game/holdmanager.h"
#include "editor/classiceditor.h"
#include "editor/editorcontext.h"
#include "editor/selectionmanager.h"
std::unique_ptr<kku::Game>
classic::getGame(const std::shared_ptr<kku::CoreFactory> &core_factory) std::unique_ptr<kku::Game> classic::getGame(const std::shared_ptr<kku::CoreFactory>& core_factory)
{ {
const kku::microsec visibility_offset = 1648648; const kku::microsec visibility_offset = 1648648;
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 graphics_manager = std::make_shared<ClassicSceneGraphicsManager>( const auto graphics_manager = std::make_shared<ClassicSceneGraphicsManager>(timeline, factory, visibility_offset);
timeline, factory, visibility_offset);
const auto hold_manager = std::make_shared<HoldManager>(); const auto hold_manager = std::make_shared<HoldManager>();
const auto context = const auto context = std::make_shared<GameContext>(hold_manager, graphics_manager);
std::make_shared<GameContext>(hold_manager, graphics_manager);
return std::make_unique<ClassicGame>(timeline, context); return std::make_unique<ClassicGame>(timeline, context);
} }
std::unique_ptr<kku::Editor> std::unique_ptr<kku::Editor> classic::getEditor(const std::shared_ptr<kku::CoreFactory>& core_factory)
classic::getEditor(const std::shared_ptr<kku::CoreFactory> &core_factory)
{ {
const kku::microsec visibility_offset = 1648648; const kku::microsec visibility_offset = 1648648;
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, visibility_offset));
std::make_shared<ClassicSceneGraphicsManager>(timeline, factory, graphics_managers.emplace_back(std::make_shared<ClassicTimelineGraphicsManager>(timeline, factory, visibility_offset * 2));
visibility_offset));
graphics_managers.emplace_back(
std::make_shared<ClassicTimelineGraphicsManager>(
timeline, factory, visibility_offset * 2));
const auto context = std::make_shared<EditorContext>( const auto context = std::make_shared<EditorContext>(selection_manager, std::move(graphics_managers));
selection_manager, std::move(graphics_managers));
return std::make_unique<ClassicEditor>(timeline, context); return std::make_unique<ClassicEditor>(timeline, context);
} }

View File

@ -1,9 +1,10 @@
#include "classicmode/classicnote.h" #include "classicmode/classicnote.h"
ClassicNote::ClassicNote(const kku::microsec &perfect_offset, int id) ClassicNote::ClassicNote(const kku::microsec& perfect_offset, int id) :
: Note(perfect_offset), _state(State::NONE), _id(id) Note(perfect_offset),
{ _state(State::NONE),
} _id(id)
{}
void ClassicNote::setState(ClassicNote::State state) noexcept void ClassicNote::setState(ClassicNote::State state) noexcept
{ {

View File

@ -1,10 +1,10 @@
#include "callbacksimple.h" #include "callbacksimple.h"
CallbackSimple::CallbackSimple(Init &&init, Metadata &&metadata) CallbackSimple::CallbackSimple(Init&& init, Metadata&& metadata) :
: _run(std::move(init.run)), _is_enabled(std::move(init.is_enabled)), _run(std::move(init.run)),
_is_enabled(std::move(init.is_enabled)),
_metadata(std::move(metadata)) _metadata(std::move(metadata))
{ {}
}
bool CallbackSimple::isEnabled() const bool CallbackSimple::isEnabled() const
{ {

View File

@ -1,35 +1,37 @@
#include "classiceditor.h" #include "classiceditor.h"
#include "editor/selectionmanager.h"
#include "graphics/classicgraphicsmanager.h" #include "graphics/classicgraphicsmanager.h"
#include "editor/selectionmanager.h"
// Replace with interface by dependency injection // Replace with interface by dependency injection
#include "graphics/animations/classicdyinganimationscenario.h"
#include "graphics/animations/classicflyinganimationscenario.h" #include "graphics/animations/classicflyinganimationscenario.h"
#include "graphics/animations/classicdyinganimationscenario.h"
// //
#include "callbacks/callbacksimple.h"
#include "editorcontext.h"
#include "game/classicarrownote.h" #include "game/classicarrownote.h"
#include "editorcontext.h"
#include "callbacks/callbacksimple.h"
ClassicEditor::ClassicEditor( ClassicEditor::ClassicEditor(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline, const std::shared_ptr<EditorContext>& context) :
const std::shared_ptr<EditorContext> &context) _timeline(timeline),
: _timeline(timeline), _context(context), _selected_type(Type::UP), _context(context),
_current_time(0), _scroll_step(500000), _note_id(0) _selected_type(Type::UP),
_current_time(0),
_scroll_step(500000),
_note_id(0)
{ {
kku::microsec starting_beat_offset = 402162; kku::microsec starting_beat_offset = 402162;
int amount_of_beats = 209; int amount_of_beats = 209;
kku::microsec interval = 1412162; kku::microsec interval = 1412162;
kku::microsec tempo_interval = interval / 4; kku::microsec tempo_interval = interval / 4;
kku::microsec note_input_offset = 412162 / 2; kku::microsec note_input_offset = 412162 / 2;
// microsec note_input_offset_fast = 412162 / 6; //microsec note_input_offset_fast = 412162 / 6;
kku::microsec bpm_iterator = starting_beat_offset; kku::microsec bpm_iterator = starting_beat_offset;
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats); kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
std::vector<kku::microsec> input_intervals = { std::vector<kku::microsec> input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset}; std::set<ClassicNote*, kku::NotePtrComparator> notes;
std::set<ClassicNote *, kku::NotePtrComparator> notes;
input_intervals.shrink_to_fit(); input_intervals.shrink_to_fit();
bpm_iterator += tempo_interval; bpm_iterator += tempo_interval;
@ -43,6 +45,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};
@ -73,8 +76,15 @@ ClassicEditor::ClassicEditor(
--counter; --counter;
ClassicArrowNote::Init init{_note_id++, context, bpm_iterator, ClassicArrowNote::Init init
input_intervals, {element}, hold}; {
_note_id++,
context,
bpm_iterator,
input_intervals,
{element},
hold
};
notes.insert(new ClassicArrowNote(std::move(init))); notes.insert(new ClassicArrowNote(std::move(init)));
@ -90,20 +100,19 @@ ClassicEditor::ClassicEditor(
kku::microsec ClassicEditor::adjustOffset(kku::microsec offset) const noexcept kku::microsec ClassicEditor::adjustOffset(kku::microsec offset) const noexcept
{ {
const auto &section = getBPMSectionAt(offset); const auto& section = getBPMSectionAt(offset);
const kku::microsec actual_offset = offset - section.offset_start; const kku::microsec actual_offset = offset - section.offset_start;
return actual_offset + (actual_offset % (section.interval + 1)); return actual_offset + (actual_offset % (section.interval + 1));
} }
void ClassicEditor::input(kku::GameEvent &&input) void ClassicEditor::input(kku::GameEvent&& input)
{ {
_current_time = input.timestamp; _current_time = input.timestamp;
const auto &event = input.event; const auto& event = input.event;
switch (input.event.type) switch (input.event.type)
{ {
default: default:
break; break;
@ -130,13 +139,11 @@ void ClassicEditor::input(kku::GameEvent &&input)
case kku::SystemEvent::Type::MousePress: case kku::SystemEvent::Type::MousePress:
{ {
const auto note = _timeline->getNoteBy(_current_time); const auto note = _timeline->getNoteBy(_current_time);
if (_timeline->isExpired(note) && !_bpm_sections.empty() && if (_timeline->isExpired(note) && !_bpm_sections.empty() && _current_time >= (*_bpm_sections.begin()).offset_start)
_current_time >= (*_bpm_sections.begin()).offset_start)
{ {
ArrowElement element; ArrowElement element;
element.position = element.position = std::get<kku::SystemEvent::Mouse>(event.data).position;
std::get<kku::SystemEvent::Mouse>(event.data).position;
element.falling_curve_interpolation = {}; element.falling_curve_interpolation = {};
element.keys = {kku::SystemEvent::Key::Code::W, element.keys = {kku::SystemEvent::Key::Code::W,
@ -144,8 +151,15 @@ void ClassicEditor::input(kku::GameEvent &&input)
element.type = Type::UP; element.type = Type::UP;
ClassicArrowNote::Init init{_note_id++, _context, _current_time, ClassicArrowNote::Init init
{}, {element}, false}; {
_note_id++,
_context,
_current_time,
{},
{element},
false
};
_timeline->insertNote(new ClassicArrowNote(std::move(init))); _timeline->insertNote(new ClassicArrowNote(std::move(init)));
} }
@ -153,8 +167,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;
} }
} }
@ -162,7 +174,7 @@ void ClassicEditor::input(kku::GameEvent &&input)
_context->inputUI(std::move(input)); _context->inputUI(std::move(input));
} }
void ClassicEditor::update(kku::UpdateData &&updatedata) void ClassicEditor::update(kku::UpdateData&& updatedata)
{ {
_timeline->update(updatedata.timestamp); _timeline->update(updatedata.timestamp);
_context->updateGraphics(updatedata.timestamp); _context->updateGraphics(updatedata.timestamp);
@ -173,7 +185,7 @@ void ClassicEditor::display() const
_context->displayGraphics(); _context->displayGraphics();
} }
void ClassicEditor::recalculate(const kku::microsec &timestamp) void ClassicEditor::recalculate(const kku::microsec& timestamp)
{ {
_timeline->recalculate(timestamp); _timeline->recalculate(timestamp);
} }

View File

@ -4,58 +4,41 @@
#include "graphics/classicgraphicsmanager.h" #include "graphics/classicgraphicsmanager.h"
#include "graphics/classicnotegraphics.h" #include "graphics/classicnotegraphics.h"
EditorContext::EditorContext( EditorContext::EditorContext(const std::shared_ptr<SelectionManager>& selection_manager,
const std::shared_ptr<SelectionManager<ClassicNote>> &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))
{ {}
}
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:
{ {
bool selection_changed = false; const auto clicked_position = std::get<kku::SystemEvent::Mouse>(input.event.data).position;
std::size_t amount_selected = 0; for (auto& element : note->getElements())
const auto position =
std::get<kku::SystemEvent::Mouse>(input.event.data).position; for (auto&
element : note->getElements())
{ {
if (element.sprite->getRectangle()->contains(position)) if (element.sprite->getRectangle()->contains(clicked_position))
{ {
element.selected = !element.selected; if (_selection_manager->isSelected(note->getId(), element.id))
selection_changed = true; _selection_manager->remove(note->getId(), element.id);
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;
}*/
} }
} }
void EditorContext::update(ClassicArrowNote *note, void EditorContext::update(ClassicArrowNote *note, const kku::microsec& music_offset) const
const kku::microsec &music_offset) const
{ {
auto &elements = note->getElements(); auto& elements = note->getElements();
switch (note->getState()) switch (note->getState())
{ {
@ -65,18 +48,16 @@ void EditorContext::update(ClassicArrowNote *note,
case ClassicArrowNote::State::INITIAL: case ClassicArrowNote::State::INITIAL:
note->setState(ClassicArrowNote::State::FLYING); note->setState(ClassicArrowNote::State::FLYING);
for (auto &manager : _graphics_managers) for (auto& manager : _graphics_managers)
manager->update(music_offset, note); manager->update(music_offset, note);
break; break;
case ClassicArrowNote::State::FLYING: case ClassicArrowNote::State::FLYING:
if (!note->isActive(music_offset) && if (!note->isActive(music_offset) && music_offset > note->getPerfectOffset())
music_offset > note->getPerfectOffset())
{ {
note->setState(ClassicArrowNote::State::DYING); note->setState(ClassicArrowNote::State::DYING);
for (auto &element : elements) for (auto& element : elements)
element.animations[note->getState()]->launch( element.animations[note->getState()]->launch(element.sprite, music_offset, note->getPerfectOffset());
element.sprite, music_offset, note->getPerfectOffset());
} }
break; break;
@ -84,37 +65,36 @@ void EditorContext::update(ClassicArrowNote *note,
if (elements[0].animations[note->getState()]->isDone()) if (elements[0].animations[note->getState()]->isDone())
{ {
note->setState(ClassicArrowNote::State::DEAD); note->setState(ClassicArrowNote::State::DEAD);
for (auto &manager : _graphics_managers) for (auto& manager : _graphics_managers)
manager->update(music_offset, note); manager->update(music_offset, note);
} }
break; break;
} }
for (auto &element : elements) for (auto& element : elements)
if (element.animations[note->getState()]) if (element.animations[note->getState()])
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;
} }
void EditorContext::inputUI(kku::GameEvent &&input) void EditorContext::inputUI(kku::GameEvent&& input)
{ {
for (auto &manager : _graphics_managers) for (auto& manager : _graphics_managers)
manager->input(std::move(input)); manager->input(std::move(input));
} }
void EditorContext::updateGraphics(const kku::microsec &music_offset) void EditorContext::updateGraphics(const kku::microsec& music_offset)
{ {
for (auto &manager : _graphics_managers) for (auto& manager : _graphics_managers)
manager->update(music_offset); manager->update(music_offset);
} }
void EditorContext::displayGraphics() const void EditorContext::displayGraphics() const
{ {
for (const auto &manager : _graphics_managers) for (const auto& manager : _graphics_managers)
manager->display(); manager->display();
} }

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,53 @@
#pragma once #pragma once
#include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#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 +63,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

@ -2,9 +2,10 @@
#include "classicmode/context.h" #include "classicmode/context.h"
#include "graphics/classicgraphicsmanager.h" #include "graphics/classicgraphicsmanager.h"
ClassicArrowNote::ClassicArrowNote(Init &&init) ClassicArrowNote::ClassicArrowNote(Init&& init) :
: ClassicNote(init.perfect_offset, init.id), ClassicNote(init.perfect_offset, init.id),
_evaluator(init.intervals, init.perfect_offset), _context(init.context), _evaluator(init.intervals, init.perfect_offset),
_context(init.context),
_is_holding(init.is_holding) _is_holding(init.is_holding)
{ {
_elements.resize(init.elements.size()); _elements.resize(init.elements.size());
@ -17,9 +18,10 @@ ClassicArrowNote::ClassicArrowNote(Init &&init)
} }
} }
bool ClassicArrowNote::isActive(const kku::microsec &offset) const bool ClassicArrowNote::isActive(const kku::microsec& offset) const
{ {
return _evaluator.isActive(offset) && _state != State::DYING; return _evaluator.isActive(offset)
&& _state != State::DYING;
} }
void ClassicArrowNote::update(const kku::microsec &music_offset) void ClassicArrowNote::update(const kku::microsec &music_offset)
@ -27,13 +29,12 @@ void ClassicArrowNote::update(const kku::microsec &music_offset)
_context->update(this, music_offset); _context->update(this, music_offset);
} }
void ClassicArrowNote::input(kku::GameEvent &&input) void ClassicArrowNote::input(kku::GameEvent&& input)
{ {
_context->input(this, std::move(input)); _context->input(this, std::move(input));
} }
void ClassicArrowNote::draw( void ClassicArrowNote::draw(const std::shared_ptr<const ClassicGraphicsManager>& graphics_manager) const
const std::shared_ptr<const ClassicGraphicsManager> &graphics_manager) const
{ {
graphics_manager->draw(this); graphics_manager->draw(this);
} }
@ -43,18 +44,17 @@ bool ClassicArrowNote::isHold() const
return _is_holding; return _is_holding;
} }
std::vector<ArrowElement> &ClassicArrowNote::getElements() std::vector<ArrowElement>& ClassicArrowNote::getElements()
{ {
return _elements; return _elements;
} }
const std::vector<ArrowElement> &ClassicArrowNote::getElements() const const std::vector<ArrowElement>& ClassicArrowNote::getElements() const
{ {
return _elements; return _elements;
} }
auto ClassicArrowNote::calculatePrecision(const kku::microsec &offset) const auto ClassicArrowNote::calculatePrecision(const kku::microsec& offset) const -> Grade
-> Grade
{ {
return _evaluator.calculatePrecision(offset); return _evaluator.calculatePrecision(offset);
} }
@ -62,6 +62,8 @@ auto ClassicArrowNote::calculatePrecision(const kku::microsec &offset) const
bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
{ {
return std::any_of(_elements.begin(), _elements.end(), return std::any_of(_elements.begin(), _elements.end(),
[key](const auto &element) [key](const auto& element)
{ return key == element.pressed_as; }); {
return key == element.pressed_as;
});
} }

View File

@ -1,16 +1,15 @@
#include "classicgame.h" #include "classicgame.h"
#include "classicmapcreator.h"
#include "classicmode/classicnote.h" #include "classicmode/classicnote.h"
#include "classicmapcreator.h"
#include "gamecontext.h" #include "gamecontext.h"
#include "graphics/classicgraphicsmanager.h"
#include "holdmanager.h" #include "holdmanager.h"
#include "graphics/classicgraphicsmanager.h"
ClassicGame::ClassicGame( ClassicGame::ClassicGame(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline, const std::shared_ptr<GameContext>& context) :
const std::shared_ptr<GameContext> &context) _timeline(timeline),
: _timeline(timeline), _context(context) _context(context)
{ {}
}
void ClassicGame::run() void ClassicGame::run()
{ {
@ -18,7 +17,7 @@ void ClassicGame::run()
_timeline->setNotes(beatmap.notes); _timeline->setNotes(beatmap.notes);
} }
void ClassicGame::input(kku::GameEvent &&input) void ClassicGame::input(kku::GameEvent&& input)
{ {
switch (input.event.type) switch (input.event.type)
{ {
@ -40,24 +39,22 @@ void ClassicGame::input(kku::GameEvent &&input)
case kku::SystemEvent::Type::KeyRelease: case kku::SystemEvent::Type::KeyRelease:
{ {
_context->getHoldManager()->checkRelease( _context->getHoldManager()->checkRelease(std::get<kku::SystemEvent::Key>(input.event.data).view);
std::get<kku::SystemEvent::Key>(input.event.data).view);
} }
break; break;
} }
} }
void ClassicGame::update(kku::UpdateData &&updatedata) void ClassicGame::update(kku::UpdateData&& updatedata)
{ {
// UNCOMMENT TO TEST AUTOPLAY // UNCOMMENT TO TEST AUTOPLAY
/*auto note_it = _timeline->getActiveNote(updatedata.timestamp); /*auto note_it = _timeline->getActiveNote(updatedata.timestamp);
if (!_timeline->isExpired(note_it) && updatedata.timestamp >= if (!_timeline->isExpired(note_it) && updatedata.timestamp >= (*note_it)->getPerfectOffset())
(*note_it)->getPerfectOffset())
{ {
auto note = (*note_it); auto note = (*note_it);
note->input(kku::GameEvent{updatedata.timestamp, note->input(kku::GameEvent{updatedata.timestamp, kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}});
kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}});
}*/ }*/
_timeline->update(updatedata.timestamp); _timeline->update(updatedata.timestamp);

View File

@ -3,28 +3,25 @@
#include "gamecontext.h" #include "gamecontext.h"
// Replace with interface by dependency injection // Replace with interface by dependency injection
#include "graphics/animations/classicdyinganimationscenario.h"
#include "graphics/animations/classicflyinganimationscenario.h" #include "graphics/animations/classicflyinganimationscenario.h"
#include "graphics/animations/classicdyinganimationscenario.h"
// //
auto classic::createBeatmap(const std::string &filepath, auto classic::createBeatmap(const std::string& filepath, const std::shared_ptr<GameContext>& context) -> Beatmap
const std::shared_ptr<GameContext> &context)
-> Beatmap
{ {
(void)filepath; (void) filepath;
kku::microsec starting_beat_offset = 402162; kku::microsec starting_beat_offset = 402162;
int amount_of_beats = 209; int amount_of_beats = 209;
kku::microsec interval = 1412162; kku::microsec interval = 1412162;
kku::microsec tempo_interval = interval / 4; kku::microsec tempo_interval = interval / 4;
kku::microsec note_input_offset = 412162 / 2; kku::microsec note_input_offset = 412162 / 2;
// microsec note_input_offset_fast = 412162 / 6; //microsec note_input_offset_fast = 412162 / 6;
kku::microsec bpm_iterator = starting_beat_offset; kku::microsec bpm_iterator = starting_beat_offset;
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats); kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
std::vector<kku::microsec> input_intervals = { std::vector<kku::microsec> input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset}; std::set<ClassicNote*, kku::NotePtrComparator> notes;
std::set<ClassicNote *, kku::NotePtrComparator> notes;
input_intervals.shrink_to_fit(); input_intervals.shrink_to_fit();
bpm_iterator += tempo_interval; bpm_iterator += tempo_interval;
@ -62,8 +59,15 @@ auto classic::createBeatmap(const std::string &filepath,
--counter; --counter;
ClassicArrowNote::Init init{ ClassicArrowNote::Init init
id++, context, bpm_iterator, input_intervals, {element}, hold}; {
id++,
context,
bpm_iterator,
input_intervals,
{element},
hold
};
notes.insert(new ClassicArrowNote(std::move(init))); notes.insert(new ClassicArrowNote(std::move(init)));
@ -76,3 +80,4 @@ auto classic::createBeatmap(const std::string &filepath,
return {std::move(notes), note_input_offset * 8}; return {std::move(notes), note_input_offset * 8};
} }

View File

@ -4,29 +4,25 @@
#include "graphics/animations/classicanimationscenario.h" #include "graphics/animations/classicanimationscenario.h"
#include "graphics/classicgraphicsmanager.h" #include "graphics/classicgraphicsmanager.h"
GameContext::GameContext( GameContext::GameContext(const std::shared_ptr<HoldManager>& hold_manager,
const std::shared_ptr<HoldManager> &hold_manager, const std::shared_ptr<ClassicGraphicsManager>& graphics_manager) :
const std::shared_ptr<ClassicGraphicsManager> &graphics_manager) _hold_manager(hold_manager),
: _hold_manager(hold_manager), _graphics_manager(graphics_manager) _graphics_manager(graphics_manager)
{ {}
}
void GameContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const void GameContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
{ {
auto grade = ClassicArrowNote::Grade::BAD; auto grade = ClassicArrowNote::Grade::BAD;
auto &elements = note->getElements(); auto& elements = note->getElements();
bool input_valid = std::any_of( bool input_valid = std::any_of(elements.begin(), elements.end(),
elements.begin(), elements.end(), [input=input](auto& element)
[input = input](auto &element)
{ {
if (element.pressed) if (element.pressed)
return false; return false;
const auto code = const auto code = std::get<kku::SystemEvent::Key>(input.event.data).view;
std::get<kku::SystemEvent::Key>(input.event.data).view; auto key_iterator = std::find(element.keys.begin(), element.keys.end(), code);
auto key_iterator =
std::find(element.keys.begin(), element.keys.end(), code);
bool found_key = key_iterator != element.keys.end(); bool found_key = key_iterator != element.keys.end();
if (found_key) if (found_key)
@ -38,9 +34,11 @@ void GameContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const
return found_key; return found_key;
}); });
bool all_pressed = bool all_pressed = std::all_of(elements.begin(), elements.end(),
std::all_of(elements.begin(), elements.end(), [](const auto& element)
[](const auto &element) { return element.pressed; }); {
return element.pressed;
});
if (all_pressed) if (all_pressed)
{ {
@ -52,23 +50,20 @@ void GameContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const
if (all_pressed || !input_valid) if (all_pressed || !input_valid)
{ {
note->setState(ClassicArrowNote::State::DYING); note->setState(ClassicArrowNote::State::DYING);
for (auto &element : elements) for (auto& element : elements)
element.animations[note->getState()]->launch( element.animations[note->getState()]->launch(element.sprite, input.timestamp, note->getPerfectOffset());
element.sprite, input.timestamp, note->getPerfectOffset());
} }
std::cout << "User input: " << static_cast<int>(grade) << "\n"; std::cout << "User input: " << static_cast<int>(grade) << "\n";
} }
void GameContext::update(ClassicArrowNote *note, void GameContext::update(ClassicArrowNote *note, const kku::microsec& music_offset) const
const kku::microsec &music_offset) const
{ {
auto &elements = note->getElements(); auto& elements = note->getElements();
switch (note->getState()) switch (note->getState())
{ {
default: default: return;
return;
break; break;
case ClassicArrowNote::State::INITIAL: case ClassicArrowNote::State::INITIAL:
@ -77,13 +72,11 @@ void GameContext::update(ClassicArrowNote *note,
break; break;
case ClassicArrowNote::State::FLYING: case ClassicArrowNote::State::FLYING:
if (!note->isActive(music_offset) && if (!note->isActive(music_offset) && music_offset > note->getPerfectOffset())
music_offset > note->getPerfectOffset())
{ {
note->setState(ClassicArrowNote::State::DYING); note->setState(ClassicArrowNote::State::DYING);
for (auto &element : elements) for (auto& element : elements)
element.animations[note->getState()]->launch( element.animations[note->getState()]->launch(element.sprite, music_offset, note->getPerfectOffset());
element.sprite, music_offset, note->getPerfectOffset());
} }
break; break;
@ -93,7 +86,7 @@ void GameContext::update(ClassicArrowNote *note,
break; break;
} }
for (auto &element : elements) for (auto& element : elements)
if (element.animations[note->getState()]) if (element.animations[note->getState()])
element.animations[note->getState()]->update(music_offset); element.animations[note->getState()]->update(music_offset);
} }

View File

@ -1,10 +1,10 @@
#include "holdmanager.h" #include "holdmanager.h"
#include "classicarrownote.h" #include "classicarrownote.h"
#include <algorithm>
#include <iostream> #include <iostream>
#include <algorithm>
void HoldManager::emplace(ClassicArrowNote *note) void HoldManager::emplace(ClassicArrowNote* note)
{ {
_notes_on_hold.emplace_back(note); _notes_on_hold.emplace_back(note);
} }
@ -12,8 +12,10 @@ void HoldManager::emplace(ClassicArrowNote *note)
void HoldManager::checkRelease(kku::SystemEvent::Key::Code released_key) void HoldManager::checkRelease(kku::SystemEvent::Key::Code released_key)
{ {
bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(), bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(),
[released_key](const auto &note) [released_key](const auto& note)
{ return note->isPressedAs(released_key); }); {
return note->isPressedAs(released_key);
});
if (key_match) if (key_match)
_notes_on_hold.clear(); _notes_on_hold.clear();

View File

@ -1,9 +1,7 @@
#include "classicdyinganimationscenario.h" #include "classicdyinganimationscenario.h"
#include "graphics/classicnotegraphics.h" #include "graphics/classicnotegraphics.h"
void ClassicDyingAnimationScenario::launch( void ClassicDyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGraphics> sprite, const kku::microsec& time_begin, const kku::microsec &time_end)
const std::shared_ptr<ClassicNoteGraphics> sprite,
const kku::microsec &time_begin, const kku::microsec &time_end)
{ {
_sprite = sprite; _sprite = sprite;
_time_begin = time_begin; _time_begin = time_begin;
@ -14,9 +12,9 @@ void ClassicDyingAnimationScenario::launch(
_sprite->setTrailPosition(kku::Point{0, 0}); _sprite->setTrailPosition(kku::Point{0, 0});
} }
void ClassicDyingAnimationScenario::update(const kku::microsec &music_offset) void ClassicDyingAnimationScenario::update(const kku::microsec& music_offset)
{ {
(void)music_offset; (void) music_offset;
auto fill_color = _sprite->getColor(); auto fill_color = _sprite->getColor();
@ -27,8 +25,7 @@ void ClassicDyingAnimationScenario::update(const kku::microsec &music_offset)
return; return;
} }
auto new_alpha = auto new_alpha = (int(fill_color.alpha) - 15) < 0 ? 0 : int(fill_color.alpha) - 15;
(int(fill_color.alpha) - 15) < 0 ? 0 : int(fill_color.alpha) - 15;
fill_color.alpha = new_alpha; fill_color.alpha = new_alpha;
_sprite->setColor(fill_color); _sprite->setColor(fill_color);

View File

@ -1,9 +1,7 @@
#include "classicflyinganimationscenario.h" #include "classicflyinganimationscenario.h"
#include "graphics/classicnotegraphics.h" #include "graphics/classicnotegraphics.h"
void ClassicFlyingAnimationScenario::launch( void ClassicFlyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGraphics> sprite, const kku::microsec& time_begin, const kku::microsec &time_end)
const std::shared_ptr<ClassicNoteGraphics> sprite,
const kku::microsec &time_begin, const kku::microsec &time_end)
{ {
_sprite = sprite; _sprite = sprite;
_time_begin = time_begin; _time_begin = time_begin;
@ -14,13 +12,12 @@ void ClassicFlyingAnimationScenario::launch(
_sprite->setTrailColor(_sprite->getColor()); _sprite->setTrailColor(_sprite->getColor());
} }
float ClassicFlyingAnimationScenario::getPoint(const kku::Point &point, float ClassicFlyingAnimationScenario::getPoint(const kku::Point& point, float perc) const
float perc) const
{ {
return point.x + ((point.y - point.x) * perc); return point.x + ((point.y - point.x) * perc);
} }
void ClassicFlyingAnimationScenario::update(const kku::microsec &music_offset) void ClassicFlyingAnimationScenario::update(const kku::microsec& music_offset)
{ {
const auto crd = _sprite->getPosition(); const auto crd = _sprite->getPosition();
auto update_time = music_offset - _time_begin; auto update_time = music_offset - _time_begin;
@ -31,8 +28,7 @@ void ClassicFlyingAnimationScenario::update(const kku::microsec &music_offset)
float xb = getPoint(kku::Point{crd.x + 90, crd.x}, i); float xb = getPoint(kku::Point{crd.x + 90, crd.x}, i);
float yb = getPoint(kku::Point{crd.y - 150, crd.y}, i); float yb = getPoint(kku::Point{crd.y - 150, crd.y}, i);
_sprite->setTrailPosition(kku::Point(getPoint(kku::Point{xa, xb}, i), _sprite->setTrailPosition(kku::Point(getPoint( kku::Point{xa, xb}, i ), getPoint( kku::Point{ya, yb}, i )));
getPoint(kku::Point{ya, yb}, i)));
} }
bool ClassicFlyingAnimationScenario::isDone() const bool ClassicFlyingAnimationScenario::isDone() const

View File

@ -1,10 +1,8 @@
#include "classicgraphicsfactory.h" #include "classicgraphicsfactory.h"
ClassicGraphicsFactory::ClassicGraphicsFactory( ClassicGraphicsFactory::ClassicGraphicsFactory(const std::shared_ptr<kku::CoreFactory>& core_factory) :
const std::shared_ptr<kku::CoreFactory> &core_factory) _core_factory(core_factory)
: _core_factory(core_factory) {}
{
}
auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
{ {
@ -43,20 +41,14 @@ auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
return SpriteData{shape, trail, color}; return SpriteData{shape, trail, color};
} }
std::shared_ptr<ClassicNoteGraphics> std::shared_ptr<ClassicNoteGraphics> ClassicGraphicsFactory::createSprite(Type type) const
ClassicGraphicsFactory::createSprite(Type type) const
{ {
const auto data = generate(type); const auto data = generate(type);
return std::make_shared<ClassicNoteGraphics>( return std::make_shared<ClassicNoteGraphics>(ClassicNoteGraphics::Init{data.shape, data.trail, data.color});
ClassicNoteGraphics::Init{data.shape, data.trail, data.color});
} }
std::shared_ptr<ClassicSelectionGraphics> std::shared_ptr<ClassicSelectionGraphics> ClassicGraphicsFactory::createSelection() const
ClassicGraphicsFactory::createSelection() const
{ {
const auto shape = _core_factory->getRectangle(); const auto shape = _core_factory->getRectangle();
return std::make_shared<ClassicSelectionGraphics>( return std::make_shared<ClassicSelectionGraphics>(ClassicSelectionGraphics::Init{shape, kku::Color{51, 153, 255, 120}});
ClassicSelectionGraphics::Init{
shape, kku::Color{51, 153, 255, 120}
});
} }

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

@ -1,7 +1,9 @@
#include "classicnotegraphics.h" #include "classicnotegraphics.h"
ClassicNoteGraphics::ClassicNoteGraphics(ClassicNoteGraphics::Init &&init) ClassicNoteGraphics::ClassicNoteGraphics(ClassicNoteGraphics::Init&& init) :
: _reset_color(init.color), _shape(init.shape), _trail(init.trail) _reset_color(init.color),
_shape(init.shape),
_trail(init.trail)
{ {
_shape->setColor(init.color); _shape->setColor(init.color);
_trail->setColor(init.color); _trail->setColor(init.color);
@ -16,7 +18,7 @@ void ClassicNoteGraphics::reset()
_trail->setColor(_reset_color); _trail->setColor(_reset_color);
} }
void ClassicNoteGraphics::setPosition(const kku::Point &position) void ClassicNoteGraphics::setPosition(const kku::Point& position)
{ {
_shape->setPosition(position); _shape->setPosition(position);
} }
@ -36,12 +38,12 @@ kku::Point ClassicNoteGraphics::getTrailPosition() const
return _trail->getPosition(); return _trail->getPosition();
} }
void ClassicNoteGraphics::setColor(const kku::Color &color) void ClassicNoteGraphics::setColor(const kku::Color& color)
{ {
_shape->setColor(color); _shape->setColor(color);
} }
void ClassicNoteGraphics::setTrailColor(const kku::Color &color) void ClassicNoteGraphics::setTrailColor(const kku::Color& color)
{ {
_trail->setColor(color); _trail->setColor(color);
} }

View File

@ -3,20 +3,21 @@
#include <iostream> #include <iostream>
ClassicSceneGraphicsManager::ClassicSceneGraphicsManager( ClassicSceneGraphicsManager::ClassicSceneGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline, const std::shared_ptr<ClassicGraphicsFactory>& factory,
const std::shared_ptr<ClassicGraphicsFactory> &factory, const kku::microsec& visibility_offset) :
const kku::microsec &visibility_offset) ClassicGraphicsManager(visibility_offset),
: ClassicGraphicsManager(visibility_offset), _sprite_container({Type::UP, Type::DOWN,
_sprite_container({Type::UP, Type::DOWN, Type::LEFT, Type::RIGHT}, Type::LEFT, Type::RIGHT},
factory), factory),
_factory(factory), _timeline(timeline) _factory(factory),
_timeline(timeline)
{ {
_timeline->expire(_first); _timeline->expire(_first);
_timeline->expire(_last); _timeline->expire(_last);
} }
void ClassicSceneGraphicsManager::input(kku::GameEvent &&input) void ClassicSceneGraphicsManager::input(kku::GameEvent&& input)
{ {
if (nothingToDraw()) if (nothingToDraw())
return; return;
@ -48,18 +49,14 @@ void ClassicSceneGraphicsManager::update(const kku::microsec &offset)
updateVisibleNotes(offset); updateVisibleNotes(offset);
} }
void ClassicSceneGraphicsManager::update(const kku::microsec &offset, void ClassicSceneGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note)
ClassicArrowNote *note)
{ {
bool hasGraphics = (note->getElements()[0].sprite != nullptr); bool hasGraphics = (note->getElements()[0].sprite != nullptr);
if (isVisiblyClose(note, offset) && !hasGraphics) if (isVisiblyClose(note, offset) && !hasGraphics)
{ {
std::cout << note->getId() << ": set graphics!\n" << std::flush; std::cout << note->getId() << ": set graphics!\n" << std::flush;
setGraphics( setGraphics(note->getElements(), kku::TimeRange{note->getPerfectOffset() - _visibility_offset, note->getPerfectOffset()});
note->getElements(),
kku::TimeRange{note->getPerfectOffset() - _visibility_offset,
note->getPerfectOffset()});
} }
else else
{ {
@ -68,18 +65,18 @@ void ClassicSceneGraphicsManager::update(const kku::microsec &offset,
} }
} }
void ClassicSceneGraphicsManager::draw(const ClassicArrowNote *const note) const void ClassicSceneGraphicsManager::draw(const ClassicArrowNote * const note) const
{ {
const auto elements = note->getElements(); const auto elements = note->getElements();
for (std::size_t i = 0; i < elements.size(); ++i) for (std::size_t i = 0; i < elements.size(); ++i)
{ {
const auto &sprite = elements[i].sprite; const auto& sprite = elements[i].sprite;
if (i >= 1) if (i >= 1)
{ {
// const auto& neighbor_sprite = elements[i - 1].sprite; //const auto& neighbor_sprite = elements[i - 1].sprite;
// const auto c1 = neighbor_sprite->trailPosition(); //const auto c1 = neighbor_sprite->trailPosition();
// const auto c2 = sprite->trailPosition(); //const auto c2 = sprite->trailPosition();
//_render_target->draw(makeLine(c1, c2)); //_render_target->draw(makeLine(c1, c2));
} }
@ -87,31 +84,37 @@ void ClassicSceneGraphicsManager::draw(const ClassicArrowNote *const note) const
} }
} }
void ClassicSceneGraphicsManager::setGraphics( void ClassicSceneGraphicsManager::switchSelection(ArrowElement* element)
std::vector<ArrowElement> &elements, kku::TimeRange &&range)
{ {
for (auto &element : elements) if (element->selection)
element->selection->reset();
else
{ {
element.sprite = _sprite_container.getSprite(element.type); element->selection = _factory->createSelection();
element.sprite->setPosition(element.position); element->selection->adjustTo(element->sprite);
element.sprite->setTrailPosition(kku::Point(0.f, 9.f));
element.animations[ClassicNote::State::NONE] = nullptr;
element.animations[ClassicNote::State::FLYING] =
std::make_shared<ClassicFlyingAnimationScenario>();
element.animations[ClassicNote::State::DYING] =
std::make_shared<ClassicDyingAnimationScenario>();
element.animations[ClassicNote::State::DEAD] = nullptr;
element.animations[ClassicNote::State::FLYING]->launch(
element.sprite, range.begin, range.end);
} }
} }
void ClassicSceneGraphicsManager::removeGraphics( void ClassicSceneGraphicsManager::setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range)
std::vector<ArrowElement> &elements)
{ {
for (auto &element : elements) for (auto& element : elements)
{
element.sprite = _sprite_container.getSprite(element.type);
element.sprite->setPosition(element.position);
element.sprite->setTrailPosition(kku::Point( 0.f, 9.f ));
element.animations[ClassicNote::State::NONE] = nullptr;
element.animations[ClassicNote::State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
element.animations[ClassicNote::State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
element.animations[ClassicNote::State::DEAD] = nullptr;
element.animations[ClassicNote::State::FLYING]->launch(element.sprite, range.begin, range.end);
}
}
void ClassicSceneGraphicsManager::removeGraphics(std::vector<ArrowElement>& elements)
{
for (auto& element : elements)
{ {
_sprite_container.resetSprite(element.sprite, element.type); _sprite_container.resetSprite(element.sprite, element.type);
element.sprite = nullptr; element.sprite = nullptr;
@ -125,17 +128,16 @@ void ClassicSceneGraphicsManager::removeGraphics(
bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept
{ {
return _timeline->isExpired(_first) || _timeline->isExpired(_last); return _timeline->isExpired(_first)
|| _timeline->isExpired(_last);
} }
bool ClassicSceneGraphicsManager::isVisiblyClose( bool ClassicSceneGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept
const ClassicNote *const note,
const kku::microsec &music_offset) const noexcept
{ {
return (note->getPerfectOffset() - _visibility_offset) <= music_offset; return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
} }
void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec &offset) void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
{ {
if (nothingToDraw()) if (nothingToDraw())
return; return;
@ -143,8 +145,7 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec &offset)
if (offset < (*_first)->getPerfectOffset()) if (offset < (*_first)->getPerfectOffset())
{ {
Iterator note_iterator = _first; Iterator note_iterator = _first;
while (note_iterator != _timeline->begin() && while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset))
isVisiblyClose(*note_iterator, offset))
{ {
--note_iterator; --note_iterator;
} }
@ -153,10 +154,10 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec &offset)
auto note = *_first; auto note = *_first;
const auto state = note->getState(); const auto state = note->getState();
if (state != ClassicNote::State::FLYING && if (state != ClassicNote::State::FLYING
state != ClassicNote::State::DYING && && state != ClassicNote::State::DYING
state != ClassicNote::State::INITIAL && && state != ClassicNote::State::INITIAL
offset <= note->getPerfectOffset()) && offset <= note->getPerfectOffset())
{ {
note->setState(ClassicNote::State::INITIAL); note->setState(ClassicNote::State::INITIAL);
} }
@ -178,21 +179,20 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec &offset)
} }
} }
void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec &offset) void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec& offset)
{ {
Iterator note_iterator = _timeline->getTopNote(); Iterator note_iterator = _timeline->getTopNote();
while (!_timeline->isExpired(note_iterator) && while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset))
isVisiblyClose(*note_iterator, offset))
{ {
if (nothingToDraw()) if (nothingToDraw())
_first = note_iterator; _first = note_iterator;
auto note = *note_iterator; auto note = *note_iterator;
const auto state = note->getState(); const auto state = note->getState();
if (state != ClassicNote::State::FLYING && if (state != ClassicNote::State::FLYING
state != ClassicNote::State::DYING && && state != ClassicNote::State::DYING
state != ClassicNote::State::INITIAL && && state != ClassicNote::State::INITIAL
offset <= note->getPerfectOffset()) && offset <= note->getPerfectOffset())
{ {
note->setState(ClassicNote::State::INITIAL); note->setState(ClassicNote::State::INITIAL);
} }
@ -203,8 +203,7 @@ void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec &offset)
_last = note_iterator; _last = note_iterator;
} }
void ClassicSceneGraphicsManager::updateVisibleNotes( void ClassicSceneGraphicsManager::updateVisibleNotes(const kku::microsec& offset)
const kku::microsec &offset)
{ {
for (auto it = _first; it != _last; ++it) for (auto it = _first; it != _last; ++it)
(*it)->update(offset); (*it)->update(offset);

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

@ -1,9 +1,9 @@
#include "classicselectiongraphics.h" #include "classicselectiongraphics.h"
#include "classicnotegraphics.h" #include "classicnotegraphics.h"
ClassicSelectionGraphics::ClassicSelectionGraphics( ClassicSelectionGraphics::ClassicSelectionGraphics(ClassicSelectionGraphics::Init&& init) :
ClassicSelectionGraphics::Init &&init) _fill_color(init.color),
: _fill_color(init.color), _shape(init.shape) _shape(init.shape)
{ {
_shape->setColor(init.color); _shape->setColor(init.color);
} }
@ -19,8 +19,7 @@ void ClassicSelectionGraphics::display() const
_shape->display(); _shape->display();
} }
void ClassicSelectionGraphics::adjustTo( void ClassicSelectionGraphics::adjustTo(const std::shared_ptr<ClassicNoteGraphics>& sprite)
const std::shared_ptr<ClassicNoteGraphics> &sprite)
{ {
_shape->setRect(sprite->getRectangle()->getRect()); _shape->setRect(sprite->getRectangle()->getRect());
} }

View File

@ -3,14 +3,15 @@
#include <iostream> #include <iostream>
ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager( ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline, const std::shared_ptr<ClassicGraphicsFactory>& factory,
const std::shared_ptr<ClassicGraphicsFactory> &factory, const kku::microsec& visibility_offset) :
const kku::microsec &visibility_offset) ClassicGraphicsManager(visibility_offset),
: ClassicGraphicsManager(visibility_offset), _sprite_container({Type::UP, Type::DOWN,
_sprite_container({Type::UP, Type::DOWN, Type::LEFT, Type::RIGHT}, Type::LEFT, Type::RIGHT},
factory), factory),
_factory(factory), _timeline(timeline), _factory(factory),
_timeline(timeline),
_back_visibility_offset(static_cast<double>(visibility_offset) / 4.f), _back_visibility_offset(static_cast<double>(visibility_offset) / 4.f),
_last_offset(0) _last_offset(0)
{ {
@ -18,7 +19,7 @@ ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(
_timeline->expire(_last); _timeline->expire(_last);
} }
void ClassicTimelineGraphicsManager::input(kku::GameEvent &&input) void ClassicTimelineGraphicsManager::input(kku::GameEvent&& input)
{ {
switch (input.event.type) switch (input.event.type)
{ {
@ -31,14 +32,12 @@ void ClassicTimelineGraphicsManager::input(kku::GameEvent &&input)
if (key_data.view == kku::SystemEvent::Key::Code::Add) if (key_data.view == kku::SystemEvent::Key::Code::Add)
{ {
_visibility_offset += 200000; _visibility_offset += 200000;
_back_visibility_offset = _back_visibility_offset = static_cast<double>(_visibility_offset) / 4.f;
static_cast<double>(_visibility_offset) / 4.f;
} }
else if (key_data.view == kku::SystemEvent::Key::Code::Subtract) else if (key_data.view == kku::SystemEvent::Key::Code::Subtract)
{ {
_visibility_offset -= 200000; _visibility_offset -= 200000;
_back_visibility_offset = _back_visibility_offset = static_cast<double>(_visibility_offset) / 4.f;
static_cast<double>(_visibility_offset) / 4.f;
} }
break; break;
} }
@ -47,8 +46,8 @@ void ClassicTimelineGraphicsManager::input(kku::GameEvent &&input)
void ClassicTimelineGraphicsManager::display() const void ClassicTimelineGraphicsManager::display() const
{ {
// if (nothingToDraw()) //if (nothingToDraw())
// return; //return;
std::cout << "displaying on tl: "; std::cout << "displaying on tl: ";
for (auto it = _first; it != _last; ++it) for (auto it = _first; it != _last; ++it)
@ -67,8 +66,7 @@ void ClassicTimelineGraphicsManager::update(const kku::microsec &offset)
fetchFirstNote(offset); fetchFirstNote(offset);
} }
void ClassicTimelineGraphicsManager::update(const kku::microsec &offset, void ClassicTimelineGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note)
ClassicArrowNote *note)
{ {
bool hasGraphics = (note->getElements()[0].sprite != nullptr); bool hasGraphics = (note->getElements()[0].sprite != nullptr);
@ -82,17 +80,13 @@ void ClassicTimelineGraphicsManager::update(const kku::microsec &offset,
} }
} }
void ClassicTimelineGraphicsManager::draw( void ClassicTimelineGraphicsManager::draw(const ClassicArrowNote * const note) const
const ClassicArrowNote *const note) const
{ {
const double d_visibility_offset = const double d_visibility_offset = static_cast<double>(_last_offset + _visibility_offset);
static_cast<double>(_last_offset + _visibility_offset); const double d_back_visibility_offset = static_cast<double>(_last_offset - _back_visibility_offset);
const double d_back_visibility_offset =
static_cast<double>(_last_offset - _back_visibility_offset);
const double span = d_visibility_offset - d_back_visibility_offset; const double span = d_visibility_offset - d_back_visibility_offset;
const double note_span = const double note_span = static_cast<double>(note->getPerfectOffset()) - d_visibility_offset;
static_cast<double>(note->getPerfectOffset()) - d_visibility_offset;
const double percent = note_span / (span / 100.f); const double percent = note_span / (span / 100.f);
@ -100,8 +94,7 @@ void ClassicTimelineGraphicsManager::draw(
for (std::size_t i = 0; i < elements.size(); ++i) for (std::size_t i = 0; i < elements.size(); ++i)
{ {
auto timeline_sprite = _factory->createSprite(elements[i].type); auto timeline_sprite = _factory->createSprite(elements[i].type);
timeline_sprite->setPosition( timeline_sprite->setPosition(kku::Point{static_cast<int>(850 + 1280.f / 100.f * percent), 700});
kku::Point{static_cast<int>(850 + 1280.f / 100.f * percent), 700});
timeline_sprite->display(); timeline_sprite->display();
} }
@ -109,27 +102,25 @@ void ClassicTimelineGraphicsManager::draw(
bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept
{ {
return _timeline->isExpired(_first) || _timeline->isExpired(_last); return _timeline->isExpired(_first)
|| _timeline->isExpired(_last);
} }
bool ClassicTimelineGraphicsManager::isVisiblyClose( bool ClassicTimelineGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept
const ClassicNote *const note,
const kku::microsec &music_offset) const noexcept
{ {
const auto &perfect_offset = note->getPerfectOffset(); const auto& perfect_offset = note->getPerfectOffset();
return ((perfect_offset - _visibility_offset) <= music_offset) || return ((perfect_offset - _visibility_offset) <= music_offset)
((perfect_offset + (_visibility_offset / 4.)) >= music_offset); || ((perfect_offset + (_visibility_offset / 4.)) >= music_offset);
} }
void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec &offset) void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec& offset)
{ {
// if (nothingToDraw()) //if (nothingToDraw())
// return; //return;
Iterator note_iterator = _first; Iterator note_iterator = _first;
while (note_iterator != _timeline->begin() && while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset))
isVisiblyClose(*note_iterator, offset))
{ {
--note_iterator; --note_iterator;
} }
@ -137,11 +128,10 @@ void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec &offset)
_first = note_iterator; _first = note_iterator;
} }
void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec &offset) void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec& offset)
{ {
Iterator note_iterator = _timeline->getTopNote(); Iterator note_iterator = _timeline->getTopNote();
while (!_timeline->isExpired(note_iterator) && while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset))
isVisiblyClose(*note_iterator, offset))
{ {
if (nothingToDraw()) if (nothingToDraw())
_first = note_iterator; _first = note_iterator;

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;

View File

@ -1,21 +1,23 @@
#include "tools/beatutils.h" #include "tools/beatutils.h"
#include <iostream>
#include <numeric> #include <numeric>
#include <iostream>
auto beat_utils::calculateBeatRateInfo( auto beat_utils::calculateBeatRateInfo(const std::vector<kku::microsec>& approximate_deltas) -> BeatInfo
const std::vector<kku::microsec> &approximate_deltas) -> BeatInfo
{ {
if (approximate_deltas.empty()) if (approximate_deltas.empty())
return {}; return {};
const long double sum = std::accumulate(approximate_deltas.begin(), const long double sum = std::accumulate(approximate_deltas.begin(), approximate_deltas.end(), 0);
approximate_deltas.end(), 0);
const long double amount = approximate_deltas.size(); const long double amount = approximate_deltas.size();
long double average = sum / amount; long double average = sum / amount;
const int bpm = static_cast<int>(60000000. / average); const int bpm = static_cast<int>(60000000. / average);
return BeatInfo{bpm, static_cast<kku::microsec>(
1. / static_cast<long double>(bpm) * 60000000.)}; return BeatInfo
{
bpm,
static_cast<kku::microsec>(1. / static_cast<long double>(bpm) * 60000000.)
};
} }

View File

@ -1,8 +1,8 @@
#include "tools/bpmcalculator.h" #include "tools/bpmcalculator.h"
#include <cmath> #include <cmath>
#include <iostream>
#include <numeric> #include <numeric>
#include <iostream>
BPMCalculator::BPMCalculator() BPMCalculator::BPMCalculator()
{ {
@ -55,7 +55,7 @@ void BPMCalculator::click(const kku::microsec &offset)
_previous_click_offset = offset; _previous_click_offset = offset;
} }
const beat_utils::BeatInfo &BPMCalculator::fetchApproximatedInfo() const beat_utils::BeatInfo& BPMCalculator::fetchApproximatedInfo()
{ {
if (!_need_recalculate) if (!_need_recalculate)
return _approximated_info; return _approximated_info;
@ -86,7 +86,7 @@ void BPMCalculator::moveStartingOffsetBy(kku::microsec shift)
_first_click_offset += shift; _first_click_offset += shift;
} }
kku::microsec BPMCalculator::fetchTimeUntilNextBeat(const kku::microsec &offset) kku::microsec BPMCalculator::fetchTimeUntilNextBeat(const kku::microsec& offset)
{ {
const kku::microsec actual_offset = offset - getStartingOffset(); const kku::microsec actual_offset = offset - getStartingOffset();