initialization all modules in engine

This commit is contained in:
2018-11-08 00:13:34 +07:00
parent fcb6698658
commit 59bb164f4c
6 changed files with 711 additions and 334 deletions

View File

@@ -13,6 +13,7 @@
namespace e2d
{
class debug;
class application;
class engine;
class mouse;
class keyboard;

View File

@@ -10,9 +10,108 @@
namespace e2d
{
//
// application
//
class application : private noncopyable {
public:
virtual ~application() noexcept = default;
virtual bool initialize();
virtual void shutdown() noexcept;
virtual bool frame_tick();
};
using application_uptr = std::unique_ptr<application>;
//
// bad_engine_operation
//
class bad_engine_operation final : public exception {
public:
const char* what() const noexcept final {
return "bad engine operation";
}
};
//
// engine
//
class engine final : public module<engine> {
public:
engine();
class debug_parameters {
public:
debug_parameters& log_filename(str_view value);
debug_parameters& file_logging(bool value) noexcept;
debug_parameters& console_logging(bool value) noexcept;
const str& log_filename() const noexcept;
bool file_logging() const noexcept;
bool console_logging() const noexcept;
private:
str log_filename_{"log.txt"};
bool file_logging_{true};
bool console_logging_{true};
};
class window_parameters {
public:
window_parameters& caption(str_view value);
window_parameters& size(const v2u& value) noexcept;
window_parameters& fullscreen(bool value) noexcept;
const str& caption() const noexcept;
const v2u& size() const noexcept;
bool fullscreen() const noexcept;
private:
str caption_{"Enduro2D"};
v2u size_{640, 480};
bool fullscreen_{false};
};
class parameters {
public:
parameters() = delete;
parameters(str_view game_name, str_view company_name);
parameters& game_name(str_view value) noexcept;
parameters& company_name(str_view value) noexcept;
parameters& debug_params(const debug_parameters& value);
parameters& window_params(const window_parameters& value);
str& game_name() noexcept;
str& company_name() noexcept;
debug_parameters& debug_params() noexcept;
window_parameters& window_params() noexcept;
const str& game_name() const noexcept;
const str& company_name() const noexcept;
const debug_parameters& debug_params() const noexcept;
const window_parameters& window_params() const noexcept;
private:
str game_name_{"noname"};
str company_name_{"noname"};
debug_parameters debug_params_;
window_parameters window_params_;
};
public:
engine(const parameters& params);
~engine() noexcept final;
template < typename Application, typename... Args >
bool start(Args&&... args);
bool start(application_uptr app);
private:
class internal_state;
std::unique_ptr<internal_state> state_;
};
}
namespace e2d
{
template < typename Application, typename... Args >
bool engine::start(Args&&... args) {
return start(std::make_unique<Application>(std::forward<Args>(args)...));
}
}

View File

@@ -89,62 +89,52 @@ namespace
vertex2{color32::blue()},
vertex2{color32::yellow()}};
}
}
int e2d_main() {
{
modules::initialize<vfs>()
.register_scheme<filesystem_file_source>("file");
modules::initialize<debug>()
.register_sink<debug_console_sink>();
modules::initialize<input>();
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false)
.register_event_listener<window_input_source>(the<input>());
modules::initialize<render>(the<debug>(), the<window>());
}
{
str resources;
filesystem::extract_predef_path(resources, filesystem::predef_path::resources);
the<vfs>().register_scheme_alias(
"resources",
url{"file", resources});
class game final : public application {
public:
bool initialize() final {
the<vfs>().register_scheme<archive_file_source>(
"piratepack",
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
the<vfs>().register_scheme_alias("ships", url("piratepack://PNG/Retina/Ships"));
}
auto texture1 = the<render>().create_texture(
the<vfs>().register_scheme_alias(
"ships",
url("piratepack://PNG/Retina/Ships"));
shader_ = the<render>().create_shader(
vs_source_cstr, fs_source_cstr);
texture1_ = the<render>().create_texture(
the<vfs>().open(url("ships://ship (2).png")));
auto texture2 = the<render>().create_texture(
texture2_ = the<render>().create_texture(
the<vfs>().open(url("ships://ship (19).png")));
const auto shader = the<render>().create_shader(
vs_source_cstr, fs_source_cstr);
if ( !shader_ || !texture1_ || !texture2_ ) {
return false;
}
const auto indices = generate_quad_indices();
const auto index_buffer = the<render>().create_index_buffer(
index_buffer_ = the<render>().create_index_buffer(
buffer(indices.data(), indices.size() * sizeof(indices[0])),
index_declaration::index_type::unsigned_byte,
index_buffer::usage::static_draw);
const auto vertices1 = generate_quad_vertices(texture1->size());
const auto vertex_buffer1 = the<render>().create_vertex_buffer(
const auto vertices1 = generate_quad_vertices(texture1_->size());
vertex_buffer1_ = the<render>().create_vertex_buffer(
buffer(vertices1.data(), vertices1.size() * sizeof(vertices1[0])),
vertex1::decl(),
vertex_buffer::usage::static_draw);
const auto vertices2 = generate_quad_colors();
const auto vertex_buffer2 = the<render>().create_vertex_buffer(
vertex_buffer2_ = the<render>().create_vertex_buffer(
buffer(vertices2.data(), vertices2.size() * sizeof(vertices2[0])),
vertex2::decl(),
vertex_buffer::usage::static_draw);
if ( !texture1 || !texture2 || !shader || !index_buffer || !vertex_buffer1 || !vertex_buffer2 ) {
return 1;
if ( !index_buffer_ || !vertex_buffer1_ || !vertex_buffer2_ ) {
return false;
}
auto material = render::material()
material_ = render::material()
.add_pass(render::pass_state()
.states(render::state_block()
.capabilities(render::capabilities_state()
@@ -152,43 +142,63 @@ int e2d_main() {
.blending(render::blending_state()
.src_factor(render::blending_factor::src_alpha)
.dst_factor(render::blending_factor::one_minus_src_alpha)))
.shader(shader)
.shader(shader_)
.properties(render::property_block()
.sampler("u_texture1", render::sampler_state()
.texture(texture1)
.texture(texture1_)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear))
.sampler("u_texture2", render::sampler_state()
.texture(texture2)
.texture(texture2_)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear))));
auto geometry = render::geometry()
.indices(index_buffer)
.add_vertices(vertex_buffer1)
.add_vertices(vertex_buffer2);
geometry_ = render::geometry()
.indices(index_buffer_)
.add_vertices(vertex_buffer1_)
.add_vertices(vertex_buffer2_);
const auto begin_game_time = time::now_ms();
begin_game_time_ = time::now_ms();
return true;
}
bool frame_tick() final {
const keyboard& k = the<input>().keyboard();
if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) {
return false;
}
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_orthogonal_lh_matrix4(framebuffer_size, 0.f, 1.f);
const keyboard& k = the<input>().keyboard();
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
const auto game_time = (time::now_ms() - begin_game_time).cast_to<f32>().value;
material.properties()
material_.properties()
.property("u_time", game_time)
.property("u_MVP", projection);
the<render>().execute(render::command_block<64>()
.add_command(render::clear_command()
.color_value({1.f, 0.4f, 0.f, 1.f}))
.add_command(render::draw_command(material, geometry))
.add_command(render::draw_command(material_, geometry_))
.add_command(render::swap_command(true)));
the<input>().frame_tick();
window::poll_events();
return true;
}
private:
shader_ptr shader_;
texture_ptr texture1_;
texture_ptr texture2_;
index_buffer_ptr index_buffer_;
vertex_buffer_ptr vertex_buffer1_;
vertex_buffer_ptr vertex_buffer2_;
render::material material_;
render::geometry geometry_;
milliseconds<i64> begin_game_time_;
};
}
int e2d_main() {
auto params = engine::parameters("sample_00", "enduro2d");
modules::initialize<engine>(params).start<game>();
return 0;
}

View File

@@ -149,60 +149,51 @@ namespace
vertex2{color32::blue()},
vertex2{color32::yellow()}};
}
}
int e2d_main() {
{
modules::initialize<vfs>()
.register_scheme<filesystem_file_source>("file");
modules::initialize<debug>()
.register_sink<debug_console_sink>();
modules::initialize<input>();
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false)
.register_event_listener<window_input_source>(the<input>());
modules::initialize<render>(the<debug>(), the<window>());
}
{
str resources;
filesystem::extract_predef_path(resources, filesystem::predef_path::resources);
the<vfs>().register_scheme_alias(
"resources",
url{"file", resources});
class game final : public application {
public:
bool initialize() final {
the<vfs>().register_scheme<archive_file_source>(
"piratepack",
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
the<vfs>().register_scheme_alias("ships", url("piratepack://PNG/Retina/Ships"));
}
auto texture = the<render>().create_texture(
the<vfs>().open(url("ships://ship (3).png")));
the<vfs>().register_scheme_alias(
"ships",
url("piratepack://PNG/Retina/Ships"));
const auto shader = the<render>().create_shader(
shader_ = the<render>().create_shader(
vs_source_cstr, fs_source_cstr);
texture_ = the<render>().create_texture(
the<vfs>().open(url("ships://ship (3).png")));
if ( !shader_ || !texture_ ) {
return false;
}
const auto indices = generate_cube_indices();
const auto index_buffer = the<render>().create_index_buffer(
index_buffer_ = the<render>().create_index_buffer(
buffer(indices.data(), indices.size() * sizeof(indices[0])),
index_declaration::index_type::unsigned_byte,
index_buffer::usage::static_draw);
const auto vertices1 = generate_cube_vertices(make_vec3(1.f));
const auto vertex_buffer1 = the<render>().create_vertex_buffer(
vertex_buffer1_ = the<render>().create_vertex_buffer(
buffer(vertices1.data(), vertices1.size() * sizeof(vertices1[0])),
vertex1::decl(),
vertex_buffer::usage::static_draw);
const auto vertices2 = generate_cube_colors();
const auto vertex_buffer2 = the<render>().create_vertex_buffer(
vertex_buffer2_ = the<render>().create_vertex_buffer(
buffer(vertices2.data(), vertices2.size() * sizeof(vertices2[0])),
vertex2::decl(),
vertex_buffer::usage::static_draw);
if ( !texture || !shader || !index_buffer || !vertex_buffer1 || !vertex_buffer2 ) {
return 1;
if ( !index_buffer_ || !vertex_buffer1_ || !vertex_buffer2_ ) {
return false;
}
auto material = render::material()
material_ = render::material()
.add_pass(render::pass_state()
.states(render::state_block()
.capabilities(render::capabilities_state()
@@ -211,19 +202,29 @@ int e2d_main() {
.culling(render::culling_state()
.mode(render::culling_mode::ccw)
.face(render::culling_face::back)))
.shader(shader)
.shader(shader_)
.properties(render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(texture)
.texture(texture_)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear))));
auto geometry = render::geometry()
.indices(index_buffer)
.add_vertices(vertex_buffer1)
.add_vertices(vertex_buffer2);
geometry_ = render::geometry()
.indices(index_buffer_)
.add_vertices(vertex_buffer1_)
.add_vertices(vertex_buffer2_);
const auto begin_game_time = time::now_ms();
begin_game_time_ = time::now_ms();
return true;
}
bool frame_tick() final {
const keyboard& k = the<input>().keyboard();
if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) {
return false;
}
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_perspective_lh_matrix4(
make_deg(45.f),
@@ -231,10 +232,6 @@ int e2d_main() {
0.1f,
100.f);
const keyboard& k = the<input>().keyboard();
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
const auto game_time = (time::now_ms() - begin_game_time).cast_to<f32>().value;
const auto MVP =
math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 1.f, 0.f, 0.f) *
math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 1.f, 0.f) *
@@ -243,19 +240,32 @@ int e2d_main() {
math::make_loot_at_lh_matrix4({0.f,0.f,-3.f}, v3f::zero(), v3f::unit_y()) *
projection;
material.properties()
material_.properties()
.property("u_time", game_time)
.property("u_MVP", MVP);
the<render>().execute(render::command_block<64>()
.add_command(render::clear_command()
.color_value({1.f, 0.4f, 0.f, 1.f}))
.add_command(render::draw_command(material, geometry))
.add_command(render::draw_command(material_, geometry_))
.add_command(render::swap_command(true)));
the<input>().frame_tick();
window::poll_events();
return true;
}
private:
shader_ptr shader_;
texture_ptr texture_;
index_buffer_ptr index_buffer_;
vertex_buffer_ptr vertex_buffer1_;
vertex_buffer_ptr vertex_buffer2_;
render::material material_;
render::geometry geometry_;
milliseconds<i64> begin_game_time_;
};
}
int e2d_main() {
auto params = engine::parameters("sample_01", "enduro2d");
modules::initialize<engine>(params).start<game>();
return 0;
}

View File

@@ -104,54 +104,63 @@ namespace
vertex{{-x, y, -z}, {1, 0}},
vertex{{-x, y, z}, {0, 0}}};
}
}
int e2d_main() {
{
modules::initialize<vfs>()
.register_scheme<filesystem_file_source>("file");
modules::initialize<debug>()
.register_sink<debug_console_sink>();
modules::initialize<input>();
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false)
.register_event_listener<window_input_source>(the<input>());
modules::initialize<render>(the<debug>(), the<window>());
}
{
str resources;
filesystem::extract_predef_path(resources, filesystem::predef_path::resources);
the<vfs>().register_scheme_alias(
"resources",
url{"file", resources});
class game final : public application {
public:
bool initialize() final {
the<vfs>().register_scheme<archive_file_source>(
"piratepack",
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
the<vfs>().register_scheme_alias("ships", url("piratepack://PNG/Retina/Ships"));
}
auto texture = the<render>().create_texture(
the<vfs>().open(url("ships://ship (3).png")));
the<vfs>().register_scheme_alias(
"ships",
url("piratepack://PNG/Retina/Ships"));
const auto shader = the<render>().create_shader(
shader_ = the<render>().create_shader(
vs_source_cstr, fs_source_cstr);
texture_ = the<render>().create_texture(
the<vfs>().open(url("ships://ship (3).png")));
if ( !shader_ || !texture_ ) {
return false;
}
const auto indices = generate_cube_indices();
const auto index_buffer = the<render>().create_index_buffer(
index_buffer_ = the<render>().create_index_buffer(
buffer(indices.data(), indices.size() * sizeof(indices[0])),
index_declaration::index_type::unsigned_byte,
index_buffer::usage::static_draw);
const auto vertices = generate_cube_vertices(make_vec3(1.f));
const auto vertex_buffer = the<render>().create_vertex_buffer(
vertex_buffer_ = the<render>().create_vertex_buffer(
buffer(vertices.data(), vertices.size() * sizeof(vertices[0])),
vertex::decl(),
vertex_buffer::usage::static_draw);
if ( !texture || !shader || !index_buffer || !vertex_buffer ) {
return 1;
render_target_ = the<render>().create_render_target(
the<window>().real_size() / 10u,
pixel_declaration::pixel_type::rgba8,
pixel_declaration::pixel_type::depth16,
render_target::external_texture::color_and_depth);
if ( !index_buffer_ || !vertex_buffer_ || !render_target_ ) {
return false;
}
auto material = render::material()
rt_props_ = render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(render_target_->color())
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear));
tex_props_ = render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(texture_)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear));
material_ = render::material()
.add_pass(render::pass_state()
.states(render::state_block()
.capabilities(render::capabilities_state()
@@ -164,18 +173,28 @@ int e2d_main() {
.culling(render::culling_state()
.mode(render::culling_mode::ccw)
.face(render::culling_face::back)))
.shader(shader))
.shader(shader_))
.properties(render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(texture)
.texture(texture_)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear)));
auto geometry = render::geometry()
.indices(index_buffer)
.add_vertices(vertex_buffer);
geometry_ = render::geometry()
.indices(index_buffer_)
.add_vertices(vertex_buffer_);
const auto begin_game_time = time::now_ms();
begin_game_time_ = time::now_ms();
return true;
}
bool frame_tick() final {
const keyboard& k = the<input>().keyboard();
if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) {
return false;
}
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_perspective_lh_matrix4(
make_deg(45.f),
@@ -183,28 +202,6 @@ int e2d_main() {
0.1f,
100.f);
const auto rt = the<render>().create_render_target(
the<window>().real_size() / 10u,
pixel_declaration::pixel_type::rgba8,
pixel_declaration::pixel_type::depth16,
render_target::external_texture::color_and_depth);
auto rt_props = render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(rt->color())
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear));
auto texture_props = render::property_block()
.sampler("u_texture", render::sampler_state()
.texture(texture)
.min_filter(render::sampler_min_filter::linear)
.mag_filter(render::sampler_mag_filter::linear));
const keyboard& k = the<input>().keyboard();
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
const auto game_time = (time::now_ms() - begin_game_time).cast_to<f32>().value;
const auto MVP =
math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 1.f, 0.f, 0.f) *
math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 1.f, 0.f) *
@@ -213,28 +210,43 @@ int e2d_main() {
math::make_loot_at_lh_matrix4({0.f,0.f,-2.f}, v3f::zero(), v3f::unit_y()) *
projection;
material.properties()
material_.properties()
.property("u_time", game_time)
.property("u_MVP", MVP);
the<render>().execute(render::command_block<64>()
.add_command(render::target_command(rt))
.add_command(render::viewport_command(rt->size()))
.add_command(render::target_command(render_target_))
.add_command(render::viewport_command(render_target_->size()))
.add_command(render::clear_command()
.color_value({0.f, 0.4f, 0.f, 1.f}))
.add_command(render::draw_command(material, geometry, texture_props)));
.add_command(render::draw_command(material_, geometry_, tex_props_)));
the<render>().execute(render::command_block<64>()
.add_command(render::target_command(nullptr))
.add_command(render::viewport_command(the<window>().real_size()))
.add_command(render::clear_command()
.color_value({1.f, 0.4f, 0.f, 1.f}))
.add_command(render::draw_command(material, geometry, rt_props))
.add_command(render::draw_command(material_, geometry_, rt_props_))
.add_command(render::swap_command(true)));
the<input>().frame_tick();
window::poll_events();
return true;
}
private:
shader_ptr shader_;
texture_ptr texture_;
index_buffer_ptr index_buffer_;
vertex_buffer_ptr vertex_buffer_;
render_target_ptr render_target_;
render::property_block rt_props_;
render::property_block tex_props_;
render::material material_;
render::geometry geometry_;
milliseconds<i64> begin_game_time_;
};
}
int e2d_main() {
auto params = engine::parameters("sample_02", "enduro2d");
modules::initialize<engine>(params).start<game>();
return 0;
}

View File

@@ -6,13 +6,258 @@
#include <enduro2d/core/engine.hpp>
#include <enduro2d/core/debug.hpp>
#include <enduro2d/core/input.hpp>
#include <enduro2d/core/render.hpp>
#include <enduro2d/core/vfs.hpp>
#include <enduro2d/core/window.hpp>
namespace
{
using namespace e2d;
template < typename Module, typename... Args >
void safe_module_initialize(Args&&... args) {
if ( !modules::is_initialized<Module>() ) {
modules::initialize<Module>(std::forward<Args>(args)...);
}
}
void safe_register_predef_path(
vfs& the_vfs,
str_view scheme,
filesystem::predef_path predef_path)
{
str path;
if ( filesystem::extract_predef_path(path, predef_path) ) {
the_vfs.register_scheme_alias(scheme, url{"file", path});
}
}
}
namespace e2d
{
engine::engine() = default;
engine::~engine() noexcept = default;
//
// application
//
bool application::initialize() {
return true;
}
void application::shutdown() noexcept {
}
bool application::frame_tick() {
return true;
}
//
// engine::debug_parameters
//
engine::debug_parameters& engine::debug_parameters::log_filename(str_view value) {
log_filename_ = value;
return *this;
}
engine::debug_parameters& engine::debug_parameters::file_logging(bool value) noexcept {
file_logging_ = value;
return *this;
}
engine::debug_parameters& engine::debug_parameters::console_logging(bool value) noexcept {
console_logging_ = value;
return *this;
}
const str& engine::debug_parameters::log_filename() const noexcept {
return log_filename_;
}
bool engine::debug_parameters::file_logging() const noexcept {
return file_logging_;
}
bool engine::debug_parameters::console_logging() const noexcept {
return console_logging_;
}
//
// engine::window_parameters
//
engine::window_parameters& engine::window_parameters::caption(str_view value) {
caption_ = value;
return *this;
}
engine::window_parameters& engine::window_parameters::size(const v2u& value) noexcept {
size_ = value;
return *this;
}
engine::window_parameters& engine::window_parameters::fullscreen(bool value) noexcept {
fullscreen_ = value;
return *this;
}
const str& engine::window_parameters::caption() const noexcept {
return caption_;
}
const v2u& engine::window_parameters::size() const noexcept {
return size_;
}
bool engine::window_parameters::fullscreen() const noexcept {
return fullscreen_;
}
//
// engine::parameters
//
engine::parameters::parameters(str_view game_name, str_view company_name)
: game_name_(game_name)
, company_name_(company_name) {}
engine::parameters& engine::parameters::game_name(str_view value) noexcept {
game_name_ = value;
return *this;
}
engine::parameters& engine::parameters::company_name(str_view value) noexcept {
company_name_ = value;
return *this;
}
engine::parameters& engine::parameters::debug_params(const debug_parameters& value) {
debug_params_ = value;
return *this;
}
engine::parameters& engine::parameters::window_params(const window_parameters& value) {
window_params_ = value;
return *this;
}
str& engine::parameters::game_name() noexcept {
return game_name_;
}
str& engine::parameters::company_name() noexcept {
return company_name_;
}
engine::debug_parameters& engine::parameters::debug_params() noexcept {
return debug_params_;
}
engine::window_parameters& engine::parameters::window_params() noexcept {
return window_params_;
}
const str& engine::parameters::game_name() const noexcept {
return game_name_;
}
const str& engine::parameters::company_name() const noexcept {
return company_name_;
}
const engine::debug_parameters& engine::parameters::debug_params() const noexcept {
return debug_params_;
}
const engine::window_parameters& engine::parameters::window_params() const noexcept {
return window_params_;
}
//
// engine::internal_state
//
class engine::internal_state final : private e2d::noncopyable {
public:
internal_state() = default;
~internal_state() noexcept = default;
};
//
// engine
//
engine::engine(const parameters& params)
: state_(new internal_state())
{
// setup debug
safe_module_initialize<debug>();
if ( params.debug_params().console_logging() ) {
the<debug>().register_sink<debug_console_sink>();
}
// setup vfs
safe_module_initialize<vfs>();
the<vfs>().register_scheme<filesystem_file_source>("file");
safe_register_predef_path(the<vfs>(), "home", filesystem::predef_path::home);
safe_register_predef_path(the<vfs>(), "appdata", filesystem::predef_path::appdata);
safe_register_predef_path(the<vfs>(), "desktop", filesystem::predef_path::desktop);
safe_register_predef_path(the<vfs>(), "working", filesystem::predef_path::working);
safe_register_predef_path(the<vfs>(), "documents", filesystem::predef_path::documents);
safe_register_predef_path(the<vfs>(), "resources", filesystem::predef_path::resources);
safe_register_predef_path(the<vfs>(), "executable", filesystem::predef_path::executable);
if ( params.debug_params().file_logging() ) {
url log_url = url("appdata://")
/ params.company_name()
/ params.game_name()
/ params.debug_params().log_filename();
output_stream_uptr log_stream = the<vfs>().write(log_url, false);
the<debug>().register_sink<debug_stream_sink>(std::move(log_stream));
}
// setup input
safe_module_initialize<input>();
// setup window
safe_module_initialize<window>(
params.window_params().size(),
params.window_params().caption(),
params.window_params().fullscreen());
the<window>().register_event_listener<window_input_source>(the<input>());
// setup render
safe_module_initialize<render>(
the<debug>(),
the<window>());
}
engine::~engine() noexcept = default;
bool engine::start(application_uptr app) {
if ( !app || !app->initialize() ) {
the<debug>().error("ENGINE: Failed to initialize application");
return false;
}
try {
while ( app->frame_tick() ) {
the<input>().frame_tick();
window::poll_events();
}
} catch ( ... ) {
app->shutdown();
throw;
}
app->shutdown();
return true;
}
}