Unravel Engine C++ Reference
Loading...
Searching...
No Matches
entity_actions.cpp
Go to the documentation of this file.
1#include "entity_actions.h"
12#include <engine/engine.h>
15
16namespace unravel
17{
18
19entity_add_component_action_t::entity_add_component_action_t(entt::handle ent, const entt::meta_type& ctype)
20 : entity(ent), component_type(ctype)
21{
22 name = "Add Component " + entt::get_pretty_name(component_type);
23}
24
26{
27 if (entity)
28 {
29 do_was_successful = component_type.invoke("component_add"_hs, {}, entity).cast<bool>();
30 }
31}
32
34{
35 if (entity)
36 {
37 component_type.invoke("component_remove"_hs, {}, entity);
38 }
39}
40
42{
43 return false;
44}
45
47{
48 return entity.valid() && component_type;
49}
50
52{
53 //draw_in_inspector_impl(ctx, component_type, component_type, {});
54}
55
56entity_remove_component_action_t::entity_remove_component_action_t(entt::handle ent, const entt::meta_type& ctype)
57 : entity(ent), component_type(ctype)
58{
59 name = "Remove Component " + entt::get_pretty_name(component_type);
60}
61
63{
64 if (entity)
65 {
66 stream = {};
67 component_type.invoke("component_save"_hs, {}, entity, entt::forward_as_meta(stream));
68 do_was_successful = component_type.invoke("component_remove"_hs, {}, entity).cast<bool>();
69 }
70}
71
73{
74 if (entity)
75 {
76 component_type.invoke("component_add"_hs, {}, entity);
77 // std::stringstream stream_copy(stream.str());
78 stream.seekg(0);
79 component_type.invoke("component_load"_hs, {}, entity, entt::forward_as_meta(stream));
80 }
81}
82
84{
85 return false;
86}
87
89{
90 return entity.valid() && component_type;
91}
92
94{
95 //draw_in_inspector_impl(ctx, component_type, component_type, {});
96}
97
98// Transform Move Action Implementation
99entity_set_active_action_t::entity_set_active_action_t(entt::handle ent, bool old_active, bool new_active)
100 : entity(ent), old_active(old_active), new_active(new_active)
101{
102 name = "Set Active";
103}
104
106{
107 if (entity)
108 {
109 if (auto transform = entity.try_get<transform_component>())
110 {
111 transform->set_active(new_active);
113 }
114 }
115}
116
118{
119 if (entity)
120 {
121 if (auto transform = entity.try_get<transform_component>())
122 {
123 transform->set_active(old_active);
125 }
126 }
127}
128
130{
131 const auto& prev = static_cast<const entity_set_active_action_t&>(previous);
132 return entity == prev.entity;
133}
134
136{
137 const auto& prev = static_cast<const entity_set_active_action_t&>(previous);
138 old_active = prev.old_active;
139}
140
142{
143 return entity.valid() && entity.try_get<transform_component>();
144}
145
147{
148 draw_in_inspector_impl(ctx, old_active, new_active, {});
149}
150
151entity_set_name_action_t::entity_set_name_action_t(entt::handle ent, const std::string& old_name, const std::string& new_name)
152 : entity(ent), old_name(old_name), new_name(new_name)
153{
154 name = "Set Name";
155}
156
158{
159 if (entity)
160 {
161 if (auto tag = entity.try_get<tag_component>())
162 {
163 tag->name = new_name;
164 prefab_override_context::mark_property_as_changed(entity, entt::resolve<tag_component>(), "name");
165 }
166 }
167}
168
170{
171 if (entity)
172 {
173 if (auto tag = entity.try_get<tag_component>())
174 {
175 tag->name = old_name;
176 prefab_override_context::mark_property_as_changed(entity, entt::resolve<tag_component>(), "name");
177 }
178 }
179}
180
182{
183 draw_in_inspector_impl(ctx, old_name, new_name, {});
184}
185
187{
188 const auto& prev = static_cast<const entity_set_name_action_t&>(previous);
189 return entity == prev.entity;
190}
191
193{
194 const auto& prev = static_cast<const entity_set_name_action_t&>(previous);
195 old_name = prev.old_name;
196}
197
199{
200 return entity.valid() && entity.try_get<tag_component>();
201}
202
203entity_set_tag_action_t::entity_set_tag_action_t(entt::handle ent, const std::string& old_tag, const std::string& new_tag)
204 : entity(ent), old_tag(old_tag), new_tag(new_tag)
205{
206 name = "Set Tag";
207}
208
210{
211 if (entity)
212 {
213 if (auto tag = entity.try_get<tag_component>())
214 {
215 tag->tag = new_tag;
216 prefab_override_context::mark_property_as_changed(entity, entt::resolve<tag_component>(), "tag");
217 }
218 }
219}
220
222{
223 if (entity)
224 {
225 if (auto tag = entity.try_get<tag_component>())
226 {
227 tag->tag = old_tag;
228 prefab_override_context::mark_property_as_changed(entity, entt::resolve<tag_component>(), "tag");
229 }
230 }
231}
232
234{
235 const auto& prev = static_cast<const entity_set_tag_action_t&>(previous);
236 return entity == prev.entity;
237}
238
240{
241 const auto& prev = static_cast<const entity_set_tag_action_t&>(previous);
242 old_tag = prev.old_tag;
243}
244
246{
247 return entity.valid() && entity.try_get<tag_component>();
248}
249
251{
252 draw_in_inspector_impl(ctx, old_tag, new_tag, {});
253}
254
255entity_set_materials_action_t::entity_set_materials_action_t(entt::handle ent, const std::vector<asset_handle<material>>& old_materials, const asset_handle<material>& new_material)
256 : entity(ent), old_materials(old_materials)
257{
258 new_materials.resize(old_materials.size(), new_material);
259 name = "Set Materials";
260}
261
263{
264 if (entity && entity.all_of<model_component>())
265 {
266 auto& model_comp = entity.get<model_component>();
267 auto model_copy = model_comp.get_model();
268
269 // Apply new material to all submeshes
270 for(size_t i = 0; i < new_materials.size() && i < model_copy.get_materials().size(); ++i)
271 {
272 model_copy.set_material(new_materials[i], i);
273 }
274
275 // Update the model in the component
276 model_comp.set_model(model_copy);
277
278 // Mark as changed for prefab system
280 }
281}
282
284{
285 if (entity && entity.all_of<model_component>() && !old_materials.empty())
286 {
287 auto& model_comp = entity.get<model_component>();
288 auto model_copy = model_comp.get_model();
289
290 // Restore original materials
291 for(size_t i = 0; i < old_materials.size() && i < model_copy.get_materials().size(); ++i)
292 {
293 model_copy.set_material(old_materials[i], i);
294 }
295
296 // Update the model in the component
297 model_comp.set_model(model_copy);
298
299 // Mark as changed for prefab system
301 }
302}
303
305{
306 const auto& prev = static_cast<const entity_set_materials_action_t&>(previous);
307 return entity == prev.entity;
308}
309
311{
312 const auto& prev = static_cast<const entity_set_materials_action_t&>(previous);
314}
315
317{
318 return entity.valid() && entity.all_of<model_component>() && new_materials.size() == old_materials.size() && new_materials.size() > 0 && new_materials[0].is_valid();
319}
320
322{
323
324 entt::meta_any old_materials_any = old_materials;
325 entt::meta_any new_material_any = new_materials;
326 draw_in_inspector_impl(ctx, old_materials_any, new_material_any, {});
327
328 // For now, we'll keep this simple since materials are complex objects
329 // Could be enhanced to show material names/paths in the future
330}
331
333 : entity(ent), old_area(old_area), new_area(new_area)
334{
335 name = "Set Text Bounds";
336}
337
339{
340 if (entity && entity.all_of<text_component>())
341 {
342 // Update the text area
343 auto text_comp = entity.try_get<text_component>();
344 if (text_comp)
345 {
346 text_comp->set_area(new_area);
348 }
349 }
350}
351
353{
354 if (entity && entity.all_of<text_component>())
355 {
356 // Restore the text area
357 auto text_comp = entity.try_get<text_component>();
358 if (text_comp)
359 {
360 text_comp->set_area(old_area);
362 }
363 }
364}
365
367{
368 const auto& prev = static_cast<const entity_set_text_bounds_action_t&>(previous);
369 return entity == prev.entity;
370}
371
373{
374 const auto& prev = static_cast<const entity_set_text_bounds_action_t&>(previous);
375 old_area = prev.old_area;
376}
377
379{
380 return entity.valid() && entity.all_of<text_component>();
381}
382
384{
385 entt::meta_any old_area_any = old_area;
386 entt::meta_any new_area_any = new_area;
387 draw_in_inspector_impl(ctx, old_area_any, new_area_any, {});
388}
389
390// Script component action implementations
392 : entity(ent), script_type_name(type_name)
393{
394 name = "Add Script Component " + script_type_name;
395}
396
398{
399 if (entity && !script_type_name.empty())
400 {
401 auto& ctx = engine::context();
402 auto& script_sys = ctx.get_cached<script_system>();
403
404 // Find the script type by name
405 mono::mono_type script_type{};
406 for (const auto& type : script_sys.get_all_scriptable_components())
407 {
408 if (type.get_fullname() == script_type_name)
409 {
410 script_type = type;
411 break;
412 }
413 }
414
415 if (script_type.valid())
416 {
417 auto script_comp = entity.try_get<script_component>();
418 if (!script_comp)
419 {
420 // Add script component if it doesn't exist
421 script_comp = &entity.emplace<script_component>();
422 }
423
424 auto script_obj = script_comp->add_script_component(script_type);
425 do_was_successful = script_obj.scoped != nullptr;
426 }
427 }
428}
429
431{
432 if (entity && !script_type_name.empty() && do_was_successful)
433 {
434 auto& ctx = engine::context();
435 auto& script_sys = ctx.get_cached<script_system>();
436
437 // Find the script type by name
438 mono::mono_type script_type{};
439 for (const auto& type : script_sys.get_all_scriptable_components())
440 {
441 if (type.get_fullname() == script_type_name)
442 {
443 script_type = type;
444 break;
445 }
446 }
447
448 if (script_type.valid())
449 {
450 auto script_comp = entity.try_get<script_component>();
451 if (script_comp)
452 {
453 script_comp->remove_script_component(script_type);
454 script_comp->process_pending_deletions();
455 }
456 }
457 }
458}
459
461{
462 return false;
463}
464
466{
467 return entity.valid() && !script_type_name.empty();
468}
469
471{
472 // Could implement visual representation if needed
473}
474
476 : entity(ent), script_type_name(type_name)
477{
478 name = "Remove Script Component " + script_type_name;
479}
480
482{
483 if (entity && !script_type_name.empty())
484 {
485 auto& ctx = engine::context();
486 auto& script_sys = ctx.get_cached<script_system>();
487
488 // Find the script type by name
489 mono::mono_type script_type{};
490 for (const auto& type : script_sys.get_all_scriptable_components())
491 {
492 if (type.get_fullname() == script_type_name)
493 {
494 script_type = type;
495 break;
496 }
497 }
498
499 if (script_type.valid())
500 {
501 auto script_comp = entity.try_get<script_component>();
502 if (script_comp)
503 {
504 // Try to get the script object before removing it for restoration
505 auto script_obj = script_comp->get_script_component(script_type);
506 if (script_obj.scoped)
507 {
508 // Serialize the script object before removing it
510
512 }
513
514 do_was_successful = script_comp->remove_script_component(script_type);
516 {
517 script_comp->process_pending_deletions();
518 }
519 }
520 }
521 }
522}
523
525{
526 if (entity && !script_type_name.empty() && do_was_successful)
527 {
528 auto& ctx = engine::context();
529 auto& script_sys = ctx.get_cached<script_system>();
530
531 // Find the script type by name
532 mono::mono_type script_type{};
533 for (const auto& type : script_sys.get_all_scriptable_components())
534 {
535 if (type.get_fullname() == script_type_name)
536 {
537 script_type = type;
538 break;
539 }
540 }
541
542 if (script_type.valid())
543 {
544 auto& script_comp = entity.get_or_emplace<script_component>();
545
546 // If we have serialized data, try to restore it, otherwise create new one
547 if (!removed_script_object_data.str().empty())
548 {
549 try
550 {
551 // Deserialize the script object
552
554
557
558 // Add the restored script object
559 script_comp.add_script_component(restored_obj);
560
561 }
562 catch(...)
563 {
564 // Fallback: create new instance if deserialization fails
565 script_comp.add_script_component(script_type);
566 }
567 }
568 else
569 {
570 // Fallback: create new instance of the type
571 script_comp.add_script_component(script_type);
572 }
573 }
574 }
575}
576
578{
579 return false;
580}
581
583{
584 return entity.valid() && !script_type_name.empty();
585}
586
588{
589 // Could implement visual representation if needed
590}
591
592} // namespace unravel
manifold_type type
Class that contains core data for meshes.
auto get_model() const -> const model &
Gets the model.
Class that contains core data for audio listeners. There can only be one instance of it per scene.
auto add_script_component(const mono::mono_type &type) -> script_object
Component that handles transformations (position, rotation, scale, etc.) in the ACE framework.
std::string name
Definition hub.cpp:27
std::string tag
Definition hub.cpp:26
auto get_pretty_name(const meta_type &t) -> std::string
auto load_from_stream(std::istream &stream, entt::handle e, script_component::script_object &obj) -> bool
auto save_to_stream(std::ostream &stream, entt::const_handle e, const script_component::script_object &obj) -> bool
entt::entity entity
Represents a handle to an asset, providing access and management functions.
static auto context() -> rtti::context &
Definition engine.cpp:115
void draw_in_inspector(rtti::context &ctx) override
auto is_valid() const -> bool override
entity_add_component_action_t(entt::handle ent, const entt::meta_type &ctype)
auto is_mergeable(const editing_action_t &previous) const -> bool override
void draw_in_inspector(rtti::context &ctx) override
auto is_mergeable(const editing_action_t &previous) const -> bool override
entity_add_script_component_action_t(entt::handle ent, const std::string &type_name)
auto is_mergeable(const editing_action_t &previous) const -> bool override
auto is_valid() const -> bool override
entity_remove_component_action_t(entt::handle ent, const entt::meta_type &ctype)
void draw_in_inspector(rtti::context &ctx) override
auto is_mergeable(const editing_action_t &previous) const -> bool override
entity_remove_script_component_action_t(entt::handle ent, const std::string &type_name)
void draw_in_inspector(rtti::context &ctx) override
void draw_in_inspector(rtti::context &ctx) override
entity_set_active_action_t(entt::handle ent, bool old_active, bool new_active)
void merge_with(const editing_action_t &previous) override
auto is_valid() const -> bool override
auto is_mergeable(const editing_action_t &previous) const -> bool override
std::vector< asset_handle< material > > new_materials
auto is_valid() const -> bool override
std::vector< asset_handle< material > > old_materials
entity_set_materials_action_t(entt::handle ent, const std::vector< asset_handle< material > > &old_materials, const asset_handle< material > &new_material)
void merge_with(const editing_action_t &previous) override
void draw_in_inspector(rtti::context &ctx) override
auto is_mergeable(const editing_action_t &previous) const -> bool override
entity_set_name_action_t(entt::handle ent, const std::string &old_name, const std::string &new_name)
auto is_mergeable(const editing_action_t &previous) const -> bool override
void draw_in_inspector(rtti::context &ctx) override
auto is_valid() const -> bool override
void merge_with(const editing_action_t &previous) override
auto is_mergeable(const editing_action_t &previous) const -> bool override
void merge_with(const editing_action_t &previous) override
entity_set_tag_action_t(entt::handle ent, const std::string &old_tag, const std::string &new_tag)
auto is_valid() const -> bool override
void draw_in_inspector(rtti::context &ctx) override
auto is_mergeable(const editing_action_t &previous) const -> bool override
auto is_valid() const -> bool override
entity_set_text_bounds_action_t(entt::handle ent, const fsize_t &old_area, const fsize_t &new_area)
void merge_with(const editing_action_t &previous) override
void draw_in_inspector(rtti::context &ctx) override
static void mark_property_as_changed(entt::handle entity, const entt::meta_type &component_type, const std::string &property_path)
Marks a specific property as changed using component type.
static void mark_material_as_changed(entt::handle entity)
Marks material as changed in prefab override system.
static void mark_text_area_as_changed(entt::handle entity)
Marks text area as changed in prefab override system.
static void mark_active_as_changed(entt::handle entity)
Marks entity active state as changed in prefab override system.
Component that provides a tag (name or label) for an entity.