12#include <RmlUi/Core/Animation.h>
13#include <RmlUi/Core/Element.h>
14#include <RmlUi/Core/ElementDocument.h>
15#include <RmlUi/Core/Property.h>
16#include <RmlUi/Core/StyleTypes.h>
17#include <RmlUi/Core/Tween.h>
26constexpr const char* default_splash_document =
"engine:/data/ui/splash.rhtml";
27constexpr const char* splash_seq_scope =
"splash_scene";
28constexpr const char* made_with_logo =
"engine:/data/logos/made_with.png";
29constexpr float made_with_duration_sec = 5.0f;
31struct splash_logo_slot
39 return std::chrono::duration_cast<seq::duration_t>(
delta_t(std::max(0.0f, seconds)));
42auto collect_logo_slots(
rtti::context& ctx) -> std::vector<splash_logo_slot>
44 std::vector<splash_logo_slot> slots;
45 if(!ctx.has<settings>())
50 const auto& splash_settings = ctx.get<settings>().splash;
51 slots.reserve(splash_settings.logos.size() + 1);
54 if(splash_settings.show_made_with)
56 slots.push_back({made_with_logo, made_with_duration_sec});
59 for(
const auto&
entry : splash_settings.logos)
65 slots.push_back({
entry.logo.id(), std::max(0.0f,
entry.duration_sec)});
71auto get_splash_logo_element(entt::handle ui_entity) -> Rml::Element*
73 if(!ui_entity || !ui_entity.all_of<ui_document_component>())
77 auto& ui_comp = ui_entity.get<ui_document_component>();
82 return ui_comp.document->GetElementById(
"splash-logo");
85void set_logo_animation(Rml::Element* logo_el,
const char* keyframe_name,
float duration_sec)
92 Rml::Animation animation;
94 animation.tween = Rml::Tween(Rml::Tween::Cubic, Rml::Tween::Out);
95 animation.name = keyframe_name;
96 animation.num_iterations = 1;
98 Rml::AnimationList animations;
99 animations.push_back(animation);
100 logo_el->SetProperty(Rml::PropertyId::Animation, Rml::Property(animations, Rml::Unit::ANIMATION));
103void set_logo_visible(entt::handle ui_entity,
bool visible)
109 if(!ui_entity.all_of<ui_document_component>())
113 auto* logo_el = get_splash_logo_element(ui_entity);
120 logo_el->SetClass(
"visible",
true);
121 logo_el->SetProperty(Rml::PropertyId::Display, Rml::Property(Rml::Style::Display::Block));
125 logo_el->SetClass(
"visible",
false);
126 logo_el->SetProperty(Rml::PropertyId::Display, Rml::Property(Rml::Style::Display::None));
136 auto* logo_el = get_splash_logo_element(ui_entity);
142 logo_el->SetClass(
"visible",
false);
143 logo_el->SetProperty(Rml::PropertyId::Display, Rml::Property(Rml::Style::Display::Block));
144 logo_el->SetClass(
"visible",
true);
145 set_logo_animation(logo_el,
"splash-logo-show",
duration_sec);
148void fade_out_logo(entt::handle ui_entity,
float duration_sec)
154 auto* logo_el = get_splash_logo_element(ui_entity);
159 set_logo_animation(logo_el,
"splash-logo-fade-out",
duration_sec);
162auto build_logo_sequence(entt::handle ui_entity,
const std::vector<splash_logo_slot>& slots,
float fade_in_sec,
float fade_out_sec)
165 std::vector<seq::seq_action> actions;
166 actions.reserve(slots.size() * 2 + 2);
168 if(fade_in_sec > 0.0f)
170 actions.push_back(
seq::delay(to_duration(fade_in_sec)));
173 for(
size_t i = 0;
i < slots.size(); ++
i)
175 const auto& slot = slots[
i];
176 auto show_action =
seq::delay(to_duration(slot.duration_sec));
177 show_action.on_begin.connect([ui_entity, path = slot.texture_path, duration = slot.duration_sec]()
179 show_logo(ui_entity, path, duration);
181 if(fade_out_sec <= 0.0f && i + 1 == slots.size())
183 show_action.on_end.connect([ui_entity]()
185 set_logo_visible(ui_entity,
false);
188 actions.push_back(show_action);
191 if(fade_out_sec > 0.0f)
193 auto hide_action =
seq::delay(to_duration(fade_out_sec));
194 hide_action.on_begin.connect([ui_entity, duration = fade_out_sec]()
196 fade_out_logo(ui_entity, duration);
198 hide_action.on_end.connect([ui_entity]()
200 set_logo_visible(ui_entity,
false);
202 actions.push_back(hide_action);
213 return default_splash_document;
218 return !collect_logo_slots(ctx).empty();
227 const auto slots = collect_logo_slots(ctx);
234 float fade_in_sec = 0.5f;
235 float fade_out_sec = 0.5f;
238 const auto& splash_settings = ctx.
get<
settings>().splash;
239 fade_in_sec = std::max(0.0f, splash_settings.fade_in_sec);
240 fade_out_sec = std::max(0.0f, splash_settings.fade_out_sec);
247 auto document_asset = am.get_asset<
ui_tree>(document_key);
250 APPLOG_ERROR(
"Failed to load splash UI document asset: {}", document_key);
262 ui_comp.
asset = document_asset;
265 set_logo_visible(state.
ui_entity,
false);
286 set_logo_visible(state.
ui_entity,
false);
305 if(state.setup_failed)
309 if(state.action != 0)
313 if(state.pending_sequence.is_valid())
Manages assets, including loading, unloading, and storage.
std::chrono::duration< float > delta_t
#define APPLOG_ERROR(...)
auto is_finished(seq_id_t id) -> bool
Checks if the action has finished.
auto start(seq_action action, const seq_scope_policy &scope_policy, hpp::source_location location) -> seq_id_t
Starts a new action.
auto delay(const duration_t &duration, const sentinel_t &sentinel) -> seq_action
Creates a delay action.
auto sequence(const std::vector< seq_action > &actions, const sentinel_t &sentinel) -> seq_action
Creates a sequential action that executes a list of actions one after another.
void stop(seq_id_t id)
Stops the action associated with the given ID.
std::chrono::nanoseconds duration_t
Represents a duration in nanoseconds.
void teardown(splash_scene_state &state)
auto is_finished(const splash_scene_state &state) -> bool
void update(rtti::context &ctx, splash_scene_state &state)
auto has_content(rtti::context &ctx) -> bool
auto get_document_key(rtti::context &ctx) -> std::string
void setup(rtti::context &ctx, scene &scn, splash_scene_state &state)
@ screen_space_overlay
Screen-space overlay (viewport-sized or positioned)
Represents an action within the sequence management system. Contains lifecycle events and management ...
auto is_valid() const noexcept -> bool
Checks if the action is valid.
static auto create_ui_document_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a UI document entity.
static auto create_camera_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a camera entity.
Represents a scene in the ACE framework, managing entities and their relationships.
void unload()
Unloads the scene, removing all entities.
seq::seq_action pending_sequence
Component that holds a reference to a UI document for RmlUi rendering.
asset_handle< ui_tree > asset
Path to the UI document file (HTML/RML)
auto is_loaded() const -> bool
Check if document is currently loaded.
Represents a UI visual tree asset (HTML/RML document).