rewrite update systems logic to features and events

This commit is contained in:
2019-10-19 08:53:53 +07:00
parent f7db4a45d8
commit 3ce725c440
19 changed files with 250 additions and 215 deletions

View File

@@ -42,7 +42,7 @@
#include "systems/flipbook_system.hpp"
#include "systems/label_system.hpp"
#include "systems/render_system.hpp"
#include "systems/spine_systems.hpp"
#include "systems/spine_system.hpp"
#include "address.hpp"
#include "asset.hpp"

View File

@@ -54,8 +54,7 @@ namespace e2d
class flipbook_system;
class label_system;
class render_system;
class spine_pre_system;
class spine_post_system;
class spine_system;
template < typename Asset, typename Content >
class content_asset;

View File

@@ -0,0 +1,37 @@
/*******************************************************************************
* 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::systems
{
struct update_event {
f32 dt{0.f};
f32 time{0.f};
};
struct pre_update_event {
f32 dt{0.f};
f32 time{0.f};
};
struct post_update_event {
f32 dt{0.f};
f32 time{0.f};
};
struct render_event {};
struct pre_render_event {};
struct post_render_event {};
using update_system = ecs::system<update_event>;
using post_update_system = ecs::system<post_update_event>;
using render_system = ecs::system<render_event>;
using post_render_system = ecs::system<post_render_event>;
}

View File

@@ -6,15 +6,19 @@
#pragma once
#include "../_high.hpp"
#include "_systems.hpp"
namespace e2d
{
class flipbook_system final : public ecs::system {
class flipbook_system final
: public ecs::system<ecs::after<systems::update_event>> {
public:
flipbook_system();
~flipbook_system() noexcept final;
void process(ecs::registry& owner) override;
~flipbook_system() noexcept;
void process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;

View File

@@ -6,15 +6,19 @@
#pragma once
#include "../_high.hpp"
#include "_systems.hpp"
namespace e2d
{
class label_system final : public ecs::system {
class label_system final
: public ecs::system<ecs::after<systems::update_event>> {
public:
label_system();
~label_system() noexcept final;
void process(ecs::registry& owner) override;
void process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;

View File

@@ -6,15 +6,19 @@
#pragma once
#include "../_high.hpp"
#include "_systems.hpp"
namespace e2d
{
class render_system final : public ecs::system {
class render_system final
: public ecs::system<ecs::after<systems::render_event>> {
public:
render_system();
~render_system() noexcept final;
void process(ecs::registry& owner) override;
~render_system() noexcept;
void process(
ecs::registry& owner,
const ecs::after<systems::render_event>& trigger) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;

View File

@@ -0,0 +1,26 @@
/*******************************************************************************
* 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 "_systems.hpp"
namespace e2d
{
class spine_system final
: public ecs::system<ecs::after<systems::update_event>> {
public:
spine_system();
~spine_system() noexcept;
void process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;
};
}

View File

@@ -1,32 +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"
namespace e2d
{
class spine_pre_system final : public ecs::system {
public:
spine_pre_system();
~spine_pre_system() noexcept final;
void process(ecs::registry& owner) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;
};
class spine_post_system final : public ecs::system {
public:
spine_post_system();
~spine_post_system() noexcept final;
void process(ecs::registry& owner) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;
};
}

View File

@@ -14,20 +14,6 @@
namespace e2d
{
class world final : public module<world> {
public:
enum priorities : ecs::priority_t {
priority_update_section_begin = 0,
priority_pre_update = 500,
priority_update = 1000,
priority_post_update = 1500,
priority_update_section_end = 2000,
priority_render_section_begin = 2500,
priority_pre_render = 3000,
priority_render = 3500,
priority_post_render = 4000,
priority_render_section_end = 4500
};
public:
world() = default;
~world() noexcept final;

View File

@@ -13,10 +13,13 @@ namespace
v3f axis;
};
class game_system final : public ecs::system {
class game_system final : public systems::update_system {
public:
void process(ecs::registry& owner) override {
E2D_UNUSED(owner);
void process(
ecs::registry& owner,
const systems::update_event& event) override
{
E2D_UNUSED(owner, event);
const keyboard& k = the<input>().keyboard();
if ( k.is_key_just_released(keyboard_key::f12) ) {
@@ -33,9 +36,13 @@ namespace
}
};
class camera_system final : public ecs::system {
class camera_system final : public systems::render_system {
public:
void process(ecs::registry& owner) override {
void process(
ecs::registry& owner,
const systems::render_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(
[](const ecs::const_entity&, camera& cam){
if ( !cam.target() ) {
@@ -48,18 +55,20 @@ namespace
}
};
class rotator_system final : public ecs::system {
class rotator_system final : public systems::update_system {
public:
void process(ecs::registry& owner) override {
const f32 time = the<engine>().time();
void process(
ecs::registry& owner,
const systems::update_event& event) override
{
owner.for_joined_components<rotator, actor>(
[&time](const ecs::const_entity&, const rotator& rot, actor& act){
const node_iptr node = act.node();
if ( node ) {
const q4f q = math::make_quat_from_axis_angle(make_rad(time), rot.axis);
node->rotation(q);
}
});
[&event](const ecs::const_entity&, const rotator& rot, actor& act){
const node_iptr node = act.node();
if ( node ) {
const q4f q = math::make_quat_from_axis_angle(make_rad(event.time), rot.axis);
node->rotation(q);
}
});
}
};
@@ -154,9 +163,10 @@ namespace
bool create_systems() {
ecs::registry_filler(the<world>().registry())
.system<game_system>(world::priority_update)
.system<rotator_system>(world::priority_update)
.system<camera_system>(world::priority_pre_render);
.feature<struct game_feature>(ecs::feature()
.add_system<game_system>()
.add_system<rotator_system>()
.add_system<camera_system>());
return true;
}
};

View File

@@ -9,10 +9,13 @@ using namespace e2d;
namespace
{
class game_system final : public ecs::system {
class game_system final : public systems::update_system {
public:
void process(ecs::registry& owner) override {
E2D_UNUSED(owner);
void process(
ecs::registry& owner,
const systems::update_event& event) override
{
E2D_UNUSED(owner, event);
const keyboard& k = the<input>().keyboard();
if ( k.is_key_just_released(keyboard_key::f12) ) {
@@ -29,9 +32,13 @@ namespace
}
};
class camera_system final : public ecs::system {
class camera_system final : public systems::render_system {
public:
void process(ecs::registry& owner) override {
void process(
ecs::registry& owner,
const systems::render_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(
[](const ecs::const_entity&, camera& cam){
if ( !cam.target() ) {
@@ -61,8 +68,9 @@ namespace
bool create_systems() {
ecs::registry_filler(the<world>().registry())
.system<game_system>(world::priority_update)
.system<camera_system>(world::priority_pre_render);
.feature<struct game_feature>(ecs::feature()
.add_system<game_system>()
.add_system<camera_system>());
return true;
}
};

View File

@@ -9,10 +9,13 @@ using namespace e2d;
namespace
{
class game_system final : public ecs::system {
class game_system final : public systems::update_system {
public:
void process(ecs::registry& owner) override {
E2D_UNUSED(owner);
void process(
ecs::registry& owner,
const systems::update_event& event) override
{
E2D_UNUSED(owner, event);
const keyboard& k = the<input>().keyboard();
if ( k.is_key_just_released(keyboard_key::f12) ) {
@@ -68,9 +71,13 @@ namespace
}
};
class camera_system final : public ecs::system {
class camera_system final : public systems::render_system {
public:
void process(ecs::registry& owner) override {
void process(
ecs::registry& owner,
const systems::render_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(
[](const ecs::const_entity&, camera& cam){
if ( !cam.target() ) {
@@ -100,8 +107,9 @@ namespace
bool create_systems() {
ecs::registry_filler(the<world>().registry())
.system<game_system>(world::priority_update)
.system<camera_system>(world::priority_pre_render);
.feature<struct game_feature>(ecs::feature()
.add_system<game_system>()
.add_system<camera_system>());
return true;
}
};

View File

@@ -12,7 +12,6 @@
#if E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGL || E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGLES
#if E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGL
# define GLEW_STATIC
# include <GL/glew.h>
#elif E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGLES
# include <GLES2/gl2.h>

View File

@@ -25,7 +25,7 @@
#include <enduro2d/high/systems/flipbook_system.hpp>
#include <enduro2d/high/systems/label_system.hpp>
#include <enduro2d/high/systems/render_system.hpp>
#include <enduro2d/high/systems/spine_systems.hpp>
#include <enduro2d/high/systems/spine_system.hpp>
namespace
{
@@ -45,11 +45,14 @@ namespace
bool initialize() final {
ecs::registry_filler(the<world>().registry())
.system<flipbook_system>(world::priority_pre_update)
.system<label_system>(world::priority_pre_update)
.system<spine_pre_system>(world::priority_pre_update)
.system<spine_post_system>(world::priority_post_update)
.system<render_system>(world::priority_render);
.feature<struct flipbook_feature>(ecs::feature()
.add_system<flipbook_system>())
.feature<struct label_feature>(ecs::feature()
.add_system<label_system>())
.feature<struct spine_feature>(ecs::feature()
.add_system<spine_system>())
.feature<struct render_feature>(ecs::feature()
.add_system<render_system>());
return !application_ || application_->initialize();
}
@@ -60,17 +63,24 @@ namespace
}
bool frame_tick() final {
the<world>().registry().process_systems_in_range(
world::priority_update_section_begin,
world::priority_update_section_end);
engine& e = the<engine>();
const f32 dt = e.delta_time();
const f32 time = e.time();
ecs::registry& registry = the<world>().registry();
registry.process_event(systems::pre_update_event{dt,time});
registry.process_event(systems::update_event{dt,time});
registry.process_event(systems::post_update_event{dt,time});
return !the<window>().should_close()
|| (application_ && !application_->on_should_close());
}
void frame_render() final {
the<world>().registry().process_systems_in_range(
world::priority_render_section_begin,
world::priority_render_section_end);
ecs::registry& registry = the<world>().registry();
registry.process_event(systems::pre_render_event{});
registry.process_event(systems::render_event{});
registry.process_event(systems::post_render_event{});
}
private:
starter::application_uptr application_;

View File

@@ -82,8 +82,8 @@ namespace e2d
internal_state() = default;
~internal_state() noexcept = default;
void process(ecs::registry& owner) {
update_flipbook_timers(the<engine>().delta_time(), owner);
void process(f32 dt, ecs::registry& owner) {
update_flipbook_timers(dt, owner);
update_flipbook_sprites(owner);
}
};
@@ -96,7 +96,10 @@ namespace e2d
: state_(new internal_state()) {}
flipbook_system::~flipbook_system() noexcept = default;
void flipbook_system::process(ecs::registry& owner) {
state_->process(owner);
void flipbook_system::process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger)
{
state_->process(trigger.event.dt, owner);
}
}

View File

@@ -382,7 +382,11 @@ namespace e2d
: state_(new internal_state()) {}
label_system::~label_system() noexcept = default;
void label_system::process(ecs::registry& owner) {
void label_system::process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger)
{
E2D_UNUSED(trigger);
state_->process(owner);
}
}

View File

@@ -117,7 +117,11 @@ namespace e2d
: state_(new internal_state()) {}
render_system::~render_system() noexcept = default;
void render_system::process(ecs::registry& owner) {
void render_system::process(
ecs::registry& owner,
const ecs::after<systems::render_event>& trigger)
{
E2D_UNUSED(trigger);
state_->process(owner);
}
}

View File

@@ -1,62 +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/systems/spine_systems.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>
namespace e2d
{
//
// internal_state
//
class spine_pre_system::internal_state final {
public:
internal_state() = default;
~internal_state() noexcept = default;
void process(ecs::registry& owner) {
update_animations(owner);
}
private:
void update_animations(ecs::registry& owner) {
const float dt = the<engine>().delta_time();
owner.for_each_component<spine_player>([dt](
const ecs::const_entity&,
spine_player& p)
{
spSkeleton* skeleton = p.skeleton().get();
spAnimationState* anim_state = p.animation().get();
if ( !skeleton || !anim_state ) {
return;
}
spSkeleton_update(skeleton, dt);
spAnimationState_update(anim_state, dt);
spAnimationState_apply(anim_state, skeleton);
spSkeleton_updateWorldTransform(skeleton);
});
}
};
//
// spine_pre_system
//
spine_pre_system::spine_pre_system()
: state_(new internal_state()) {}
spine_pre_system::~spine_pre_system() noexcept = default;
void spine_pre_system::process(ecs::registry& owner) {
state_->process(owner);
}
}

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include <enduro2d/high/systems/spine_systems.hpp>
#include <enduro2d/high/systems/spine_system.hpp>
#include <enduro2d/high/components/spine_player.hpp>
#include <enduro2d/high/components/spine_player_cmd.hpp>
@@ -166,6 +166,59 @@ namespace
spSkeletonData& skeleton_data_;
spAnimationState& animation_state_;
};
void clear_events(ecs::registry& owner) {
owner.for_each_component<spine_player_evt>([
](const ecs::const_entity&, spine_player_evt& pe) {
pe.clear_events();
});
}
void update_animations(f32 dt, ecs::registry& owner) {
owner.for_each_component<spine_player>([dt](
const ecs::const_entity&,
spine_player& p)
{
spSkeleton* skeleton = p.skeleton().get();
spAnimationState* anim_state = p.animation().get();
if ( !skeleton || !anim_state ) {
return;
}
spSkeleton_update(skeleton, dt);
spAnimationState_update(anim_state, dt);
spAnimationState_apply(anim_state, skeleton);
spSkeleton_updateWorldTransform(skeleton);
});
}
void process_commands(ecs::registry& owner) {
owner.for_joined_components<spine_player_cmd, spine_player>([](
ecs::entity e,
const spine_player_cmd& pc,
spine_player& p)
{
spSkeleton* skeleton = p.skeleton().get();
spAnimationState* animation_state = p.animation().get();
if ( !skeleton || !skeleton->data || !animation_state ) {
return;
}
command_visitor v(e, *skeleton->data, *animation_state);
for ( const auto& cmd : pc.commands() ) {
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();
});
}
}
namespace e2d
@@ -174,64 +227,34 @@ namespace e2d
// internal_state
//
class spine_post_system::internal_state final {
class spine_system::internal_state final {
public:
internal_state() = default;
~internal_state() noexcept = default;
void process(ecs::registry& owner) {
void process(f32 dt, ecs::registry& owner) {
process_commands(owner);
clear_commands(owner);
clear_events(owner);
}
private:
void process_commands(ecs::registry& owner) {
owner.for_joined_components<spine_player_cmd, spine_player>([](
ecs::entity e,
const spine_player_cmd& pc,
spine_player& p)
{
spSkeleton* skeleton = p.skeleton().get();
spAnimationState* animation_state = p.animation().get();
if ( !skeleton || !skeleton->data || !animation_state ) {
return;
}
command_visitor v(e, *skeleton->data, *animation_state);
for ( const auto& cmd : pc.commands() ) {
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();
});
}
void clear_events(ecs::registry& owner) {
owner.for_each_component<spine_player_evt>([
](const ecs::const_entity&, spine_player_evt& pe) {
pe.clear_events();
});
update_animations(dt, owner);
}
};
//
// spine_post_system
// spine_system
//
spine_post_system::spine_post_system()
spine_system::spine_system()
: state_(new internal_state()) {}
spine_post_system::~spine_post_system() noexcept {
spine_system::~spine_system() noexcept {
spAnimationState_disposeStatics();
}
void spine_post_system::process(ecs::registry& owner) {
state_->process(owner);
void spine_system::process(
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger)
{
state_->process(trigger.event.dt, owner);
}
}