4#include "imgui/imgui.h"
29#include <imgui_widgets/gizmo.h>
33#include <filedialog/filedialog.h>
42 void reload_script_domains(
rtti::context& ctx, script_system& scripting,
bool recompile)
44 const bool reload_engine =
45 ctx.
has<project_manager>() &&
46 ctx.
get_cached<project_manager>().get_editor_settings().scripting.reload_engine_domain;
48 scripting.unload_app_domain();
51 scripting.unload_engine_domain();
52 scripting.load_engine_domain(ctx, recompile);
54 scripting.load_app_domain(ctx, recompile);
62 auto is_active() const ->
bool
64 return ImGui::IsMouseDown(ImGuiMouseButton_Left) || ImGui::IsAnyItemActive();
69 const bool down = is_active();
72 if(!ImGui::IsAnyItemActive())
75 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) ||
76 ImGui::GetIO().AppFocusLost)
81 if(ImGui::IsMouseReleased(ImGuiMouseButton_Left))
94 auto current_merge_key() const -> uint64_t
100 static merge_session session;
125 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
127 waiting_for_compilation_before_play_ =
true;
133 scripting.wait_for_jobs_to_finish(ctx);
151 for(
auto scn : scenes)
153 auto&
cache = caches_[scn->tag];
155 save_checkpoint(ctx,
cache);
166 scripting.wait_for_jobs_to_finish(ctx);
170 reload_script_domains(ctx, scripting,
true);
177 for(
auto scn : scenes)
179 if(defer_game_scene && scn->tag ==
"game")
183 auto&
cache = caches_[scn->tag];
185 load_checkpoint(ctx,
cache,
true);
192 waiting_for_compilation_before_play_ =
false;
198 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
205 auto cache_it = caches_.find(
"game");
206 if(cache_it == caches_.end())
213 if(scn->tag !=
"game")
217 auto&
cache = cache_it->second;
219 load_checkpoint(ctx,
cache,
true);
227 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
234 scripting.wait_for_jobs_to_finish(ctx);
246 for(
auto scn : scenes)
249 if(scn->tag ==
"game")
254 auto&
cache = caches_[scn->tag];
256 save_checkpoint(ctx,
cache);
265 scripting.wait_for_jobs_to_finish(ctx);
269 reload_script_domains(ctx, scripting,
false);
271 for(
auto scn : scenes)
273 auto&
cache = caches_[scn->tag];
275 load_checkpoint(ctx,
cache,
true);
292 if(waiting_for_compilation_before_play_)
307 for(
auto scn : scenes)
309 auto&
cache = caches_[scn->tag];
311 save_checkpoint(ctx,
cache);
320 reload_script_domains(ctx, scripting,
false);
322 for(
auto scn : scenes)
324 auto&
cache = caches_[scn->tag];
326 load_checkpoint(ctx,
cache,
true);
337 selection_cache_ = {};
344 auto& id_comp = sel->get_or_emplace<id_component>();
345 id_comp.generate_if_nil();
346 selection_cache_.uids.emplace_back(id_comp.id);
369void editing_manager::load_checkpoint(
rtti::context& ctx, scene_cache&
cache,
bool recover_selection)
387 std::vector<entt::handle> entities;
392 cache.scn->registry->view<id_component>().each(
393 [&](
auto e,
auto&& comp)
396 if(std::find(selection_cache_.uids.begin(), selection_cache_.uids.end(), uid) != selection_cache_.uids.end())
398 entities.emplace_back(
cache.scn->create_handle(e));
402 for(
auto entity : entities)
404 if(recover_selection)
416 auto& rpath = ctx.
get_cached<rendering_system>();
417 rpath.on_frame_update(*
cache.scn, dt);
418 rpath.on_frame_before_render(*
cache.scn, dt);
439 for(
auto scn : scenes)
442 std::vector<entt::handle> affected_entities;
444 [&](
auto e,
auto&& prefab_comp)
446 auto entity = scn->create_handle(e);
447 if(prefab_comp.source == pfb)
449 affected_entities.emplace_back(
entity);
453 for(
auto&
entity : affected_entities)
463 [&ctx,
entity, pfb]()
mutable
483 if(
auto trans_comp =
entity.template try_get<transform_component>())
485 auto parent = trans_comp->get_parent();
486 auto pos = trans_comp->get_position_local();
487 auto rot = trans_comp->get_rotation_local();
494 return !prefab_comp.has_serialization_override(property_path);
496 path_ctx.enable_recording();
505 new_trans.set_rotation_local(rot);
507 new_trans.set_parent(parent,
false);
521 [&](
auto e,
auto&& comp)
532 if(ImGui::IsKeyDown(ImGuiKey_LeftShift))
536 if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
565 if(!play.is_active())
567 using namespace std::chrono;
568 static auto last_eviction = steady_clock::now();
569 auto now = steady_clock::now();
570 if(now - last_eviction > seconds(30))
597 if(clear_selection_tools)
599 ImGuizmo::Enable(
false);
600 ImGuizmo::Enable(
true);
607 bool selection_changed = old_selection.size() != new_selection.size();
608 if (!selection_changed && !old_selection.empty())
611 for (
size_t i = 0; i < old_selection.size() && !selection_changed; ++i)
613 if (i >= new_selection.size() || old_selection[i] != new_selection[i])
615 selection_changed =
true;
621 if (selection_changed)
624 queue_action(
"Unselect", std::make_shared<selection_action_t>(
this, old_selection, new_selection,
false));
643 auto on_continue = [
this,&ctx,
prefab]()
675 auto on_save = [
this,&ctx]()
686 prompt_save_changes(ctx, on_save, on_continue);
704auto editing_manager::prompt_save_changes(
rtti::context& ctx,
const std::function<
void()>& on_save,
const std::function<
void()>& on_continue) ->
bool
707 "Do you want to save the changes you made?",
731 auto on_save = [
this,&ctx]()
736 auto on_continue = [
this, &ctx]()
750 switch (save_changes)
762 prompt_save_changes(ctx, on_save, on_continue);
810 if (is_prefab_mode())
812 return &prefab_scene;
825 for(
auto scn : scenes)
899 action->merge_key = session.current_merge_key();
908 action->undoable =
false;
932 bool last_enabled =
true;
951 for (
auto& action : actions)
956 action->execution_count++;
962 if (action->is_undoable())
978 if (undo_stack.can_undo())
980 has_unsaved_changes_ =
true;
981 return undo_stack.undo();
988 if (undo_stack.can_redo())
990 has_unsaved_changes_ =
true;
991 return undo_stack.redo();
1001 if(action->modifies_scene_content())
1003 has_unsaved_changes_ =
true;
1009 if(!play.is_active())
const btCollisionObject * object
Manages assets, including loading, unloading, and storage.
void evict_unused_assets(const std::string &group, std::chrono::steady_clock::duration max_idle)
Evicts full-loaded assets not accessed within the given duration. Demotes them back to deferred state...
Class that contains core data for audio listeners. There can only be one instance of it per scene.
std::chrono::duration< float > delta_t
#define APPLOG_ERROR(...)
#define APPLOG_TRACE(...)
ModalResult
Modal result flags for message box buttons.
auto ShowSaveConfirmation(const std::string &title, const std::string &message, std::function< void(ModalResult)> callback) -> std::shared_ptr< MsgBox >
Show a save confirmation dialog with Save/Don't Save/Cancel buttons.
NOTIFY_INLINE void PushNotification(const ImGuiToast &toast)
Insert a new toast in the list.
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
void set_path_context(path_context *ctx)
auto get_path_context() -> path_context *
auto atomic_save_to_file(const fs::path &key, const asset_handle< T > &obj) -> bool
auto load_from_stream(std::istream &stream, entt::handle e, script_component::script_object &obj) -> bool
@ immediate
Schedule load on thread pool now (default, backward compatible).
auto save_to_stream(std::ostream &stream, entt::const_handle e, const script_component::script_object &obj) -> bool
Thread-safe handle to an asset.
auto is_valid() const -> bool
Checks if the handle references a task.
std::function< bool(const std::string &)> should_serialize_property_callback
static void create_default_3d_scene_for_editing(rtti::context &ctx, scene &scn)
Creates a default 3D scene for editing.
Manages the entity-component-system (ECS) operations for the ACE framework.
auto get_scene() -> scene &
Gets the current scene.
std::vector< entt::meta_any > objects
auto is_prefab_mode() const -> bool
auto get_active_scene(rtti::context &ctx) -> scene *
void on_play_begin(rtti::context &ctx)
void on_play_after_end(rtti::context &ctx)
auto try_get_selections_as() const -> std::vector< const T * >
auto get_select_mode() const -> select_mode
void push_undo_stack_enabled(bool enabled)
ImGuizmo::MODE mode
current manipulation gizmo space.
void on_action_executed(std::shared_ptr< editing_action_t > action)
void focus_path(const fs::path &object)
auto undo() -> std::shared_ptr< editing_action_t >
void pop_undo_stack_enabled()
auto init(rtti::context &ctx) -> bool
void on_play_before_begin(rtti::context &ctx)
void on_frame_update(rtti::context &ctx, delta_t)
void select(const T &entry, select_mode mode=select_mode::normal, std::string hint="")
void on_script_recompile(rtti::context &ctx, const std::string &protocol, uint64_t version)
void clear(bool clear_unsaved=true)
std::vector< std::shared_ptr< editing_action_t > > pending_actions
entt::handle prefab_entity
void sync_prefab_entity(rtti::context &ctx, entt::handle entity, const asset_handle< prefab > &pfb)
void clear_unsaved_changes()
selection selection_data
selection data containing selected object
void queue_action(const std::string &name, const std::function< void()> &action)
bool auto_rebuild_reflection_probes
void do_action(const std::string &name, const std::function< void()> &action)
auto redo() -> std::shared_ptr< editing_action_t >
void sync_prefab_instances(rtti::context &ctx, scene *scn)
void on_prefab_updated(const asset_handle< prefab > &pfb)
void unload_scenes_scripting(const std::vector< scene * > &scenes)
void enter_prefab_mode(rtti::context &ctx, const asset_handle< prefab > &prefab, bool auto_save=false)
std::stack< bool > undo_stack_enabled
auto deinit(rtti::context &ctx) -> bool
void add_action(const std::string &name, std::shared_ptr< editing_action_t > action, bool immediate=true)
void focus(entt::meta_any object)
Selects an object. Can be anything.
void exit_prefab_mode(rtti::context &ctx, save_option save_changes=save_option::prompt)
undo_redo_stack undo_stack
void save_prefab_changes(rtti::context &ctx)
editing_mode current_mode
asset_handle< prefab > edited_prefab
void unselect(bool clear_selection_tools=true)
Clears the selection data.
static auto rebuild_reflection_probes(rtti::context &ctx, bool force_full_first_frame=true) -> size_t
Flags every reflection probe across all loaded scenes for rebuild.
static auto context() -> rtti::context &
hpp::event< void(rtti::context &)> on_play_before_begin
engine play events
Owns play-mode state and orchestrates the splash -> running lifecycle.
Component that holds a reference to a prefab asset and tracks property overrides.
Represents a generic prefab with a buffer for serialized data.
Represents a scene in the ACE framework, managing entities and their relationships.
auto instantiate_out(const asset_handle< prefab > &pfb, entt::handle &, bool call_callbacks=true) -> bool
Instantiates a prefab in the scene.
static auto get_all_scenes() -> const std::vector< scene * > &
auto instantiate(const asset_handle< prefab > &pfb, bool call_callbacks=true) -> entt::handle
void unload()
Unloads the scene, removing all entities.
std::unique_ptr< entt::registry > registry
The registry that manages all entities in the scene.
struct unravel::settings::splash_settings splash
Class responsible for timers.
void push_if_undoable(std::shared_ptr< editing_action_t > action)
delta_t last_action_elapsed_time