Unravel Engine C++ Reference
Loading...
Searching...
No Matches
prefab_component.cpp
Go to the documentation of this file.
1#include "prefab_component.h"
2#include <sstream>
3#include <string_view>
4#include <uuid/uuid.h>
6
7namespace unravel
8{
9
10// prefab_property_override_data implementation
11
12prefab_property_override_data::prefab_property_override_data(const hpp::uuid& uuid, const std::string& path)
13 : entity_uuid(uuid), component_path(path), pretty_component_path(path)
14{
15}
16
17prefab_property_override_data::prefab_property_override_data(const hpp::uuid& uuid, const std::string& path, const std::string& pretty_path)
18 : entity_uuid(uuid), component_path(path), pretty_component_path(pretty_path)
19{
20}
21
23{
24 return entity_uuid == other.entity_uuid && component_path == other.component_path;
25}
26
28{
29 if (entity_uuid != other.entity_uuid)
30 {
31 return entity_uuid < other.entity_uuid;
32 }
33 return component_path < other.component_path;
34}
35
36// prefab_component implementation
42
43void prefab_component::add_override(const hpp::uuid& entity_uuid, const std::string& component_path)
44{
45 property_overrides.emplace(entity_uuid, component_path);
46}
47
48void prefab_component::add_override(const hpp::uuid& entity_uuid, const std::string& component_path, const std::string& pretty_component_path)
49{
50 // Helper function to check if one path is a parent of another
51 auto is_parent_path = [](const std::string& parent, const std::string& child) -> bool
52 {
53 if (child.length() <= parent.length())
54 {
55 return false;
56 }
57 if (child.substr(0, parent.length()) != parent)
58 {
59 return false;
60 }
61 char next_char = child[parent.length()];
62 return next_char == '/' || next_char == '[';
63 };
64
65 // Remove any existing overrides that are parents or children of this path for the same entity
66 std::vector<prefab_property_override_data> to_remove;
67 for (const auto& existing_override : get_all_overrides())
68 {
69 // Only consider overrides for the same entity
70 if (existing_override.entity_uuid != entity_uuid)
71 {
72 continue;
73 }
74
75 // Check if the existing override is a parent of the new one
76 if (is_parent_path(existing_override.component_path, component_path))
77 {
78 to_remove.push_back(existing_override);
79 }
80 // Check if the new override is a parent of existing ones
81 else if (is_parent_path(component_path, existing_override.component_path))
82 {
83 // Don't add the new override, the existing one is more specific
84 return;
85 }
86 }
87
88 // Remove the parent overrides
89 for (const auto& override_to_remove : to_remove)
90 {
91 remove_override(override_to_remove.entity_uuid, override_to_remove.component_path);
92 }
93 property_overrides.emplace(entity_uuid, component_path, pretty_component_path);
94}
95
96auto prefab_component::has_override(const hpp::uuid& entity_uuid, const std::string& component_path) const -> bool
97{
98 return property_overrides.contains(prefab_property_override_data{entity_uuid, component_path});
99}
100
101void prefab_component::remove_override(const hpp::uuid& entity_uuid, const std::string& component_path)
102{
103 property_overrides.erase(prefab_property_override_data{entity_uuid, component_path});
104}
105
106void prefab_component::remove_entity(const hpp::uuid& entity_uuid)
107{
108 removed_entities.insert(entity_uuid);
109
110 for(auto& override : property_overrides)
111 {
112 if(override.entity_uuid == entity_uuid)
113 {
114 property_overrides.erase(override);
115 return;
116 }
117 }
118}
119
120
125
126auto prefab_component::has_serialization_override(const std::string& serialization_path) const -> bool
127{
128 // Parse serialization path: "entities/uuid/components/component_type/property_path"
129 auto segments = string_utils::tokenize(serialization_path, "/");
130
131 if (segments.size() < 4)
132 {
133 return false;
134 }
135
136 bool starts_with_entities = hpp::string_view(segments[0]).starts_with("entities");
137 if(!starts_with_entities)
138 {
139 return false;
140 }
141
142 bool starts_with_components = hpp::string_view(segments[2]).starts_with("components");
143 if(!starts_with_components)
144 {
145 return false;
146 }
147
148 // Extract UUID and component path
149 std::string_view uuid_str = segments[1];
150 auto uuid_opt = hpp::uuid::from_string(uuid_str);
151 if (!uuid_opt.has_value())
152 {
153 return false;
154 }
155
156 // Build component path from remaining segments, skipping Script/script_components/ if present
157 std::string component_path;
158 bool first_segment = true;
159
160 for (size_t i = 3; i < segments.size(); ++i)
161 {
162 if (!first_segment)
163 {
164 component_path += "/";
165 }
166 component_path += segments[i];
167 first_segment = false;
168 }
169
170 // APPLOG_TRACE("Checking for serialization override for property: {}", serialization_path);
171 if(has_override(uuid_opt.value(), component_path))
172 {
173 // APPLOG_TRACE("Serialization override found for property: {}", serialization_path);
174 return true;
175 }
176 return false;
177}
178
179} // namespace unravel
Hash specialization for batch_key to enable use in std::unordered_map.
auto tokenize(const std::string &str, const std::string &delimiters) -> string_tokens_t
Definition utils.cpp:153
const segment_list * segments
void remove_override(const hpp::uuid &entity_uuid, const std::string &component_path)
Remove a property override.
void clear_overrides()
Clear all overrides (for applying all changes to prefab)
auto has_serialization_override(const std::string &serialization_path) const -> bool
Check if a serialization path has an override (for backward compatibility)
auto has_override(const hpp::uuid &entity_uuid, const std::string &component_path) const -> bool
Check if a property is overridden.
std::set< hpp::uuid > removed_entities
std::set< prefab_property_override_data > property_overrides
Storage of property overrides Each override is identified by entity UUID + component path This allows...
void remove_entity(const hpp::uuid &entity_uuid)
Remove an entity from the prefab.
void add_override(const hpp::uuid &entity_uuid, const std::string &component_path)
Add a property override.
auto get_all_overrides() const -> const std::set< prefab_property_ override _data > &
Get all overrides.
Represents a property override with entity UUID and component/property path.
auto operator==(const prefab_property_override_data &other) const -> bool
auto operator<(const prefab_property_override_data &other) const -> bool