/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
examples/canvas_example.cpp
250 строк
9 KB
den163
Added base ui input handling
06 ноя 2024, 20:51
06 ноя 2024, 20:51
04ca94a
Код
Авторство
О чём код?
#include "division_engine/canvas/border_radius.hpp" #include "division_engine/canvas/components.hpp" #include "division_engine/canvas/components/collision_rect.hpp" #include "division_engine/canvas/components/render_batch.hpp" #include "division_engine/canvas/components/render_bounds.hpp" #include "division_engine/canvas/components/render_order.hpp" #include "division_engine/canvas/components/render_texture.hpp" #include "division_engine/canvas/components/renderable_rect.hpp" #include "division_engine/canvas/components/renderable_text.hpp" #include "division_engine/canvas/components/tags.hpp" #include "division_engine/canvas/input_handler.hpp" #include "division_engine/canvas/rect_drawer.hpp" #include "division_engine/canvas/render_manager.hpp" #include "division_engine/canvas/state.hpp" #include "division_engine/canvas/text_drawer.hpp" #include "division_engine/color.hpp" #include "division_engine/core/context.hpp" #include "division_engine/core/core_runner.hpp" #include "division_engine/core/font_texture.hpp" #include "division_engine/core/input.hpp" #include "division_engine/core/lifecycle_manager.hpp" #include <flecs.h> #include <glm/gtc/random.hpp> #include <glm/vec2.hpp> #include <array> #include <filesystem> #include <functional> #include <iostream> #include <locale> #include <string> #include <tuple> #include <utility> using namespace division_engine; using namespace division_engine::canvas; using namespace division_engine::canvas::components; using namespace division_engine::canvas::components::tags; using namespace division_engine::core; const size_t RECT_COUNT = 100'000; const size_t RECT_SIZE = 8; const size_t TEXT_RECT_SIZE = 512; const auto FONT_SIZE = 20; const auto FONT_PATH = std::filesystem::path { "resources" } / "fonts" / "Roboto-Medium.ttf"; struct Velocity { glm::vec2 value; }; struct MyManager { MyManager() = delete; MyManager(MyManager&&) = delete; MyManager& operator=(MyManager&&) = delete; MyManager(MyManager&) = delete; MyManager operator=(MyManager&) = delete; ~MyManager() = default; MyManager(DivisionContext* context_ptr) : _state(context_ptr) , _query(_state.world.query<RenderBounds, RenderableRect, Velocity>()) { _renderer_manager.register_renderer<RectDrawer>(_state); _renderer_manager.register_renderer<TextDrawer>(_state, FONT_PATH); _renderer_manager.register_renderer<InputHandler>(_state); const auto with_white_tex = _state.world.entity().set(RenderTexture { _state.white_texture_id }); _state.clear_color = color::WHITE; const auto screen_size = _state.context.get_screen_size(); for (int i = 0; i < RECT_COUNT; i++) { auto entity = _renderer_manager .create_renderer( _state, std::make_tuple( RenderableRect { .color = glm::linearRand(color::WHITE, color::BLACK) }, RenderBounds { Rect::from_center( glm::linearRand(glm::vec2 { 0 }, screen_size), glm::vec2 { RECT_SIZE } ) } ), -2, // custom_order with_white_tex.id() ) .set(Velocity { glm::linearRand(glm::vec2 { -1 }, glm::vec2 { 1 }) }); entity.add<Selectable>(flecs::Tag); } _mouse_pos_text = _renderer_manager .create_renderer( _state, std::make_tuple( RenderableText { .text = "Mouse position: ", .color = color::PURPLE, .font_size = FONT_SIZE, }, RenderBounds { Rect::from_bottom_left(glm::vec2 { 0 }, glm::vec2 { TEXT_RECT_SIZE }) } ), 1 // custom_order ) .set(Velocity { glm::linearRand(glm::vec2 { -1 }, glm::vec2 { 1 }) }); auto red_rect = Rect::from_center(glm::linearRand(glm::vec2 { 0 }, screen_size), glm::vec2 { 256 }); _renderer_manager .create_renderer( _state, std::make_tuple( RenderableRect { .color = color::RED, .border_radius = BorderRadius::all(10), }, RenderBounds { red_rect }, CollisionRect { red_rect } ), 0, // custom_order with_white_tex.id() ) .set(Velocity { glm::linearRand(glm::vec2 { -1 }, glm::vec2 { 1 }) }) .add<Selectable>(flecs::Tag); auto blue_rect = Rect::from_center(glm::linearRand(glm::vec2 { 0 }, screen_size), glm::vec2 { 256 }); _renderer_manager .create_renderer( _state, std::make_tuple( RenderableRect { .color = color::BLUE, .border_radius = BorderRadius::all(10), }, RenderBounds { blue_rect }, CollisionRect { blue_rect } ), -1, // custom_order with_white_tex.id() ) .set(Velocity { glm::linearRand(glm::vec2 { -1 }, glm::vec2 { 1 }) }) .add<Selectable>(flecs::Tag); } void draw() { auto text = flecs::entity { _state.world, _mouse_pos_text }.get_mut<RenderableText>(); auto mouse_pos = _state.context.get_mouse_position(); text->text = std::string { "Mouse position (X: " } .append(std::to_string(static_cast<int>(mouse_pos.x))) .append(", Y: ") .append(std::to_string(static_cast<int>(mouse_pos.y))) .append(")"); _state.update(); _renderer_manager.update(_state); update_rects(); _state.render_queue.draw(_state.context.get_ptr(), _state.clear_color); if (_state.context.is_key_pressed(DivisionKeycode::DIVISION_KEYCODE_SPACE) | _state.context.is_mouse_button_pressed(MouseButton::Left)) { const auto selected_id = _state.selected_id; if (selected_id.has_value()) { std::cout << "Clicked! Selected entity is: " << selected_id.value() << std::endl; } else { std::cout << "Clicked! There is no selected entity" << std::endl; } } } void update_rects() { const auto screen_size = _state.context.get_screen_size(); _query.each( [screen_size](RenderBounds& bounds, RenderableRect& rect, Velocity& vel) { auto& rect_bounds = bounds.value; auto& dir = vel.value; rect_bounds.center += dir; if (rect_bounds.right() > screen_size.x) { rect_bounds.set_right(screen_size.x); dir.x = -dir.x; } else if (rect_bounds.left() < 0) { rect_bounds.set_left(0); dir.x = -dir.x; } if (rect_bounds.top() > screen_size.y) { rect_bounds.set_top(screen_size.y); dir.y = -dir.y; } else if (rect_bounds.bottom() < 0) { rect_bounds.set_bottom(0); dir.y = -dir.y; } } ); _state.world.each([](CollisionRect& collision_rect, const RenderBounds& render_bounds) { collision_rect.rect = render_bounds.value; }); } void error(int error_code, const char* error_message) { std::cout << "Error code: " << error_code << ". Message: " << error_message << std::endl; } State _state; flecs::query<RenderBounds, RenderableRect, Velocity> _query; RenderManager _renderer_manager; flecs::entity_t _mouse_pos_text; }; struct MyManagerBuilder { using manager_type = MyManager; MyManager* build(DivisionContext* context) { return new MyManager { context }; } }; int main(int argc, char** argv) { const size_t WINDOW_SIZE = 512; CoreRunner { "Canvas example", { WINDOW_SIZE, WINDOW_SIZE } }.run(MyManagerBuilder {}); }