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 <uuid/uuid.h>
5
6namespace unravel
7{
8
9// prefab_property_override_data implementation
10
11prefab_property_override_data::prefab_property_override_data(const hpp::uuid& uuid, const std::string& path)
12 : entity_uuid(uuid), component_path(path), pretty_component_path(path)
13{
14}
15
16prefab_property_override_data::prefab_property_override_data(const hpp::uuid& uuid, const std::string& path, const std::string& pretty_path)
17 : entity_uuid(uuid), component_path(path), pretty_component_path(pretty_path)
18{
19}
20
22{
23 return entity_uuid == other.entity_uuid && component_path == other.component_path;
24}
25
27{
28 if (entity_uuid != other.entity_uuid)
29 {
30 return entity_uuid < other.entity_uuid;
31 }
32 return component_path < other.component_path;
33}
34
35// prefab_component implementation
41
42void prefab_component::add_override(const hpp::uuid& entity_uuid, const std::string& component_path)
43{
44 property_overrides.emplace(entity_uuid, component_path);
45}
46
47void prefab_component::add_override(const hpp::uuid& entity_uuid, const std::string& component_path, const std::string& pretty_component_path)
48{
49 // Helper function to check if one path is a parent of another
50 auto is_parent_path = [](const std::string& parent, const std::string& child) -> bool
51 {
52 if (child.length() <= parent.length())
53 {
54 return false;
55 }
56 if (child.substr(0, parent.length()) != parent)
57 {
58 return false;
59 }
60 char next_char = child[parent.length()];
61 return next_char == '/' || next_char == '[';
62 };
63
64 // Remove any existing overrides that are parents or children of this path for the same entity
65 std::vector<prefab_property_override_data> to_remove;
66 for (const auto& existing_override : get_all_overrides())
67 {
68 // Only consider overrides for the same entity
69 if (existing_override.entity_uuid != entity_uuid)
70 {
71 continue;
72 }
73
74 // Check if the existing override is a parent of the new one
75 if (is_parent_path(existing_override.component_path, component_path))
76 {
77 to_remove.push_back(existing_override);
78 }
79 // Check if the new override is a parent of existing ones
80 else if (is_parent_path(component_path, existing_override.component_path))
81 {
82 // Don't add the new override, the existing one is more specific
83 return;
84 }
85 }
86
87 // Remove the parent overrides
88 for (const auto& override_to_remove : to_remove)
89 {
90 remove_override(override_to_remove.entity_uuid, override_to_remove.component_path);
91 }
92 property_overrides.emplace(entity_uuid, component_path, pretty_component_path);
93}
94
95auto prefab_component::has_override(const hpp::uuid& entity_uuid, const std::string& component_path) const -> bool
96{
97 return property_overrides.contains(prefab_property_override_data{entity_uuid, component_path});
98}
99
100void prefab_component::remove_override(const hpp::uuid& entity_uuid, const std::string& component_path)
101{
102 property_overrides.erase(prefab_property_override_data{entity_uuid, component_path});
103}
104
105void prefab_component::remove_entity(const hpp::uuid& entity_uuid)
106{
107 removed_entities.insert(entity_uuid);
108
109 for(auto& override : property_overrides)
110 {
111 if(override.entity_uuid == entity_uuid)
112 {
113 property_overrides.erase(override);
114 return;
115 }
116 }
117}
118
119
124
125auto prefab_component::has_serialization_override(const std::string& serialization_path) const -> bool
126{
127 // Parse serialization path: "entities/uuid/components/component_type/property_path"
128 auto segments = string_utils::tokenize(serialization_path, "/");
129
130 if (segments.size() < 4 || segments[0] != "entities" || segments[2] != "components")
131 {
132 return false;
133 }
134
135 // Extract UUID and component path
136 std::string uuid_str = segments[1];
137 auto uuid_opt = hpp::uuid::from_string(uuid_str);
138 if (!uuid_opt.has_value())
139 {
140 return false;
141 }
142
143 // Build component path from remaining segments, skipping Script/script_components/ if present
144 std::string component_path;
145 bool first_segment = true;
146
147 for (size_t i = 3; i < segments.size(); ++i)
148 {
149 if (!first_segment)
150 {
151 component_path += "/";
152 }
153 component_path += segments[i];
154 first_segment = false;
155 }
156
157 if(has_override(uuid_opt.value(), component_path))
158 {
159 APPLOG_TRACE("Serialization override found for property: {}", serialization_path);
160 return true;
161 }
162 return false;
163}
164
165} // namespace unravel
#define APPLOG_TRACE(...)
Definition logging.h:17
auto tokenize(const std::string &str, const std::string &delimiters) -> string_tokens_t
Definition utils.cpp:136
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