/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
examples/view_tree_example.cpp
191 строка
6 KB
den163
Improved SDF fonts visuals
05 дек 2024, 01:56
05 дек 2024, 01:56
8dec6fc
Код
Авторство
О чём код?
#include "division_engine/canvas/border_radius.hpp" #include "division_engine/canvas/components/render_bounds.hpp" #include "division_engine/canvas/components/renderable_rect.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/size.hpp" #include "division_engine/canvas/state.hpp" #include "division_engine/canvas/text_drawer.hpp" #include "division_engine/canvas/view_tree/any_view.hpp" #include "division_engine/canvas/view_tree/decorated_box.hpp" #include "division_engine/canvas/view_tree/list.hpp" #include "division_engine/canvas/view_tree/padding.hpp" #include "division_engine/canvas/view_tree/sized_box.hpp" #include "division_engine/canvas/view_tree/stack.hpp" #include "division_engine/canvas/view_tree/text.hpp" #include "division_engine/canvas/view_tree/view.hpp" #include "division_engine/canvas/view_tree/view_builder.hpp" #include "division_engine/color.hpp" #include "division_engine/core/context.hpp" #include "division_engine/core/core_runner.hpp" #include "division_engine/lua/lua_manager.hpp" #include "division_engine/lua/state.hpp" #include "division_engine/rect.hpp" #include "division_engine_core/context.h" #include "glm/vec2.hpp" #include "glm/vec4.hpp" #include <cassert> #include <chrono> #include <exception> #include <filesystem> #include <iostream> #include <memory> #include <string> #include <tuple> #include <type_traits> #include <utility> using namespace division_engine; using namespace core; using namespace canvas; using namespace view_tree; using std::filesystem::path; const path FONT_PATH = path { "resources" } / "fonts" / "Roboto-Regular.ttf"; template<typename T> concept UIBuilder = requires(T t, State& state) { { t.build_ui(state) } -> View; }; long example_sum(long x, long y) { return x + y; } struct MyUIBuilder { using time_point_t = std::chrono::time_point<std::chrono::steady_clock>; time_point_t _prev_time = std::chrono::steady_clock::now(); View auto build_ui(State& state) { const auto now = std::chrono::steady_clock::now(); const auto delta_time = (now - _prev_time); const auto delta_ms = std::chrono::duration_cast<std::chrono::milliseconds>(delta_time).count(); _prev_time = now; return HorizontalList { SizedBox { Size { 200, 100 }, Stack { DecoratedBox { .background_color = glm::vec4 { glm::vec3 { 0.7 }, 1 }, .border_radius = BorderRadius::bottom(15), }, Text { .text = std::string { "UI build delta time: " } + std::to_string(delta_ms) + " ms", .color = color::BLACK, }, }, }, }; } }; template<UIBuilder T> class MyLifecycleManager { public: using root_view_t = typename std::invoke_result_t<decltype(&T::build_ui), T, State&>; using root_view_renderer_t = typename root_view_t::Renderer; using Self = MyLifecycleManager<T>; MyLifecycleManager(DivisionContext* ctx_ptr, T ui_builder) : _state(State { ctx_ptr, color::WHITE }) , _lua_manager(lua::LuaManager::with_search_script_path({ "../../resources/scripts" })) , _ui_builder(ui_builder) , _root_view(std::make_unique<root_view_t>(_ui_builder.build_ui(_state))) , _root_view_render( std::make_unique<root_view_renderer_t>(_state, _render_manager, *_root_view) ) { lua::State& lua = _lua_manager.state(); lua.set_global_ptr("__ENGINE_STATE__", &_state); lua.set_global_ptr("__RENDER_MANAGER__", &_render_manager); try { _lua_manager.set_watch_file("../../resources/scripts/hello_world.lua"); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } _render_manager.register_renderer<RectDrawer>(_state); _render_manager.register_renderer<TextDrawer>(_state, FONT_PATH); _render_manager.register_renderer<InputHandler>(_state); } void draw() { _state.update(); _render_manager.update(_state); try { _lua_manager.update(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } _state.render_queue.draw(_state.context.get_ptr(), _state.clear_color); } void render_view_tree() { const auto screen_size = _state.context.get_screen_size(); auto screen_rect = Rect::from_bottom_left(glm::vec2 { 0 }, screen_size); std::exchange(*_root_view, _ui_builder.build_ui(_state)); _root_view_render->render(_state, _render_manager, screen_rect, *_root_view); } void error(int error_code, const char* error_message) { std::cerr << error_message << std::endl; } uint32_t draw_rect(components::RenderableRect rect, components::RenderBounds bounds) { return _render_manager .create_renderer( _state, RectDrawer::renderable_type { rect, bounds }, _state.white_texture_batch ) .id(); } private: State _state; RenderManager _render_manager; lua::LuaManager _lua_manager; T _ui_builder; std::unique_ptr<root_view_t> _root_view; std::unique_ptr<root_view_renderer_t> _root_view_render; }; struct MyBuilder { MyLifecycleManager<MyUIBuilder>* build(DivisionContext* ctx) { return new MyLifecycleManager { ctx, MyUIBuilder {} }; } }; int main(int argc, char** argv) { CoreRunner core_runner { "View tree example", glm::vec2 { 512, 512 } }; // NOLINT core_runner.run(MyBuilder {}); }