mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-13 23:58:18 +07:00
generic events and commands components
This commit is contained in:
@@ -31,7 +31,9 @@
|
||||
#include "components/actor.hpp"
|
||||
#include "components/behaviour.hpp"
|
||||
#include "components/camera.hpp"
|
||||
#include "components/commands.hpp"
|
||||
#include "components/disabled.hpp"
|
||||
#include "components/events.hpp"
|
||||
#include "components/flipbook_player.hpp"
|
||||
#include "components/label.hpp"
|
||||
#include "components/model_renderer.hpp"
|
||||
@@ -39,8 +41,6 @@
|
||||
#include "components/renderer.hpp"
|
||||
#include "components/scene.hpp"
|
||||
#include "components/spine_player.hpp"
|
||||
#include "components/spine_player_cmd.hpp"
|
||||
#include "components/spine_player_evt.hpp"
|
||||
#include "components/sprite_renderer.hpp"
|
||||
|
||||
#include "systems/flipbook_system.hpp"
|
||||
|
||||
@@ -46,8 +46,12 @@ namespace e2d
|
||||
class actor;
|
||||
class behaviour;
|
||||
class camera;
|
||||
template < typename C >
|
||||
class commands;
|
||||
template < typename T >
|
||||
class disabled;
|
||||
template < typename E >
|
||||
class events;
|
||||
class flipbook_player;
|
||||
class label;
|
||||
class model_renderer;
|
||||
@@ -55,8 +59,6 @@ namespace e2d
|
||||
class renderer;
|
||||
class scene;
|
||||
class spine_player;
|
||||
class spine_player_cmd;
|
||||
class spine_player_evt;
|
||||
class sprite_renderer;
|
||||
|
||||
class flipbook_system;
|
||||
|
||||
86
headers/enduro2d/high/components/commands.hpp
Normal file
86
headers/enduro2d/high/components/commands.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename C >
|
||||
class commands final {
|
||||
public:
|
||||
commands() = default;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<C>::const_iterator
|
||||
begin() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<C>::const_iterator
|
||||
cbegin() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<C>::const_iterator
|
||||
end() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<C>::const_iterator
|
||||
cend() const noexcept;
|
||||
|
||||
commands& add(C command);
|
||||
commands& clear() noexcept;
|
||||
[[nodiscard]] bool empty() const noexcept;
|
||||
[[nodiscard]] std::size_t size() const noexcept;
|
||||
private:
|
||||
vector<C> commands_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename C >
|
||||
typename vector<C>::const_iterator commands<C>::begin() const noexcept {
|
||||
return commands_.begin();
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
typename vector<C>::const_iterator commands<C>::cbegin() const noexcept {
|
||||
return commands_.cbegin();
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
typename vector<C>::const_iterator commands<C>::end() const noexcept {
|
||||
return commands_.end();
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
typename vector<C>::const_iterator commands<C>::cend() const noexcept {
|
||||
return commands_.cend();
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
commands<C>& commands<C>::add(C command) {
|
||||
commands_.push_back(std::move(command));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
commands<C>& commands<C>::clear() noexcept {
|
||||
commands_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
bool commands<C>::empty() const noexcept {
|
||||
return commands_.empty();
|
||||
}
|
||||
|
||||
template < typename C >
|
||||
std::size_t commands<C>::size() const noexcept {
|
||||
return commands_.size();
|
||||
}
|
||||
}
|
||||
86
headers/enduro2d/high/components/events.hpp
Normal file
86
headers/enduro2d/high/components/events.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename E >
|
||||
class events final {
|
||||
public:
|
||||
events() = default;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<E>::const_iterator
|
||||
begin() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<E>::const_iterator
|
||||
cbegin() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<E>::const_iterator
|
||||
end() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
typename vector<E>::const_iterator
|
||||
cend() const noexcept;
|
||||
|
||||
events& add(E event);
|
||||
events& clear() noexcept;
|
||||
[[nodiscard]] bool empty() const noexcept;
|
||||
[[nodiscard]] std::size_t size() const noexcept;
|
||||
private:
|
||||
vector<E> events_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename E >
|
||||
typename vector<E>::const_iterator events<E>::begin() const noexcept {
|
||||
return events_.begin();
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
typename vector<E>::const_iterator events<E>::cbegin() const noexcept {
|
||||
return events_.cbegin();
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
typename vector<E>::const_iterator events<E>::end() const noexcept {
|
||||
return events_.end();
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
typename vector<E>::const_iterator events<E>::cend() const noexcept {
|
||||
return events_.cend();
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
events<E>& events<E>::add(E event) {
|
||||
events_.push_back(std::move(event));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
events<E>& events<E>::clear() noexcept {
|
||||
events_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
bool events<E>::empty() const noexcept {
|
||||
return events_.empty();
|
||||
}
|
||||
|
||||
template < typename E >
|
||||
std::size_t events<E>::size() const noexcept {
|
||||
return events_.size();
|
||||
}
|
||||
}
|
||||
@@ -37,25 +37,20 @@ namespace e2d
|
||||
spine_player& spine(
|
||||
const spine_asset::ptr& value);
|
||||
|
||||
spine_player& materials(
|
||||
flat_map<str_hash, material_asset::ptr>&& value) noexcept;
|
||||
bool skin(str_view name);
|
||||
bool attachment(str_view slot, str_view name);
|
||||
|
||||
spine_player& materials(
|
||||
const flat_map<str_hash, material_asset::ptr>& value);
|
||||
|
||||
spine_player& skin(const str& value) noexcept;
|
||||
spine_player& attachment(const str& slot, const str& name) noexcept;
|
||||
|
||||
bool has_skin(const str& name) const noexcept;
|
||||
bool has_animation(const str& name) const noexcept;
|
||||
bool has_skin(str_view name) const noexcept;
|
||||
bool has_animation(str_view name) const noexcept;
|
||||
|
||||
const spine_asset::ptr& spine() const noexcept;
|
||||
const clipping_ptr& clipper() const noexcept;
|
||||
const skeleton_ptr& skeleton() const noexcept;
|
||||
const animation_ptr& animation() const noexcept;
|
||||
|
||||
material_asset::ptr find_material(str_hash name) const noexcept;
|
||||
spine_player& materials(flat_map<str_hash, material_asset::ptr> value) noexcept;
|
||||
const flat_map<str_hash, material_asset::ptr>& materials() const noexcept;
|
||||
material_asset::ptr find_material(str_hash name) const noexcept;
|
||||
private:
|
||||
spine_asset::ptr spine_;
|
||||
clipping_ptr clipping_;
|
||||
@@ -78,3 +73,236 @@ namespace e2d
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d::spine_player_events
|
||||
{
|
||||
class custom_evt;
|
||||
class end_evt;
|
||||
class complete_evt;
|
||||
|
||||
using event = std::variant<
|
||||
custom_evt,
|
||||
end_evt,
|
||||
complete_evt>;
|
||||
|
||||
class custom_evt final {
|
||||
public:
|
||||
custom_evt(str name)
|
||||
: name_(std::move(name)) {}
|
||||
|
||||
custom_evt& int_value(i32 value) noexcept {
|
||||
int_value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
custom_evt& float_value(f32 value) noexcept {
|
||||
float_value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
custom_evt& string_value(str value) noexcept {
|
||||
string_value_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] const str& name() const noexcept { return name_; }
|
||||
[[nodiscard]] i32 int_value() const noexcept { return int_value_; }
|
||||
[[nodiscard]] f32 float_value() const noexcept { return float_value_; }
|
||||
[[nodiscard]] const str& string_value() const noexcept { return string_value_; }
|
||||
private:
|
||||
str name_;
|
||||
i32 int_value_{0};
|
||||
f32 float_value_{0.f};
|
||||
str string_value_;
|
||||
};
|
||||
|
||||
class end_evt final {
|
||||
public:
|
||||
end_evt(str message)
|
||||
: message_(std::move(message)) {}
|
||||
|
||||
[[nodiscard]] const str& message() const noexcept { return message_; }
|
||||
private:
|
||||
str message_;
|
||||
};
|
||||
|
||||
class complete_evt final {
|
||||
public:
|
||||
complete_evt(str message)
|
||||
: message_(std::move(message)) {}
|
||||
|
||||
[[nodiscard]] const str& message() const noexcept { return message_; }
|
||||
private:
|
||||
str message_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d::spine_player_commands
|
||||
{
|
||||
class clear_track_cmd;
|
||||
class set_anim_cmd;
|
||||
class add_anim_cmd;
|
||||
class set_empty_anim_cmd;
|
||||
class add_empty_anim_cmd;
|
||||
|
||||
using command = std::variant<
|
||||
clear_track_cmd,
|
||||
set_anim_cmd,
|
||||
add_anim_cmd,
|
||||
set_empty_anim_cmd,
|
||||
add_empty_anim_cmd>;
|
||||
|
||||
class clear_track_cmd final {
|
||||
public:
|
||||
clear_track_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
[[nodiscard]] u32 track() const noexcept { return track_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
};
|
||||
|
||||
class set_anim_cmd final {
|
||||
public:
|
||||
set_anim_cmd(u32 track, str name)
|
||||
: track_(track)
|
||||
, name_(std::move(name)) {}
|
||||
|
||||
set_anim_cmd& loop(bool value) noexcept {
|
||||
loop_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 track() const noexcept { return track_; }
|
||||
[[nodiscard]] const str& name() const noexcept { return name_; }
|
||||
[[nodiscard]] bool loop() const noexcept { return loop_; }
|
||||
[[nodiscard]] const str& end_message() const noexcept { return complete_message_; }
|
||||
[[nodiscard]] const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
str name_;
|
||||
bool loop_{false};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class add_anim_cmd final {
|
||||
public:
|
||||
add_anim_cmd(u32 track, str name)
|
||||
: track_(track)
|
||||
, name_(std::move(name)) {}
|
||||
|
||||
add_anim_cmd& loop(bool value) noexcept {
|
||||
loop_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& delay(f32 value) noexcept {
|
||||
delay_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 track() const noexcept { return track_; }
|
||||
[[nodiscard]] const str& name() const noexcept { return name_; }
|
||||
[[nodiscard]] bool loop() const noexcept { return loop_; }
|
||||
[[nodiscard]] f32 delay() const noexcept { return delay_; }
|
||||
[[nodiscard]] const str& end_message() const noexcept { return end_message_; }
|
||||
[[nodiscard]] const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
str name_;
|
||||
bool loop_{false};
|
||||
f32 delay_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class set_empty_anim_cmd final {
|
||||
public:
|
||||
set_empty_anim_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
set_empty_anim_cmd& mix_duration(f32 value) noexcept {
|
||||
mix_duration_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_empty_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_empty_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 track() const noexcept { return track_; }
|
||||
[[nodiscard]] f32 mix_duration() const noexcept { return mix_duration_; }
|
||||
[[nodiscard]] const str& end_message() const noexcept { return end_message_; }
|
||||
[[nodiscard]] const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
f32 mix_duration_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class add_empty_anim_cmd final {
|
||||
public:
|
||||
add_empty_anim_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
add_empty_anim_cmd& delay(f32 value) noexcept {
|
||||
delay_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& mix_duration(f32 value) noexcept {
|
||||
mix_duration_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 track() const noexcept { return track_; }
|
||||
[[nodiscard]] f32 delay() const noexcept { return delay_; }
|
||||
[[nodiscard]] f32 mix_duration() const noexcept { return mix_duration_; }
|
||||
[[nodiscard]] const str& end_message() const noexcept { return end_message_; }
|
||||
[[nodiscard]] const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
f32 delay_{0.f};
|
||||
f32 mix_duration_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../factory.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class spine_player_cmd final {
|
||||
public:
|
||||
class clear_track_cmd final {
|
||||
public:
|
||||
clear_track_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
u32 track() const noexcept { return track_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
};
|
||||
|
||||
class set_anim_cmd final {
|
||||
public:
|
||||
set_anim_cmd(u32 track, str name)
|
||||
: track_(track)
|
||||
, name_(std::move(name)) {}
|
||||
|
||||
set_anim_cmd& loop(bool value) noexcept {
|
||||
loop_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
u32 track() const noexcept { return track_; }
|
||||
const str& name() const noexcept { return name_; }
|
||||
bool loop() const noexcept { return loop_; }
|
||||
const str& end_message() const noexcept { return complete_message_; }
|
||||
const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
str name_;
|
||||
bool loop_{false};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class add_anim_cmd final {
|
||||
public:
|
||||
add_anim_cmd(u32 track, str name)
|
||||
: track_(track)
|
||||
, name_(std::move(name)) {}
|
||||
|
||||
add_anim_cmd& loop(bool value) noexcept {
|
||||
loop_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& delay(secf value) noexcept {
|
||||
delay_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
u32 track() const noexcept { return track_; }
|
||||
const str& name() const noexcept { return name_; }
|
||||
bool loop() const noexcept { return loop_; }
|
||||
secf delay() const noexcept { return delay_; }
|
||||
const str& end_message() const noexcept { return end_message_; }
|
||||
const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
str name_;
|
||||
bool loop_{false};
|
||||
secf delay_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class set_empty_anim_cmd final {
|
||||
public:
|
||||
set_empty_anim_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
set_empty_anim_cmd& mix_duration(secf value) noexcept {
|
||||
mix_duration_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_empty_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
set_empty_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
u32 track() const noexcept { return track_; }
|
||||
secf mix_duration() const noexcept { return mix_duration_; }
|
||||
const str& end_message() const noexcept { return end_message_; }
|
||||
const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
secf mix_duration_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
class add_empty_anim_cmd final {
|
||||
public:
|
||||
add_empty_anim_cmd(u32 track)
|
||||
: track_(track) {}
|
||||
|
||||
add_empty_anim_cmd& delay(secf value) noexcept {
|
||||
delay_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& mix_duration(secf value) noexcept {
|
||||
mix_duration_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& end_message(str value) noexcept {
|
||||
end_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
add_empty_anim_cmd& complete_message(str value) noexcept {
|
||||
complete_message_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
u32 track() const noexcept { return track_; }
|
||||
secf delay() const noexcept { return delay_; }
|
||||
secf mix_duration() const noexcept { return mix_duration_; }
|
||||
const str& end_message() const noexcept { return end_message_; }
|
||||
const str& complete_message() const noexcept { return complete_message_; }
|
||||
private:
|
||||
u32 track_{0u};
|
||||
secf delay_{0.f};
|
||||
secf mix_duration_{0.f};
|
||||
str end_message_;
|
||||
str complete_message_;
|
||||
};
|
||||
|
||||
using command = std::variant<
|
||||
clear_track_cmd,
|
||||
set_anim_cmd,
|
||||
add_anim_cmd,
|
||||
set_empty_anim_cmd,
|
||||
add_empty_anim_cmd>;
|
||||
public:
|
||||
spine_player_cmd() = default;
|
||||
|
||||
spine_player_cmd& add_command(command cmd) {
|
||||
commands_.push_back(std::move(cmd));
|
||||
return *this;
|
||||
}
|
||||
|
||||
spine_player_cmd& clear_commands() noexcept {
|
||||
commands_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const vector<command>& commands() const noexcept {
|
||||
return commands_;
|
||||
}
|
||||
private:
|
||||
vector<command> commands_;
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<spine_player_cmd> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
spine_player_cmd& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../factory.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class spine_player_evt final {
|
||||
public:
|
||||
class custom_evt final {
|
||||
public:
|
||||
custom_evt(str_hash name)
|
||||
: name_(name) {}
|
||||
|
||||
custom_evt& int_value(i32 value) noexcept {
|
||||
int_value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
custom_evt& float_value(f32 value) noexcept {
|
||||
float_value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
custom_evt& string_value(str value) noexcept {
|
||||
string_value_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
str_hash name() const noexcept { return name_; }
|
||||
i32 int_value() const noexcept { return int_value_; }
|
||||
f32 float_value() const noexcept { return float_value_; }
|
||||
const str& string_value() const noexcept { return string_value_; }
|
||||
private:
|
||||
str_hash name_;
|
||||
i32 int_value_{0};
|
||||
f32 float_value_{0.f};
|
||||
str string_value_;
|
||||
};
|
||||
|
||||
class end_evt final {
|
||||
public:
|
||||
end_evt(str message)
|
||||
: message_(std::move(message)) {}
|
||||
|
||||
const str& message() const noexcept { return message_; }
|
||||
private:
|
||||
str message_;
|
||||
};
|
||||
|
||||
class complete_evt final {
|
||||
public:
|
||||
complete_evt(str message)
|
||||
: message_(std::move(message)) {}
|
||||
|
||||
const str& message() const noexcept { return message_; }
|
||||
private:
|
||||
str message_;
|
||||
};
|
||||
|
||||
using event = std::variant<
|
||||
custom_evt,
|
||||
end_evt,
|
||||
complete_evt>;
|
||||
public:
|
||||
spine_player_evt() = default;
|
||||
|
||||
spine_player_evt& add_event(event evt) {
|
||||
events_.push_back(std::move(evt));
|
||||
return *this;
|
||||
}
|
||||
|
||||
spine_player_evt& clear_events() noexcept {
|
||||
events_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const vector<event>& events() const noexcept {
|
||||
return events_;
|
||||
}
|
||||
private:
|
||||
vector<event> events_;
|
||||
};
|
||||
|
||||
template <>
|
||||
class factory_loader<spine_player_evt> final : factory_loader<> {
|
||||
public:
|
||||
static const char* schema_source;
|
||||
|
||||
bool operator()(
|
||||
spine_player_evt& component,
|
||||
const fill_context& ctx) const;
|
||||
|
||||
bool operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const;
|
||||
};
|
||||
}
|
||||
12
sources/enduro2d/high/components/commands.cpp
Normal file
12
sources/enduro2d/high/components/commands.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/components/commands.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
}
|
||||
12
sources/enduro2d/high/components/events.cpp
Normal file
12
sources/enduro2d/high/components/events.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/components/events.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
}
|
||||
@@ -49,44 +49,59 @@ namespace e2d
|
||||
return *this;
|
||||
}
|
||||
|
||||
spine_player& spine_player::materials(
|
||||
flat_map<str_hash, material_asset::ptr>&& value) noexcept
|
||||
{
|
||||
materials_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
spine_player& spine_player::materials(
|
||||
const flat_map<str_hash, material_asset::ptr>& value)
|
||||
{
|
||||
materials_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
spine_player& spine_player::skin(const str& value) noexcept {
|
||||
if ( !spSkeleton_setSkinByName(skeleton_.get(), value.empty() ? nullptr : value.c_str()) ) {
|
||||
the<debug>().error("SPINE_PLAYER: can't set skin '%0'", value);
|
||||
bool spine_player::skin(str_view name) {
|
||||
if ( !skeleton_ ) {
|
||||
return false;
|
||||
}
|
||||
return *this;
|
||||
|
||||
static thread_local str skin_name;
|
||||
skin_name = name;
|
||||
|
||||
return !!spSkeleton_setSkinByName(
|
||||
skeleton_.get(), skin_name.c_str());
|
||||
}
|
||||
|
||||
spine_player& spine_player::attachment(const str& slot, const str& name) noexcept {
|
||||
if ( !spSkeleton_setAttachment(skeleton_.get(), slot.c_str(), name.c_str()) ) {
|
||||
the<debug>().error("SPINE_PLAYER: can't set attachment '%0' to slot '%1'", name, slot);
|
||||
bool spine_player::attachment(str_view slot, str_view name) {
|
||||
if ( !skeleton_ ) {
|
||||
return false;
|
||||
}
|
||||
return *this;
|
||||
|
||||
static thread_local str slot_name;
|
||||
slot_name = slot;
|
||||
|
||||
static thread_local str attachment_name;
|
||||
attachment_name = name;
|
||||
|
||||
return !!spSkeleton_setAttachment(
|
||||
skeleton_.get(), slot_name.c_str(), attachment_name.c_str());
|
||||
}
|
||||
|
||||
bool spine_player::has_skin(const str& name) const noexcept {
|
||||
return spine_
|
||||
&& spine()->content().skeleton()
|
||||
&& spSkeletonData_findSkin(spine()->content().skeleton().get(), name.c_str());
|
||||
bool spine_player::has_skin(str_view name) const noexcept {
|
||||
if ( !skeleton_ ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < skeleton_->data->skinsCount; ++i ) {
|
||||
if ( name == skeleton_->data->skins[i]->name ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool spine_player::has_animation(const str& name) const noexcept {
|
||||
return spine_
|
||||
&& spine()->content().skeleton()
|
||||
&& spSkeletonData_findAnimation(spine()->content().skeleton().get(), name.c_str());
|
||||
bool spine_player::has_animation(str_view name) const noexcept {
|
||||
if ( !skeleton_ ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < skeleton_->data->animationsCount; ++i ) {
|
||||
if ( name == skeleton_->data->animations[i]->name ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const spine_asset::ptr& spine_player::spine() const noexcept {
|
||||
@@ -105,16 +120,21 @@ namespace e2d
|
||||
return animation_;
|
||||
}
|
||||
|
||||
spine_player& spine_player::materials(flat_map<str_hash, material_asset::ptr> value) noexcept {
|
||||
materials_ = std::move(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const flat_map<str_hash, material_asset::ptr>& spine_player::materials() const noexcept {
|
||||
return materials_;
|
||||
}
|
||||
|
||||
material_asset::ptr spine_player::find_material(str_hash name) const noexcept {
|
||||
const auto iter = materials_.find(name);
|
||||
return iter != materials_.end()
|
||||
? iter->second
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
const flat_map<str_hash, material_asset::ptr>& spine_player::materials() const noexcept {
|
||||
return materials_;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
|
||||
@@ -1,398 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/components/spine_player_cmd.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
std::optional<spine_player_cmd::clear_track_cmd> parse_clear_track_cmd(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
u32 cmd_track{0u};
|
||||
if ( !json_utils::try_parse_value(root["track"], cmd_track) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'clear_track_cmd.track' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return spine_player_cmd::clear_track_cmd(cmd_track);
|
||||
}
|
||||
|
||||
std::optional<spine_player_cmd::set_anim_cmd> parse_set_anim_cmd(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
u32 cmd_track{0u};
|
||||
E2D_ASSERT(root.HasMember("track"));
|
||||
if ( !json_utils::try_parse_value(root["track"], cmd_track) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_anim_cmd.track' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
str cmd_name;
|
||||
E2D_ASSERT(root.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(root["name"], cmd_name) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_anim_cmd.name' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
spine_player_cmd::set_anim_cmd cmd(cmd_track, std::move(cmd_name));
|
||||
|
||||
if ( root.HasMember("loop") ) {
|
||||
bool cmd_loop = cmd.loop();
|
||||
if ( !json_utils::try_parse_value(root["loop"], cmd_loop) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_anim_cmd.loop' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.loop(cmd_loop);
|
||||
}
|
||||
|
||||
if ( root.HasMember("end_message") ) {
|
||||
str cmd_end_message = cmd.end_message();
|
||||
if ( !json_utils::try_parse_value(root["end_message"], cmd_end_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_anim_cmd.end_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.end_message(std::move(cmd_end_message));
|
||||
}
|
||||
|
||||
if ( root.HasMember("complete_message") ) {
|
||||
str cmd_complete_message = cmd.complete_message();
|
||||
if ( !json_utils::try_parse_value(root["complete_message"], cmd_complete_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_anim_cmd.complete_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.complete_message(std::move(cmd_complete_message));
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
std::optional<spine_player_cmd::add_anim_cmd> parse_add_anim_cmd(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
u32 cmd_track{0u};
|
||||
E2D_ASSERT(root.HasMember("track"));
|
||||
if ( !json_utils::try_parse_value(root["track"], cmd_track) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.track' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
str cmd_name;
|
||||
E2D_ASSERT(root.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(root["name"], cmd_name) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.name' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
spine_player_cmd::add_anim_cmd cmd(cmd_track, std::move(cmd_name));
|
||||
|
||||
if ( root.HasMember("loop") ) {
|
||||
bool cmd_loop = cmd.loop();
|
||||
if ( !json_utils::try_parse_value(root["loop"], cmd_loop) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.loop' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.loop(cmd_loop);
|
||||
}
|
||||
|
||||
if ( root.HasMember("delay") ) {
|
||||
secf cmd_delay = cmd.delay();
|
||||
if ( !json_utils::try_parse_value(root["delay"], cmd_delay) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.delay' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.delay(cmd_delay);
|
||||
}
|
||||
|
||||
if ( root.HasMember("end_message") ) {
|
||||
str cmd_end_message = cmd.end_message();
|
||||
if ( !json_utils::try_parse_value(root["end_message"], cmd_end_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.end_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.end_message(std::move(cmd_end_message));
|
||||
}
|
||||
|
||||
if ( root.HasMember("complete_message") ) {
|
||||
str cmd_complete_message = cmd.complete_message();
|
||||
if ( !json_utils::try_parse_value(root["complete_message"], cmd_complete_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_anim_cmd.complete_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.complete_message(std::move(cmd_complete_message));
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
std::optional<spine_player_cmd::set_empty_anim_cmd> parse_set_empty_anim_cmd(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
u32 cmd_track{0u};
|
||||
E2D_ASSERT(root.HasMember("track"));
|
||||
if ( !json_utils::try_parse_value(root["track"], cmd_track) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_empty_anim_cmd.track' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
spine_player_cmd::set_empty_anim_cmd cmd(cmd_track);
|
||||
|
||||
if ( root.HasMember("mix_duration") ) {
|
||||
secf cmd_mix_duration = cmd.mix_duration();
|
||||
if ( !json_utils::try_parse_value(root["mix_duration"], cmd_mix_duration) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_empty_anim_cmd.mix_duration' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.mix_duration(cmd_mix_duration);
|
||||
}
|
||||
|
||||
if ( root.HasMember("end_message") ) {
|
||||
str cmd_end_message = cmd.end_message();
|
||||
if ( !json_utils::try_parse_value(root["end_message"], cmd_end_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_empty_anim_cmd.end_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.end_message(std::move(cmd_end_message));
|
||||
}
|
||||
|
||||
if ( root.HasMember("complete_message") ) {
|
||||
str cmd_complete_message = cmd.complete_message();
|
||||
if ( !json_utils::try_parse_value(root["complete_message"], cmd_complete_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'set_empty_anim_cmd.complete_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.complete_message(std::move(cmd_complete_message));
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
std::optional<spine_player_cmd::add_empty_anim_cmd> parse_add_empty_anim_cmd(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
u32 cmd_track{0u};
|
||||
E2D_ASSERT(root.HasMember("track"));
|
||||
if ( !json_utils::try_parse_value(root["track"], cmd_track) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_empty_anim_cmd.track' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
spine_player_cmd::add_empty_anim_cmd cmd(cmd_track);
|
||||
|
||||
if ( root.HasMember("delay") ) {
|
||||
secf cmd_delay = cmd.delay();
|
||||
if ( !json_utils::try_parse_value(root["delay"], cmd_delay) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_empty_anim_cmd.delay' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.delay(cmd_delay);
|
||||
}
|
||||
|
||||
if ( root.HasMember("mix_duration") ) {
|
||||
secf cmd_mix_duration = cmd.mix_duration();
|
||||
if ( !json_utils::try_parse_value(root["mix_duration"], cmd_mix_duration) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_empty_anim_cmd.mix_duration' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.mix_duration(cmd_mix_duration);
|
||||
}
|
||||
|
||||
if ( root.HasMember("end_message") ) {
|
||||
str cmd_end_message = cmd.end_message();
|
||||
if ( !json_utils::try_parse_value(root["end_message"], cmd_end_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_empty_anim_cmd.end_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.end_message(std::move(cmd_end_message));
|
||||
}
|
||||
|
||||
if ( root.HasMember("complete_message") ) {
|
||||
str cmd_complete_message = cmd.complete_message();
|
||||
if ( !json_utils::try_parse_value(root["complete_message"], cmd_complete_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'add_empty_anim_cmd.complete_message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
cmd.complete_message(std::move(cmd_complete_message));
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
std::optional<spine_player_cmd::command> parse_command(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
str_hash command_type;
|
||||
E2D_ASSERT(root.HasMember("type") && root["type"].IsString());
|
||||
if ( !json_utils::try_parse_value(root["type"], command_type) ) {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'command.type' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
E2D_ASSERT(root.HasMember("desc") && root["desc"].IsObject());
|
||||
const auto& command_desc = root["desc"];
|
||||
|
||||
if ( command_type == make_hash("clear_track_cmd") ) {
|
||||
auto cmd = parse_clear_track_cmd(command_desc);
|
||||
return cmd ? cmd : std::nullopt;
|
||||
} else if ( command_type == make_hash("set_anim_cmd") ) {
|
||||
auto cmd = parse_set_anim_cmd(command_desc);
|
||||
return cmd ? cmd : std::nullopt;
|
||||
} else if ( command_type == make_hash("add_anim_cmd") ) {
|
||||
auto cmd = parse_add_anim_cmd(command_desc);
|
||||
return cmd ? cmd : std::nullopt;
|
||||
} else if ( command_type == make_hash("set_empty_anim_cmd") ) {
|
||||
auto cmd = parse_set_empty_anim_cmd(command_desc);
|
||||
return cmd ? cmd : std::nullopt;
|
||||
} else if ( command_type == make_hash("add_empty_anim_cmd") ) {
|
||||
auto cmd = parse_add_empty_anim_cmd(command_desc);
|
||||
return cmd ? cmd : std::nullopt;
|
||||
} else {
|
||||
the<debug>().error("SPINE_PLAYER_CMD: Incorrect formatting of 'command.type' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<vector<spine_player_cmd::command>> parse_commands(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsArray());
|
||||
|
||||
vector<spine_player_cmd::command> cmds;
|
||||
cmds.reserve(root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < root.Size(); ++i ) {
|
||||
auto cmd = parse_command(root[i]);
|
||||
if ( !cmd ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
cmds.push_back(std::move(cmd.value()));
|
||||
}
|
||||
|
||||
return cmds;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<spine_player_cmd>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"commands" : { "$ref": "#/definitions/commands" }
|
||||
},
|
||||
"definitions" : {
|
||||
"commands" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/command" }
|
||||
},
|
||||
"command" : {
|
||||
"type" : "object",
|
||||
"required" : [ "type", "desc" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"type" : { "$ref": "#/common_definitions/name" },
|
||||
"desc" : {
|
||||
"anyOf" : [{
|
||||
"$ref" : "#/definitions/clear_track_cmd"
|
||||
}, {
|
||||
"$ref" : "#/definitions/set_anim_cmd"
|
||||
}, {
|
||||
"$ref" : "#/definitions/add_anim_cmd"
|
||||
}, {
|
||||
"$ref" : "#/definitions/set_empty_anim_cmd"
|
||||
}, {
|
||||
"$ref" : "#/definitions/add_empty_anim_cmd"
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"clear_track_cmd" : {
|
||||
"type" : "object",
|
||||
"required" : [ "track" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"track" : { "type" : "integer", "minimum" : 0 }
|
||||
}
|
||||
},
|
||||
"set_anim_cmd" : {
|
||||
"type" : "object",
|
||||
"required" : [ "track", "name" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"track" : { "type" : "integer", "minimum" : 0 },
|
||||
"name" : { "$ref": "#/common_definitions/name" },
|
||||
"loop" : { "type" : "boolean" },
|
||||
"end_message" : { "type" : "string" },
|
||||
"complete_message" : { "type" : "string" }
|
||||
}
|
||||
},
|
||||
"add_anim_cmd" : {
|
||||
"type" : "object",
|
||||
"required" : [ "track", "name" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"track" : { "type" : "integer", "minimum" : 0 },
|
||||
"name" : { "$ref": "#/common_definitions/name" },
|
||||
"loop" : { "type" : "boolean" },
|
||||
"delay" : { "type" : "number" },
|
||||
"end_message" : { "type" : "string" },
|
||||
"complete_message" : { "type" : "string" }
|
||||
}
|
||||
},
|
||||
"set_empty_anim_cmd" : {
|
||||
"type" : "object",
|
||||
"required" : [ "track" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"track" : { "type" : "integer", "minimum" : 0 },
|
||||
"mix_duration" : { "type" : "number" },
|
||||
"end_message" : { "type" : "string" },
|
||||
"complete_message" : { "type" : "string" }
|
||||
}
|
||||
},
|
||||
"add_empty_anim_cmd" : {
|
||||
"type" : "object",
|
||||
"required" : [ "track" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"track" : { "type" : "integer", "minimum" : 0 },
|
||||
"delay" : { "type" : "number" },
|
||||
"mix_duration" : { "type" : "number" },
|
||||
"end_message" : { "type" : "string" },
|
||||
"complete_message" : { "type" : "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
})json";
|
||||
|
||||
bool factory_loader<spine_player_cmd>::operator()(
|
||||
spine_player_cmd& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
if ( ctx.root.HasMember("commands") ) {
|
||||
auto cmds = parse_commands(ctx.root["commands"]);
|
||||
if ( !cmds ) {
|
||||
return false;
|
||||
}
|
||||
for ( auto& cmd : cmds.value() ) {
|
||||
if ( cmd.valueless_by_exception() ) {
|
||||
return false;
|
||||
}
|
||||
component.add_command(std::move(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<spine_player_cmd>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(dependencies, ctx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/components/spine_player_evt.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
std::optional<spine_player_evt::custom_evt> parse_custom_evt(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
str_hash evt_name;
|
||||
E2D_ASSERT(root.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(root["name"], evt_name) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'custom_evt.name' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
spine_player_evt::custom_evt evt(evt_name);
|
||||
|
||||
if ( root.HasMember("int_value") ) {
|
||||
i32 evt_int_value = evt.int_value();
|
||||
if ( !json_utils::try_parse_value(root["int_value"], evt_int_value) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'custom_evt.int_value' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
evt.int_value(evt_int_value);
|
||||
}
|
||||
|
||||
if ( root.HasMember("float_value") ) {
|
||||
f32 evt_float_value = evt.float_value();
|
||||
if ( !json_utils::try_parse_value(root["float_value"], evt_float_value) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'custom_evt.float_value' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
evt.float_value(evt_float_value);
|
||||
}
|
||||
|
||||
if ( root.HasMember("string_value") ) {
|
||||
str evt_string_value = evt.string_value();
|
||||
if ( !json_utils::try_parse_value(root["string_value"], evt_string_value) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'custom_evt.string_value' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
evt.string_value(evt_string_value);
|
||||
}
|
||||
|
||||
return evt;
|
||||
}
|
||||
|
||||
std::optional<spine_player_evt::end_evt> parse_end_evt(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
str evt_message;
|
||||
E2D_ASSERT(root.HasMember("message"));
|
||||
if ( !json_utils::try_parse_value(root["message"], evt_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'end_evt.message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return spine_player_evt::end_evt(evt_message);
|
||||
}
|
||||
|
||||
std::optional<spine_player_evt::complete_evt> parse_complete_evt(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
str evt_message;
|
||||
E2D_ASSERT(root.HasMember("message"));
|
||||
if ( !json_utils::try_parse_value(root["message"], evt_message) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'complete_evt.message' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return spine_player_evt::complete_evt(evt_message);
|
||||
}
|
||||
|
||||
std::optional<spine_player_evt::event> parse_event(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
str_hash event_type;
|
||||
E2D_ASSERT(root.HasMember("type") && root["type"].IsString());
|
||||
if ( !json_utils::try_parse_value(root["type"], event_type) ) {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'event.type' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
E2D_ASSERT(root.HasMember("desc") && root["desc"].IsObject());
|
||||
const auto& event_desc = root["desc"];
|
||||
|
||||
if ( event_type == make_hash("custom_evt") ) {
|
||||
auto evt = parse_custom_evt(event_desc);
|
||||
return evt ? evt : std::nullopt;
|
||||
} else if ( event_type == make_hash("end_evt") ) {
|
||||
auto evt = parse_end_evt(event_desc);
|
||||
return evt ? evt : std::nullopt;
|
||||
} else if ( event_type == make_hash("complete_evt") ) {
|
||||
auto evt = parse_complete_evt(event_desc);
|
||||
return evt ? evt : std::nullopt;
|
||||
} else {
|
||||
the<debug>().error("SPINE_PLAYER_EVT: Incorrect formatting of 'event.type' property");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<vector<spine_player_evt::event>> parse_events(const rapidjson::Value& root) {
|
||||
E2D_ASSERT(root.IsArray());
|
||||
|
||||
vector<spine_player_evt::event> evts;
|
||||
evts.reserve(root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < root.Size(); ++i ) {
|
||||
auto evt = parse_event(root[i]);
|
||||
if ( !evt ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
evts.push_back(std::move(evt.value()));
|
||||
}
|
||||
|
||||
return evts;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
const char* factory_loader<spine_player_evt>::schema_source = R"json({
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"events" : { "$ref": "#/definitions/events" }
|
||||
},
|
||||
"definitions" : {
|
||||
"events" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/event" }
|
||||
},
|
||||
"event" : {
|
||||
"type" : "object",
|
||||
"required" : [ "type", "desc" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"type" : { "$ref": "#/common_definitions/name" },
|
||||
"desc" : {
|
||||
"anyOf" : [{
|
||||
"$ref" : "#/definitions/custom_evt"
|
||||
},{
|
||||
"$ref" : "#/definitions/end_evt"
|
||||
},{
|
||||
"$ref" : "#/definitions/complete_evt"
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"custom_evt" : {
|
||||
"type" : "object",
|
||||
"required" : [ "name" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"name" : { "$ref": "#/common_definitions/name" },
|
||||
"int_value" : { "type" : "integer" },
|
||||
"float_value" : { "type" : "number" },
|
||||
"string_value" : { "type" : "string" }
|
||||
}
|
||||
},
|
||||
"end_evt" : {
|
||||
"type" : "object",
|
||||
"required" : [ "message" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"message" : { "$ref": "#/common_definitions/name" }
|
||||
}
|
||||
},
|
||||
"complete_evt" : {
|
||||
"type" : "object",
|
||||
"required" : [ "message" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"message" : { "$ref": "#/common_definitions/name" }
|
||||
}
|
||||
}
|
||||
}
|
||||
})json";
|
||||
|
||||
bool factory_loader<spine_player_evt>::operator()(
|
||||
spine_player_evt& component,
|
||||
const fill_context& ctx) const
|
||||
{
|
||||
if ( ctx.root.HasMember("events") ) {
|
||||
auto evts = parse_events(ctx.root["events"]);
|
||||
if ( !evts ) {
|
||||
return false;
|
||||
}
|
||||
for ( auto& evt : evts.value() ) {
|
||||
if ( evt.valueless_by_exception() ) {
|
||||
return false;
|
||||
}
|
||||
component.add_event(std::move(evt));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool factory_loader<spine_player_evt>::operator()(
|
||||
asset_dependencies& dependencies,
|
||||
const collect_context& ctx) const
|
||||
{
|
||||
E2D_UNUSED(dependencies, ctx);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <enduro2d/high/components/renderer.hpp>
|
||||
#include <enduro2d/high/components/scene.hpp>
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/spine_player_cmd.hpp>
|
||||
#include <enduro2d/high/components/spine_player_evt.hpp>
|
||||
#include <enduro2d/high/components/sprite_renderer.hpp>
|
||||
|
||||
#include <enduro2d/high/systems/flipbook_system.hpp>
|
||||
@@ -188,8 +186,6 @@ namespace e2d
|
||||
.register_component<renderer>("renderer")
|
||||
.register_component<scene>("scene")
|
||||
.register_component<spine_player>("spine_player")
|
||||
.register_component<spine_player_cmd>("spine_player_cmd")
|
||||
.register_component<spine_player_evt>("spine_player_evt")
|
||||
.register_component<sprite_renderer>("sprite_renderer");
|
||||
|
||||
safe_module_initialize<luasol>();
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <enduro2d/high/components/actor.hpp>
|
||||
#include <enduro2d/high/components/behaviour.hpp>
|
||||
#include <enduro2d/high/components/disabled.hpp>
|
||||
#include <enduro2d/high/components/spine_player_evt.hpp>
|
||||
#include <enduro2d/high/components/events.hpp>
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -45,23 +46,23 @@ namespace
|
||||
}
|
||||
|
||||
void process_spine_player_events(ecs::registry& owner) {
|
||||
systems::for_extracted_components<spine_player_evt, behaviour, actor>(owner,
|
||||
[](ecs::entity e, const spine_player_evt& spe, behaviour& b, actor& a){
|
||||
systems::for_extracted_components<events<spine_player_events::event>, behaviour, actor>(owner,
|
||||
[](ecs::entity e, const events<spine_player_events::event>& es, behaviour& b, actor& a){
|
||||
if ( !a.node() || !a.node()->owner() ) {
|
||||
return;
|
||||
}
|
||||
for ( const spine_player_evt::event& evt : spe.events() ) {
|
||||
for ( const spine_player_events::event& evt : es ) {
|
||||
behaviours::call_result r = behaviours::call_result::success;
|
||||
std::visit(utils::overloaded {
|
||||
[&b,&a,&r](const spine_player_evt::custom_evt& e){
|
||||
[&b,&a,&r](const spine_player_events::custom_evt& e){
|
||||
r = behaviours::call_meta_method(
|
||||
b, "on_event", a.node()->owner(), "spine_player.custom_evt", e);
|
||||
},
|
||||
[&b,&a,&r](const spine_player_evt::end_evt& e){
|
||||
[&b,&a,&r](const spine_player_events::end_evt& e){
|
||||
r = behaviours::call_meta_method(
|
||||
b, "on_event", a.node()->owner(), "spine_player.end_evt", e);
|
||||
},
|
||||
[&b,&a,&r](const spine_player_evt::complete_evt& e){
|
||||
[&b,&a,&r](const spine_player_events::complete_evt& e){
|
||||
r = behaviours::call_meta_method(
|
||||
b, "on_event", a.node()->owner(), "spine_player.complete_evt", e);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
#include <enduro2d/high/systems/spine_system.hpp>
|
||||
|
||||
#include <enduro2d/high/components/events.hpp>
|
||||
#include <enduro2d/high/components/commands.hpp>
|
||||
#include <enduro2d/high/components/spine_player.hpp>
|
||||
#include <enduro2d/high/components/spine_player_cmd.hpp>
|
||||
#include <enduro2d/high/components/spine_player_evt.hpp>
|
||||
|
||||
#include <spine/spine.h>
|
||||
|
||||
@@ -50,23 +50,26 @@ namespace
|
||||
if ( !event || !event->data ) {
|
||||
return;
|
||||
}
|
||||
entry_state.target.ensure_component<spine_player_evt>()
|
||||
.add_event(spine_player_evt::custom_evt(event->data->name ? event->data->name : "")
|
||||
.int_value(event->intValue)
|
||||
.float_value(event->floatValue)
|
||||
.string_value(event->stringValue ? event->stringValue : ""));
|
||||
entry_state.target
|
||||
.ensure_component<events<spine_player_events::event>>()
|
||||
.add(spine_player_events::custom_evt(event->data->name ? event->data->name : "")
|
||||
.int_value(event->intValue)
|
||||
.float_value(event->floatValue)
|
||||
.string_value(event->stringValue ? event->stringValue : ""));
|
||||
} else if ( type == SP_ANIMATION_END ) {
|
||||
if ( entry_state.end_message.empty() ) {
|
||||
return;
|
||||
}
|
||||
entry_state.target.ensure_component<spine_player_evt>()
|
||||
.add_event(spine_player_evt::end_evt(entry_state.end_message));
|
||||
entry_state.target
|
||||
.ensure_component<events<spine_player_events::event>>()
|
||||
.add(spine_player_events::end_evt(entry_state.end_message));
|
||||
} else if ( type == SP_ANIMATION_COMPLETE ) {
|
||||
if ( entry_state.complete_message.empty() ) {
|
||||
return;
|
||||
}
|
||||
entry_state.target.ensure_component<spine_player_evt>()
|
||||
.add_event(spine_player_evt::complete_evt(entry_state.complete_message));
|
||||
entry_state.target
|
||||
.ensure_component<events<spine_player_events::event>>()
|
||||
.add(spine_player_events::complete_evt(entry_state.complete_message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,13 +83,13 @@ namespace
|
||||
, skeleton_data_(skeleton_data)
|
||||
, animation_state_(animation_state) {}
|
||||
|
||||
void operator()(const spine_player_cmd::clear_track_cmd& cmd) const noexcept {
|
||||
void operator()(const spine_player_commands::clear_track_cmd& cmd) const noexcept {
|
||||
spAnimationState_clearTrack(
|
||||
&animation_state_,
|
||||
math::numeric_cast<int>(cmd.track()));
|
||||
}
|
||||
|
||||
void operator()(const spine_player_cmd::set_anim_cmd& cmd) const noexcept {
|
||||
void operator()(const spine_player_commands::set_anim_cmd& cmd) const noexcept {
|
||||
spAnimation* animation = spSkeletonData_findAnimation(&skeleton_data_, cmd.name().c_str());
|
||||
if ( !animation ) {
|
||||
the<debug>().error("SPINE_POST_SYSTEM: animation '%0' is not found", cmd.name());
|
||||
@@ -108,7 +111,7 @@ namespace
|
||||
entry->userData = entry_state.release();
|
||||
}
|
||||
|
||||
void operator()(const spine_player_cmd::add_anim_cmd& cmd) const noexcept {
|
||||
void operator()(const spine_player_commands::add_anim_cmd& cmd) const noexcept {
|
||||
spAnimation* animation = spSkeletonData_findAnimation(&skeleton_data_, cmd.name().c_str());
|
||||
if ( !animation ) {
|
||||
the<debug>().error("SPINE_POST_SYSTEM: animation '%0' is not found", cmd.name());
|
||||
@@ -125,13 +128,13 @@ namespace
|
||||
math::numeric_cast<int>(cmd.track()),
|
||||
animation,
|
||||
cmd.loop() ? 1 : 0,
|
||||
cmd.delay().value);
|
||||
cmd.delay());
|
||||
|
||||
entry->listener = &entry_listener;
|
||||
entry->userData = entry_state.release();
|
||||
}
|
||||
|
||||
void operator()(const spine_player_cmd::set_empty_anim_cmd& cmd) const noexcept {
|
||||
void operator()(const spine_player_commands::set_empty_anim_cmd& cmd) const noexcept {
|
||||
auto entry_state = std::make_unique<entry_internal_state>(
|
||||
target_,
|
||||
cmd.end_message(),
|
||||
@@ -140,13 +143,13 @@ namespace
|
||||
spTrackEntry* entry = spAnimationState_setEmptyAnimation(
|
||||
&animation_state_,
|
||||
math::numeric_cast<int>(cmd.track()),
|
||||
cmd.mix_duration().value);
|
||||
cmd.mix_duration());
|
||||
|
||||
entry->listener = &entry_listener;
|
||||
entry->userData = entry_state.release();
|
||||
}
|
||||
|
||||
void operator()(const spine_player_cmd::add_empty_anim_cmd& cmd) const noexcept {
|
||||
void operator()(const spine_player_commands::add_empty_anim_cmd& cmd) const noexcept {
|
||||
auto entry_state = std::make_unique<entry_internal_state>(
|
||||
target_,
|
||||
cmd.end_message(),
|
||||
@@ -155,8 +158,8 @@ namespace
|
||||
spTrackEntry* entry = spAnimationState_addEmptyAnimation(
|
||||
&animation_state_,
|
||||
math::numeric_cast<int>(cmd.track()),
|
||||
cmd.mix_duration().value,
|
||||
cmd.delay().value);
|
||||
cmd.mix_duration(),
|
||||
cmd.delay());
|
||||
|
||||
entry->listener = &entry_listener;
|
||||
entry->userData = entry_state.release();
|
||||
@@ -168,9 +171,9 @@ namespace
|
||||
};
|
||||
|
||||
void clear_events(ecs::registry& owner) {
|
||||
owner.for_each_component<spine_player_evt>([
|
||||
](const ecs::const_entity&, spine_player_evt& pe) {
|
||||
pe.clear_events();
|
||||
owner.for_each_component<events<spine_player_events::event>>([
|
||||
](const ecs::const_entity&, events<spine_player_events::event>& es) {
|
||||
es.clear();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,9 +197,9 @@ namespace
|
||||
}
|
||||
|
||||
void process_commands(ecs::registry& owner) {
|
||||
owner.for_joined_components<spine_player_cmd, spine_player>([](
|
||||
owner.for_joined_components<commands<spine_player_commands::command>, spine_player>([](
|
||||
ecs::entity e,
|
||||
const spine_player_cmd& pc,
|
||||
const commands<spine_player_commands::command>& cs,
|
||||
spine_player& p)
|
||||
{
|
||||
spSkeleton* skeleton = p.skeleton().get();
|
||||
@@ -207,16 +210,16 @@ namespace
|
||||
}
|
||||
|
||||
command_visitor v(e, *skeleton->data, *animation_state);
|
||||
for ( const auto& cmd : pc.commands() ) {
|
||||
for ( const auto& cmd : cs ) {
|
||||
std::visit(v, cmd);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void clear_commands(ecs::registry& owner) {
|
||||
owner.for_each_component<spine_player_cmd>([
|
||||
](const ecs::const_entity&, spine_player_cmd& pc) {
|
||||
pc.clear_commands();
|
||||
owner.for_each_component<commands<spine_player_commands::command>>([
|
||||
](const ecs::const_entity&, commands<spine_player_commands::command>& cs) {
|
||||
cs.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user