Unravel Engine C++ Reference
Loading...
Searching...
No Matches
inspector_prefab_component.cpp
Go to the documentation of this file.
2#include "imgui_widgets/tooltips.h"
3#include "inspectors.h"
8#include <engine/ecs/scene.h>
10#include <uuid/uuid.h>
11#include <functional>
13
14// must be below all
16
17namespace unravel
18{
19
20namespace
21{
22
23
24} // anonymous namespace
25
26
28 entt::meta_any& var,
29 const meta_any_proxy& var_proxy,
30 const var_info& info,
31 const entt::meta_custom& custom) -> inspect_result
32{
33 auto& data = var.cast<prefab_component&>();
34 inspect_result result{};
35
36 auto root_prefab_entity = data.get_owner();
37 // Show override information
38 const auto& overrides = data.get_all_overrides();
39
40 if(!overrides.empty())
41 {
42 std::string header_id = fmt::format("Property Overrides: {}###Override Details", overrides.size());
43 if(ImGui::CollapsingHeader(header_id.c_str()))
44 {
45 ImGui::Indent();
46
47 // Display overrides - show pretty paths to users
48 std::string serialization_path_to_remove;
49
50 // Display overrides from the new structure
51 const auto& property_overrides = data.get_all_overrides();
52 for(const auto& override_data : property_overrides)
53 {
54 // Build full display path with entity name
55 std::string display_path;
56
57 // Find the entity by UUID and get its name
58 auto found_entity = scene::find_entity_by_prefab_uuid(root_prefab_entity, override_data.entity_uuid);
59 if (found_entity)
60 {
61 std::string entity_name = entity_panel::get_entity_name(found_entity);
62 display_path = entity_name + "/" + override_data.pretty_component_path;
63 }
64 else
65 {
66 // Fallback if entity not found
67 display_path = override_data.pretty_component_path;
68 }
69
70 ImGui::BeginGroup();
71 ImGui::BulletText("%s", display_path.c_str());
72 ImGui::SameLine();
73
74 // Add a revert button for each override
75 std::string override_id = hpp::to_string(override_data.entity_uuid) + ":" + override_data.component_path;
76 ImGui::PushID(override_id.c_str());
77 if(ImGui::SmallButton("Revert"))
78 {
79 // Store the UUID and component path for removal
80 serialization_path_to_remove = override_id;
81 }
82 ImGui::PopID();
83 ImGui::EndGroup();
84
85
86 if(ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip) && found_entity)
87 {
88 auto& em = ctx.get_cached<editing_manager>();
89
90 em.focus(found_entity);
91 }
92
93 // Show technical details as tooltip
94 std::string entity_name = found_entity ? entity_panel::get_entity_name(found_entity) : "Entity Not Found";
95 ImGui::SetItemTooltipEx("Entity: %s\nUUID: %s\nComponent Path: %s\nPretty Path: %s",
96 entity_name.c_str(),
97 hpp::to_string(override_data.entity_uuid).c_str(),
98 override_data.component_path.c_str(),
99 override_data.pretty_component_path.c_str());
100
101 }
102
103 // Process removal outside the loop to avoid iterator invalidation
104 if(!serialization_path_to_remove.empty())
105 {
106 // Parse the stored override ID to extract UUID and component path
107 auto colon_pos = serialization_path_to_remove.find(':');
108 if (colon_pos != std::string::npos)
109 {
110 std::string uuid_str = serialization_path_to_remove.substr(0, colon_pos);
111 std::string component_path = serialization_path_to_remove.substr(colon_pos + 1);
112
113 auto uuid_opt = hpp::uuid::from_string(uuid_str);
114 if (uuid_opt.has_value())
115 {
116 data.remove_override(uuid_opt.value(), component_path);
117 data.changed = true;
118 result.changed = true;
119
120 auto& em = ctx.get_cached<editing_manager>();
121 em.sync_prefab_entity(ctx, root_prefab_entity, data.source);
122 }
123 }
124 }
125
126 ImGui::Unindent();
127 }
128 ImGui::Separator();
129 }
130
131 if(!data.removed_entities.empty())
132 {
133 std::string header_id = fmt::format("Removed Entities: {}###Removed Entities", data.removed_entities.size());
134 if(ImGui::CollapsingHeader(header_id.c_str()))
135 {
136 ImGui::Indent();
137
138 hpp::uuid uiid_to_remove;
139 for(auto& entity_uuid : data.removed_entities)
140 {
141 auto uuid_str = hpp::to_string(entity_uuid);
142 ImGui::BulletText("%s", uuid_str.c_str());
143 ImGui::SameLine();
144
145 // Add a revert button for each override
146 ImGui::PushID(uuid_str.c_str());
147 if(ImGui::SmallButton("Revert"))
148 {
149 // Store the UUID and component path for removal
150 uiid_to_remove = entity_uuid;
151 }
152 ImGui::PopID();
153 }
154
155 if(!uiid_to_remove.is_nil())
156 {
157 data.removed_entities.erase(uiid_to_remove);
158 data.changed = true;
159 result.changed = true;
160
161 auto& em = ctx.get_cached<editing_manager>();
162 em.sync_prefab_entity(ctx, root_prefab_entity, data.source);
163
164 }
165
166 ImGui::Unindent();
167 }
168 }
169
170
171 // Control buttons
172 if(ImGui::Button("Apply All to Prefab", ImVec2(-1, ImGui::GetFrameHeight())))
173 {
174 data.changed = false;
175 auto prefab_path = fs::resolve_protocol(data.source.id());
176 asset_writer::atomic_save_to_file(prefab_path.string(), root_prefab_entity);
177 data.clear_overrides(); // Clear overrides after applying to prefab
178 result.changed = true;
179 }
180
181 if(ImGui::Button("Revert All Overrides", ImVec2(-1, ImGui::GetFrameHeight())))
182 {
183 data.clear_overrides();
184 data.changed = true;
185 result.changed = true;
186 auto& em = ctx.get_cached<editing_manager>();
187 em.sync_prefab_entity(ctx, root_prefab_entity, data.source);
188 }
189
190
191 ImGui::NewLine();
192
193 result |= inspect_var_properties(ctx, var, var_proxy, info, custom);
194
195 if(result.changed)
196 {
197 auto& em = ctx.get_cached<editing_manager>();
198 em.sync_prefab_entity(ctx, root_prefab_entity, data.source);
199 }
200
201 return result;
202}
203
204} // namespace unravel
static auto get_entity_name(entt::handle entity) -> std::string
Gets the entity name from tag component.
path resolve_protocol(const path &_path)
Given the specified path/filename, resolve the final full filename. This will be based on either the ...
auto atomic_save_to_file(const fs::path &key, const asset_handle< T > &obj) -> bool
auto inspect_var_properties(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result
Inspects all properties of a complex object recursively.
void sync_prefab_entity(rtti::context &ctx, entt::handle entity, const asset_handle< prefab > &pfb)
void focus(entt::meta_any object)
Selects an object. Can be anything.
Result of an inspection operation indicating what changes occurred.
Definition inspector.h:146
auto inspect(rtti::context &ctx, entt::meta_any &var, const meta_any_proxy &var_proxy, const var_info &info, const entt::meta_custom &custom) -> inspect_result override
Safe deferred property access proxy for arbitrary object properties.
Definition inspector.h:198
Component that holds a reference to a prefab asset and tracks property overrides.
static auto find_entity_by_prefab_uuid(entt::handle root_entity, const hpp::uuid &target_uuid) -> entt::handle
Finds an entity by UUID in the scene.
Definition scene.cpp:316
Metadata about a variable being inspected.
Definition inspector.h:133