separate ecs render event by cameras

This commit is contained in:
2020-01-21 03:32:32 +07:00
parent 771ab9008a
commit aa0d0fda15
21 changed files with 289 additions and 107 deletions

View File

@@ -44,10 +44,12 @@
#include "components/sprite_renderer.hpp"
#include "systems/flipbook_system.hpp"
#include "systems/frame_system.hpp"
#include "systems/label_system.hpp"
#include "systems/render_system.hpp"
#include "systems/script_system.hpp"
#include "systems/spine_system.hpp"
#include "systems/world_system.hpp"
#include "address.hpp"
#include "asset.hpp"

View File

@@ -62,10 +62,12 @@ namespace e2d
class sprite_renderer;
class flipbook_system;
class frame_system;
class label_system;
class render_system;
class script_system;
class spine_system;
class world_system;
template < typename Asset, typename Content >
class content_asset;

View File

@@ -25,10 +25,20 @@ namespace e2d::systems
f32 time{0.f};
};
struct render_event {};
struct pre_render_event {};
struct post_render_event {};
struct render_event {
ecs::const_entity cam_e;
};
struct pre_render_event {
ecs::const_entity cam_e;
};
struct post_render_event {
ecs::const_entity cam_e;
};
struct frame_update_event {};
struct frame_render_event {};
struct frame_finalize_event {};
using update_system = ecs::system<update_event>;

View File

@@ -0,0 +1,32 @@
/*******************************************************************************
* 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 frame_system final
: public ecs::system<
ecs::after<systems::frame_update_event>,
ecs::after<systems::frame_render_event>> {
public:
frame_system();
~frame_system() noexcept;
void process(
ecs::registry& owner,
const ecs::after<systems::frame_update_event>& trigger) override;
void process(
ecs::registry& owner,
const ecs::after<systems::frame_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 world_system final
: public ecs::system<ecs::after<systems::frame_finalize_event>> {
public:
world_system();
~world_system() noexcept;
void process(
ecs::registry& owner,
const ecs::after<systems::frame_finalize_event>& trigger) override;
private:
class internal_state;
std::unique_ptr<internal_state> state_;
};
}

View File

@@ -212,6 +212,8 @@ namespace
int e2d_main(int argc, char *argv[]) {
auto params = engine::parameters("sample_00", "enduro2d")
.window_params(engine::window_parameters()
.size({1024, 768}))
.timer_params(engine::timer_parameters()
.maximal_framerate(100));
modules::initialize<engine>(argc, argv, params).start<game>();

View File

@@ -272,6 +272,8 @@ namespace
int e2d_main(int argc, char *argv[]) {
auto params = engine::parameters("sample_01", "enduro2d")
.window_params(engine::window_parameters()
.size({1024, 768}))
.timer_params(engine::timer_parameters()
.maximal_framerate(100));
modules::initialize<engine>(argc, argv, params).start<game>();

View File

@@ -254,6 +254,8 @@ namespace
int e2d_main(int argc, char *argv[]) {
auto params = engine::parameters("sample_02", "enduro2d")
.window_params(engine::window_parameters()
.size({1024, 768}))
.timer_params(engine::timer_parameters()
.maximal_framerate(100));
modules::initialize<engine>(argc, argv, params).start<game>();

View File

@@ -39,11 +39,11 @@ namespace
}
};
class camera_system final : public systems::render_system {
class camera_system final : public systems::post_update_system {
public:
void process(
ecs::registry& owner,
const systems::render_event& event) override
const systems::post_update_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(
@@ -192,6 +192,8 @@ namespace
int e2d_main(int argc, char *argv[]) {
const auto starter_params = starter::parameters(
engine::parameters("sample_03", "enduro2d")
.window_params(engine::window_parameters()
.size({1024, 768}))
.timer_params(engine::timer_parameters()
.maximal_framerate(100)));
modules::initialize<starter>(argc, argv, starter_params).start<game>();

View File

@@ -32,11 +32,11 @@ namespace
}
};
class camera_system final : public systems::render_system {
class camera_system final : public systems::post_update_system {
public:
void process(
ecs::registry& owner,
const systems::render_event& event) override
const systems::post_update_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(

View File

@@ -79,6 +79,8 @@ namespace
int e2d_main(int argc, char *argv[]) {
auto params = engine::parameters("sample_05", "enduro2d")
.window_params(engine::window_parameters()
.size({1024, 768}))
.timer_params(engine::timer_parameters()
.maximal_framerate(100));
modules::initialize<engine>(argc, argv, params).start<game>();

View File

@@ -70,11 +70,11 @@ namespace
}
};
class camera_system final : public systems::render_system {
class camera_system final : public systems::post_update_system {
public:
void process(
ecs::registry& owner,
const systems::render_event& event) override
const systems::post_update_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(

View File

@@ -32,11 +32,11 @@ namespace
}
};
class camera_system final : public systems::render_system {
class camera_system final : public systems::post_update_system {
public:
void process(
ecs::registry& owner,
const systems::render_event& event) override
const systems::post_update_event& event) override
{
E2D_UNUSED(event);
owner.for_joined_components<camera>(

View File

@@ -29,10 +29,12 @@
#include <enduro2d/high/components/sprite_renderer.hpp>
#include <enduro2d/high/systems/flipbook_system.hpp>
#include <enduro2d/high/systems/frame_system.hpp>
#include <enduro2d/high/systems/label_system.hpp>
#include <enduro2d/high/systems/render_system.hpp>
#include <enduro2d/high/systems/script_system.hpp>
#include <enduro2d/high/systems/spine_system.hpp>
#include <enduro2d/high/systems/world_system.hpp>
namespace
{
@@ -54,6 +56,8 @@ namespace
ecs::registry_filler(the<world>().registry())
.feature<struct flipbook_feature>(ecs::feature()
.add_system<flipbook_system>())
.feature<struct frame_feature>(ecs::feature()
.add_system<frame_system>())
.feature<struct label_feature>(ecs::feature()
.add_system<label_system>())
.feature<struct render_feature>(ecs::feature()
@@ -61,7 +65,9 @@ namespace
.feature<struct script_feature>(ecs::feature()
.add_system<script_system>())
.feature<struct spine_feature>(ecs::feature()
.add_system<spine_system>());
.add_system<spine_system>())
.feature<struct world_feature>(ecs::feature()
.add_system<world_system>());
return !application_ || application_->initialize();
}
@@ -73,67 +79,19 @@ namespace
bool frame_tick() final {
E2D_PROFILER_SCOPE("application.frame_tick");
world& w = the<world>();
engine& e = the<engine>();
const f32 dt = e.delta_time();
const f32 time = e.time();
{
E2D_PROFILER_SCOPE("ecs.pre_update");
w.registry().process_event(systems::pre_update_event{dt,time});
}
{
E2D_PROFILER_SCOPE("ecs.update");
w.registry().process_event(systems::update_event{dt,time});
}
{
E2D_PROFILER_SCOPE("ecs.post_update");
w.registry().process_event(systems::post_update_event{dt,time});
}
the<world>().registry().process_event(systems::frame_update_event{});
return !the<window>().should_close()
|| (application_ && !application_->on_should_close());
}
void frame_render() final {
E2D_PROFILER_SCOPE("application.frame_render");
world& w = the<world>();
{
E2D_PROFILER_SCOPE("ecs.pre_render");
w.registry().process_event(systems::pre_render_event{});
}
{
E2D_PROFILER_SCOPE("ecs.render");
w.registry().process_event(systems::render_event{});
}
{
E2D_PROFILER_SCOPE("ecs.post_render");
w.registry().process_event(systems::post_render_event{});
}
the<world>().registry().process_event(systems::frame_render_event{});
}
void frame_finalize() final {
E2D_PROFILER_SCOPE("application.frame_finalize");
world& w = the<world>();
{
E2D_PROFILER_SCOPE("ecs.frame_finalize");
w.registry().process_event(systems::frame_finalize_event{});
}
{
E2D_PROFILER_SCOPE("world.finalize_instances");
w.finalize_instances();
}
the<world>().registry().process_event(systems::frame_finalize_event{});
}
private:
starter::application_uptr application_;

View File

@@ -82,7 +82,7 @@ namespace e2d
internal_state() = default;
~internal_state() noexcept = default;
void process(f32 dt, ecs::registry& owner) {
void process_update(f32 dt, ecs::registry& owner) {
update_flipbook_timers(dt, owner);
update_flipbook_sprites(owner);
}
@@ -100,7 +100,7 @@ namespace e2d
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger)
{
E2D_PROFILER_SCOPE("flipbook_system.process");
state_->process(trigger.event.dt, owner);
E2D_PROFILER_SCOPE("flipbook_system.process_update");
state_->process_update(trigger.event.dt, owner);
}
}

View File

@@ -0,0 +1,114 @@
/*******************************************************************************
* 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/frame_system.hpp>
#include <enduro2d/high/components/camera.hpp>
#include <enduro2d/high/components/disabled.hpp>
namespace
{
using namespace e2d;
template < typename Event >
void for_all_cameras(ecs::registry& owner) {
const auto comp = [](const auto& l, const auto& r) noexcept {
return std::get<camera>(l).depth() < std::get<camera>(r).depth();
};
const auto func = [&owner](
const ecs::const_entity& e,
const camera&)
{
owner.process_event(Event{e});
};
systems::for_extracted_sorted_components<camera>(
owner,
comp,
func,
!ecs::exists<disabled<camera>>());
}
}
namespace e2d
{
//
// frame_system::internal_state
//
class frame_system::internal_state final : private noncopyable {
public:
internal_state(engine& e)
: engine_(e) {}
~internal_state() noexcept = default;
void process_frame_update(ecs::registry& owner) {
const f32 dt = engine_.delta_time();
const f32 time = engine_.time();
{
E2D_PROFILER_SCOPE("ecs.pre_update");
owner.process_event(systems::pre_update_event{dt,time});
}
{
E2D_PROFILER_SCOPE("ecs.update");
owner.process_event(systems::update_event{dt,time});
}
{
E2D_PROFILER_SCOPE("ecs.post_update");
owner.process_event(systems::post_update_event{dt,time});
}
}
void process_frame_render(ecs::registry& owner) {
{
E2D_PROFILER_SCOPE("ecs.pre_render");
for_all_cameras<systems::pre_render_event>(owner);
}
{
E2D_PROFILER_SCOPE("ecs.render");
for_all_cameras<systems::render_event>(owner);
}
{
E2D_PROFILER_SCOPE("ecs.post_render");
for_all_cameras<systems::post_render_event>(owner);
}
}
private:
engine& engine_;
};
//
// frame_system
//
frame_system::frame_system()
: state_(new internal_state(the<engine>())) {}
frame_system::~frame_system() noexcept = default;
void frame_system::process(
ecs::registry& owner,
const ecs::after<systems::frame_update_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("frame_system.frame_update");
state_->process_frame_update(owner);
}
void frame_system::process(
ecs::registry& owner,
const ecs::after<systems::frame_render_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("frame_system.process_frame_render");
state_->process_frame_render(owner);
}
}

View File

@@ -378,7 +378,7 @@ namespace e2d
internal_state() = default;
~internal_state() noexcept = default;
void process(ecs::registry& owner) {
void process_update(ecs::registry& owner) {
update_dirty_labels(owner);
}
};
@@ -396,7 +396,7 @@ namespace e2d
const ecs::after<systems::update_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("label_system.process");
state_->process(owner);
E2D_PROFILER_SCOPE("label_system.process_update");
state_->process_update(owner);
}
}

View File

@@ -21,8 +21,6 @@ namespace
using namespace e2d::render_system_impl;
void for_all_scenes(drawer::context& ctx, const ecs::registry& owner) {
E2D_PROFILER_SCOPE("render_system.for_all_scenes");
const auto comp = [](const auto& l, const auto& r) noexcept {
return std::get<scene>(l).depth() < std::get<scene>(r).depth();
};
@@ -43,30 +41,6 @@ namespace
func,
!ecs::exists<disabled<scene>>());
}
void for_all_cameras(drawer& drawer, const ecs::registry& owner) {
E2D_PROFILER_SCOPE("render_system.for_all_cameras");
const auto comp = [](const auto& l, const auto& r) noexcept {
return std::get<camera>(l).depth() < std::get<camera>(r).depth();
};
const auto func = [&drawer, &owner](
const ecs::const_entity&,
const camera& cam,
const actor& cam_a)
{
drawer.with(cam, cam_a.node(), [&owner](drawer::context& ctx){
for_all_scenes(ctx, owner);
});
};
systems::for_extracted_sorted_components<camera, actor>(
owner,
comp,
func,
!ecs::exists<disabled<camera>>());
}
}
namespace e2d
@@ -81,8 +55,16 @@ namespace e2d
: drawer_(the<engine>(), the<debug>(), the<render>(), the<window>()) {}
~internal_state() noexcept = default;
void process(ecs::registry& owner) {
for_all_cameras(drawer_, owner);
void process_render(const ecs::const_entity& cam_e, ecs::registry& owner) {
if ( !cam_e.valid() || !ecs::exists_all<actor, camera>()(cam_e) ) {
return;
}
drawer_.with(
cam_e.get_component<camera>(),
cam_e.get_component<actor>().node(),
[&owner](drawer::context& ctx){
for_all_scenes(ctx, owner);
});
}
private:
drawer drawer_;
@@ -100,8 +82,7 @@ namespace e2d
ecs::registry& owner,
const ecs::after<systems::render_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("render_system.process");
state_->process(owner);
E2D_PROFILER_SCOPE("render_system.process_render");
state_->process_render(trigger.event.cam_e, owner);
}
}

View File

@@ -94,7 +94,7 @@ namespace e2d
}
~internal_state() noexcept = default;
void update_process(ecs::registry& owner) {
void process_update(ecs::registry& owner) {
systems::for_extracted_components<behaviour, actor>(owner,
[](ecs::entity e, behaviour& b, actor& a){
if ( !a.node() || !a.node()->owner() ) {
@@ -125,8 +125,8 @@ namespace e2d
const systems::update_event& event)
{
E2D_UNUSED(event);
E2D_PROFILER_SCOPE("script_system.process");
state_->update_process(owner);
E2D_PROFILER_SCOPE("script_system.process_update");
state_->process_update(owner);
}
void script_system::process(
@@ -134,7 +134,7 @@ namespace e2d
const ecs::before<systems::update_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("script_system.process");
E2D_PROFILER_SCOPE("script_system.process_events");
state_->process_events(owner);
}
}

View File

@@ -235,7 +235,7 @@ namespace e2d
internal_state() = default;
~internal_state() noexcept = default;
void process(f32 dt, ecs::registry& owner) {
void process_update(f32 dt, ecs::registry& owner) {
process_commands(owner);
clear_commands(owner);
clear_events(owner);
@@ -258,7 +258,7 @@ namespace e2d
ecs::registry& owner,
const ecs::after<systems::update_event>& trigger)
{
E2D_PROFILER_SCOPE("spine_system.process");
state_->process(trigger.event.dt, owner);
E2D_PROFILER_SCOPE("spine_system.process_update");
state_->process_update(trigger.event.dt, owner);
}
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* 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/world_system.hpp>
#include <enduro2d/high/world.hpp>
namespace e2d
{
//
// world_system::internal_state
//
class world_system::internal_state final : private noncopyable {
public:
internal_state(world& w)
: world_(w) {}
~internal_state() noexcept = default;
void process_frame_finalize(ecs::registry& owner) {
E2D_UNUSED(owner);
world_.finalize_instances();
}
private:
world& world_;
};
//
// world_system
//
world_system::world_system()
: state_(new internal_state(the<world>())) {}
world_system::~world_system() noexcept = default;
void world_system::process(
ecs::registry& owner,
const ecs::after<systems::frame_finalize_event>& trigger)
{
E2D_UNUSED(trigger);
E2D_PROFILER_SCOPE("world_system.process_frame_finalize");
state_->process_frame_finalize(owner);
}
}