forked from NaiJi/project-kyoku
Implement Editor command system
parent
98273d3a39
commit
124417d778
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/systemevent.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace kku
|
||||||
|
{
|
||||||
|
|
||||||
|
class EditorCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~EditorCallback() = default;
|
||||||
|
|
||||||
|
struct Metadata
|
||||||
|
{
|
||||||
|
const std::string group_title;
|
||||||
|
const std::string title;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool isEnabled() const = 0;
|
||||||
|
virtual void run() const = 0;
|
||||||
|
|
||||||
|
virtual Metadata getMetadata() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace kku
|
||||||
|
{
|
||||||
|
|
||||||
|
using lambda = std::function<void(void)>;
|
||||||
|
using predicate = std::function<bool(void)>;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
#include "callbacksimple.h"
|
||||||
|
|
||||||
|
CallbackSimple::CallbackSimple(Init&& init, Metadata&& metadata) :
|
||||||
|
_run(std::move(init.run)),
|
||||||
|
_is_enabled(std::move(init.is_enabled)),
|
||||||
|
_metadata(std::move(metadata))
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CallbackSimple::isEnabled() const
|
||||||
|
{
|
||||||
|
return _is_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallbackSimple::run() const
|
||||||
|
{
|
||||||
|
_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CallbackSimple::getMetadata() const -> EditorCallback::Metadata
|
||||||
|
{
|
||||||
|
return _metadata;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/editorcallback.h"
|
||||||
|
#include "core/functional.h"
|
||||||
|
|
||||||
|
class CallbackSimple : public kku::EditorCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Init
|
||||||
|
{
|
||||||
|
kku::lambda run;
|
||||||
|
kku::predicate is_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit CallbackSimple(Init&& init, Metadata&& metadata);
|
||||||
|
|
||||||
|
virtual bool isEnabled() const override;
|
||||||
|
virtual void run() const override;
|
||||||
|
|
||||||
|
virtual Metadata getMetadata() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const kku::lambda _run;
|
||||||
|
const kku::predicate _is_enabled;
|
||||||
|
const Metadata _metadata;
|
||||||
|
};
|
@ -1,248 +0,0 @@
|
|||||||
#include "classicscenegraphicsmanager.h"
|
|
||||||
|
|
||||||
#include "editor/mockelement.h"
|
|
||||||
#include "game/arrowelement.h"
|
|
||||||
|
|
||||||
#include "graphics/animations/classicflyinganimationscenario.h"
|
|
||||||
#include "graphics/animations/classicdyinganimationscenario.h"
|
|
||||||
|
|
||||||
ClassicSceneGraphicsManager::ClassicSceneGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
|
|
||||||
const std::shared_ptr<ClassicGraphicsFactory>& factory,
|
|
||||||
const kku::microsec& visibility_offset) :
|
|
||||||
ClassicGraphicsManager(visibility_offset),
|
|
||||||
_sprite_container({Type::UP, Type::DOWN,
|
|
||||||
Type::LEFT, Type::RIGHT},
|
|
||||||
factory),
|
|
||||||
_factory(factory),
|
|
||||||
_timeline(timeline)
|
|
||||||
{
|
|
||||||
_timeline->expire(_first);
|
|
||||||
_timeline->expire(_last);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::input(kku::GameEvent&& input)
|
|
||||||
{
|
|
||||||
if (nothingToDraw())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto it = _first; it != _last; ++it)
|
|
||||||
{
|
|
||||||
(*it)->input(std::move(input));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::display() const
|
|
||||||
{
|
|
||||||
if (nothingToDraw())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto it = _first; it != _last; ++it)
|
|
||||||
{
|
|
||||||
(*it)->display(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::update(const kku::microsec &offset)
|
|
||||||
{
|
|
||||||
fetchLastNote(offset);
|
|
||||||
fetchFirstNote(offset);
|
|
||||||
|
|
||||||
updateVisibleNotes(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::display(const std::vector<ArrowElement>& elements) const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < elements.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& sprite = elements[i].sprite;
|
|
||||||
|
|
||||||
if (i >= 1)
|
|
||||||
{
|
|
||||||
//const auto& neighbor_sprite = elements[i - 1].sprite;
|
|
||||||
|
|
||||||
//const auto c1 = neighbor_sprite->trailPosition();
|
|
||||||
//const auto c2 = sprite->trailPosition();
|
|
||||||
|
|
||||||
//_render_target->draw(makeLine(c1, c2));
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite->display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange &&range)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
element.sprite = nullptr;
|
|
||||||
|
|
||||||
element.animations[ClassicNote::State::NONE] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::FLYING] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::DYING] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::DEAD] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::display(const std::vector<MockElement>& elements) const
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < elements.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& sprite = elements[i].sprite;
|
|
||||||
|
|
||||||
if (i >= 1)
|
|
||||||
{
|
|
||||||
//const auto& neighbor_sprite = elements[i - 1].sprite;
|
|
||||||
|
|
||||||
//const auto c1 = neighbor_sprite->trailPosition();
|
|
||||||
//const auto c2 = sprite->trailPosition();
|
|
||||||
|
|
||||||
//_render_target->draw(makeLine(c1, c2));
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite->display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::setGraphics(std::vector<MockElement>& elements, kku::TimeRange &&range)
|
|
||||||
{
|
|
||||||
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.selection = _factory->createSelection();
|
|
||||||
element.selection->adjustTo(element.sprite);
|
|
||||||
|
|
||||||
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<MockElement>& elements)
|
|
||||||
{
|
|
||||||
for (auto& element : elements)
|
|
||||||
{
|
|
||||||
_sprite_container.resetSprite(element.sprite, element.type);
|
|
||||||
element.sprite = nullptr;
|
|
||||||
|
|
||||||
element.animations[ClassicNote::State::NONE] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::FLYING] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::DYING] = nullptr;
|
|
||||||
element.animations[ClassicNote::State::DEAD] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*sf::VertexArray ClassicSceneGraphicsSFML::makeLine(const kku::Point& c1, const kku::Point& c2) const
|
|
||||||
{
|
|
||||||
sf::VertexArray line(sf::LinesStrip, 2);
|
|
||||||
line[0].color = sf::Color::Yellow;
|
|
||||||
line[0].position = {c1.x + 10, c1.y};
|
|
||||||
line[1].color = sf::Color::Blue;
|
|
||||||
line[1].position = {c2.x + 10, c2.y};
|
|
||||||
|
|
||||||
return line;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::updateVisibleNotes(const kku::microsec &offset)
|
|
||||||
{
|
|
||||||
for (auto it = _first; it != _last; ++it)
|
|
||||||
(*it)->update(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
|
||||||
{
|
|
||||||
if (nothingToDraw())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (offset < (*_first)->getPerfectOffset())
|
|
||||||
{
|
|
||||||
Iterator note_iterator = _first;
|
|
||||||
while (note_iterator != _timeline->begin() && isVisiblyClose(note_iterator, offset))
|
|
||||||
{
|
|
||||||
--note_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
_first = note_iterator;
|
|
||||||
|
|
||||||
auto note = *_first;
|
|
||||||
if (note->getState() != ClassicNote::State::FLYING
|
|
||||||
&& note->getState() != ClassicNote::State::DYING
|
|
||||||
&& offset <= note->getPerfectOffset())
|
|
||||||
{
|
|
||||||
note->setState(ClassicNote::State::FLYING);
|
|
||||||
note->setGraphics(this, kku::TimeRange{note->getPerfectOffset() - _visibility_offset, note->getPerfectOffset()});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Iterator note_iterator = _first;
|
|
||||||
while (note_iterator != _last)
|
|
||||||
{
|
|
||||||
auto note = *note_iterator;
|
|
||||||
if (note->getState() == ClassicNote::State::DEAD)
|
|
||||||
{
|
|
||||||
// note->removeGraphics(this);
|
|
||||||
++_first;
|
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec& offset)
|
|
||||||
{
|
|
||||||
Iterator note_iterator = _timeline->getTopNote();
|
|
||||||
while (!_timeline->isExpired(note_iterator) && isVisiblyClose(note_iterator, offset))
|
|
||||||
{
|
|
||||||
if (nothingToDraw())
|
|
||||||
_first = note_iterator;
|
|
||||||
|
|
||||||
auto note = *note_iterator;
|
|
||||||
|
|
||||||
if (note->getState() != ClassicNote::State::FLYING
|
|
||||||
&& note->getState() != ClassicNote::State::DYING
|
|
||||||
&& offset <= note->getPerfectOffset())
|
|
||||||
{
|
|
||||||
note->setState(ClassicNote::State::FLYING);
|
|
||||||
note->setGraphics(this, kku::TimeRange{note->getPerfectOffset() - _visibility_offset, note->getPerfectOffset()});
|
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
_last = note_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept
|
|
||||||
{
|
|
||||||
return _timeline->isExpired(_first)
|
|
||||||
|| _timeline->isExpired(_last);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicSceneGraphicsManager::isVisiblyClose(const Iterator& iterator, const kku::microsec& music_offset) const noexcept
|
|
||||||
{
|
|
||||||
return ((*iterator)->getPerfectOffset() - _visibility_offset) <= music_offset;
|
|
||||||
}
|
|
Loading…
Reference in New Issue