Unravel Engine C++ Reference
Loading...
Searching...
No Matches
scene_bindings.cpp
Go to the documentation of this file.
1// Scene + Entity bindings share one TU: Entity component helpers are used by Scene find APIs.
3#include "script_bindings.h"
4
5#include "../script_interop.h"
6
8#include <engine/ecs/prefab.h>
10#include <seq/seq.h>
11
12namespace unravel
13{
14namespace
15{
16
17void internal_m2n_load_scene(const std::string& key)
18{
19 auto delay = seq::delay(0ms);
20 delay.on_end.connect(
21 [key]()
22 {
23 auto& ctx = engine::context();
24 auto& ec = ctx.get_cached<ecs>();
25 auto& am = ctx.get_cached<asset_manager>();
26
27 ec.get_scene().load_from(am.get_asset<scene_prefab>(key));
28 });
29
30 seq::queue(delay, "script");
31}
32
33void internal_m2n_load_scene_uid(const hpp::uuid& uid)
34{
35 auto delay = seq::delay(0ms);
36 delay.on_end.connect(
37 [uid]()
38 {
39 auto& ctx = engine::context();
40 auto& ec = ctx.get_cached<ecs>();
41 auto& am = ctx.get_cached<asset_manager>();
42
43 ec.get_scene().load_from(am.get_asset<scene_prefab>(uid));
44 });
45
46 seq::queue(delay, "script");
47}
48
49void internal_m2n_reload_scene()
50{
51 auto delay = seq::delay(0ms);
52 delay.on_end.connect(
53 []()
54 {
55 auto& ctx = engine::context();
56 auto& ec = ctx.get_cached<ecs>();
57
58 ec.get_scene().reload();
59 });
60
61 seq::queue(delay, "script");
62}
63
64void internal_m2n_create_scene(const dotnet::object& this_ptr)
65{
66 dotnet::ignore(this_ptr);
67}
68
69void internal_m2n_destroy_scene(const dotnet::object& this_ptr)
70{
71 dotnet::ignore(this_ptr);
72}
73
74auto internal_m2n_create_entity(const std::string& tag) -> entt::entity
75{
76 auto& ctx = engine::context();
77 auto& ec = ctx.get_cached<ecs>();
78
79 auto e = ec.get_scene().create_entity(tag);
80
81 return e.entity();
82}
83
84auto internal_m2n_create_entity_from_prefab_uid(const hpp::uuid& uid) -> entt::entity
85{
86 auto& ctx = engine::context();
87 auto& ec = ctx.get_cached<ecs>();
88 auto& am = ctx.get_cached<asset_manager>();
89
90 auto pfb = am.get_asset<prefab>(uid);
91 auto e = ec.get_scene().instantiate(pfb);
92
93 return e.entity();
94}
95
96auto internal_m2n_create_entity_from_prefab_key(const std::string& key) -> entt::entity
97{
98 auto& ctx = engine::context();
99 auto& ec = ctx.get_cached<ecs>();
100 auto& am = ctx.get_cached<asset_manager>();
101
102 auto pfb = am.get_asset<prefab>(key);
103 auto e = ec.get_scene().instantiate(pfb);
104
105 return e.entity();
106}
107
108auto internal_m2n_create_entity_from_prefab_uid_with_parent(const hpp::uuid& uid, entt::entity parent) -> entt::entity
109{
110 auto& ctx = engine::context();
111 auto& ec = ctx.get_cached<ecs>();
112 auto& am = ctx.get_cached<asset_manager>();
113
114 auto pfb = am.get_asset<prefab>(uid);
115 auto parent_handle = get_entity_from_id(parent);
116 auto e = ec.get_scene().instantiate(pfb, parent_handle);
117
118 return e.entity();
119}
120
121auto internal_m2n_create_entity_from_prefab_key_with_parent(const std::string& key, entt::entity parent) -> entt::entity
122{
123 auto& ctx = engine::context();
124 auto& ec = ctx.get_cached<ecs>();
125 auto& am = ctx.get_cached<asset_manager>();
126
127 auto pfb = am.get_asset<prefab>(key);
128 auto parent_handle = get_entity_from_id(parent);
129 auto e = ec.get_scene().instantiate(pfb, parent_handle);
130
131 return e.entity();
132}
133
134auto internal_m2n_create_entity_from_prefab_uid_with_position(const hpp::uuid& uid, const math::vec3& position) -> entt::entity
135{
136 auto& ctx = engine::context();
137 auto& ec = ctx.get_cached<ecs>();
138 auto& am = ctx.get_cached<asset_manager>();
139
140 auto pfb = am.get_asset<prefab>(uid);
141 auto e = ec.get_scene().instantiate(pfb);
142
143 if(auto comp = e.try_get<transform_component>())
144 {
145 comp->set_position_global(position);
146 }
147
148 return e.entity();
149}
150
151auto internal_m2n_create_entity_from_prefab_key_with_position(const std::string& key, const math::vec3& position) -> entt::entity
152{
153 auto& ctx = engine::context();
154 auto& ec = ctx.get_cached<ecs>();
155 auto& am = ctx.get_cached<asset_manager>();
156
157 auto pfb = am.get_asset<prefab>(key);
158 auto e = ec.get_scene().instantiate(pfb);
159
160 if(auto comp = e.try_get<transform_component>())
161 {
162 comp->set_position_global(position);
163 }
164
165 return e.entity();
166}
167
168auto internal_m2n_create_entity_from_prefab_uid_with_position_parent(const hpp::uuid& uid,
169 const math::vec3& position,
170 entt::entity parent) -> entt::entity
171{
172 auto& ctx = engine::context();
173 auto& ec = ctx.get_cached<ecs>();
174 auto& am = ctx.get_cached<asset_manager>();
175
176 auto pfb = am.get_asset<prefab>(uid);
177 auto parent_handle = get_entity_from_id(parent);
178 auto e = ec.get_scene().instantiate(pfb, parent_handle);
179
180 if(auto comp = e.try_get<transform_component>())
181 {
182 comp->set_position_global(position);
183 }
184
185 return e.entity();
186}
187
188auto internal_m2n_create_entity_from_prefab_key_with_position_parent(const std::string& key,
189 const math::vec3& position,
190 entt::entity parent) -> entt::entity
191{
192 auto& ctx = engine::context();
193 auto& ec = ctx.get_cached<ecs>();
194 auto& am = ctx.get_cached<asset_manager>();
195
196 auto pfb = am.get_asset<prefab>(key);
197 auto parent_handle = get_entity_from_id(parent);
198 auto e = ec.get_scene().instantiate(pfb, parent_handle);
199
200 if(auto comp = e.try_get<transform_component>())
201 {
202 comp->set_position_global(position);
203 }
204
205 return e.entity();
206}
207
208auto internal_m2n_create_entity_from_prefab_uid_with_position_rotation_parent(const hpp::uuid& uid,
209 const math::vec3& position,
210 const math::quat& rotation,
211 entt::entity parent) -> entt::entity
212{
213 auto& ctx = engine::context();
214 auto& ec = ctx.get_cached<ecs>();
215 auto& am = ctx.get_cached<asset_manager>();
216
217 auto pfb = am.get_asset<prefab>(uid);
218 auto parent_handle = get_entity_from_id(parent);
219 auto e = ec.get_scene().instantiate(pfb, parent_handle);
220
221 if(auto comp = e.try_get<transform_component>())
222 {
223 comp->set_position_global(position);
224 comp->set_rotation_global(rotation);
225 }
226
227 return e.entity();
228}
229
230auto internal_m2n_create_entity_from_prefab_key_with_position_rotation_parent(const std::string& key,
231 const math::vec3& position,
232 const math::quat& rotation,
233 entt::entity parent) -> entt::entity
234{
235 auto& ctx = engine::context();
236 auto& ec = ctx.get_cached<ecs>();
237 auto& am = ctx.get_cached<asset_manager>();
238
239 auto pfb = am.get_asset<prefab>(key);
240 auto parent_handle = get_entity_from_id(parent);
241 auto e = ec.get_scene().instantiate(pfb, parent_handle);
242
243 if(auto comp = e.try_get<transform_component>())
244 {
245 comp->set_position_global(position);
246 comp->set_rotation_global(rotation);
247 }
248
249 return e.entity();
250}
251
252auto internal_m2n_clone_entity(entt::entity id) -> entt::entity
253{
254 auto e = get_entity_from_id(id);
255 if(e)
256 {
257 auto& ctx = engine::context();
258 auto& ec = ctx.get_cached<ecs>();
259
260 auto cloned = ec.get_scene().clone_entity(e);
261 return cloned.entity();
262 }
263
264 entt::handle invalid;
265 return invalid.entity();
266}
267
268auto internal_m2n_destroy_entity_immediate(entt::entity id) -> bool
269{
270 auto e = get_entity_from_id(id);
271 if(e)
272 {
273 e.destroy();
274 return true;
275 }
276 return false;
277}
278
279auto internal_m2n_destroy_entity(entt::entity id, float seconds) -> bool
280{
281 seconds = std::max(0.0f, seconds);
282
283 delta_t secs(seconds);
284 auto dur = std::chrono::duration_cast<seq::duration_t>(secs);
285
286 auto delay = seq::delay(dur);
287 delay.on_end.connect(
288 [id]()
289 {
290 internal_m2n_destroy_entity_immediate(id);
291 });
292
293 seq::queue(delay, "script");
294
295 return true;
296}
297
298auto internal_m2n_is_entity_valid(entt::entity id) -> bool
299{
300 auto e = get_entity_from_id(id);
301 bool valid = e.valid();
302 return valid;
303}
304
305auto internal_m2n_find_entity_by_name(const std::string& name) -> entt::entity
306{
307 auto& ctx = engine::context();
308 auto& ec = ctx.get_cached<ecs>();
309 auto& scn = ec.get_scene();
310 auto& registry = *scn.registry;
311
312 auto view = registry.view<tag_component>();
313
314 for(const auto& e : view)
315 {
316 if(registry.get<tag_component>(e).name == name)
317 {
318 return e;
319 }
320 }
321
322 const entt::handle invalid;
323 return invalid.entity();
324}
325
326auto internal_m2n_find_entities_by_name(const std::string& name) -> hpp::small_vector<entt::entity>
327{
328 auto& ctx = engine::context();
329 auto& ec = ctx.get_cached<ecs>();
330 auto& scn = ec.get_scene();
331 auto& registry = *scn.registry;
332
333 auto view = registry.view<tag_component>();
334
335 hpp::small_vector<entt::entity> result;
336 for(const auto& e : view)
337 {
338 if(registry.get<tag_component>(e).name == name)
339 {
340 result.emplace_back(e);
341 }
342 }
343
344 return result;
345}
346
347auto internal_m2n_find_entity_by_tag(const std::string& tag) -> entt::entity
348{
349 auto& ctx = engine::context();
350 auto& ec = ctx.get_cached<ecs>();
351 auto& scn = ec.get_scene();
352 auto& registry = *scn.registry;
353
354 auto view = registry.view<tag_component>();
355
356 for(const auto& e : view)
357 {
358 if(registry.get<tag_component>(e).tag == tag)
359 {
360 return e;
361 }
362 }
363
364 const entt::handle invalid;
365 return invalid.entity();
366}
367
368auto internal_m2n_find_entities_by_tag(const std::string& tag) -> hpp::small_vector<entt::entity>
369{
370 auto& ctx = engine::context();
371 auto& ec = ctx.get_cached<ecs>();
372 auto& scn = ec.get_scene();
373 auto& registry = *scn.registry;
374
375 auto view = registry.view<tag_component>();
376
377 hpp::small_vector<entt::entity> result;
378 for(const auto& e : view)
379 {
380 if(registry.get<tag_component>(e).tag == tag)
381 {
382 result.emplace_back(e);
383 }
384 }
385
386 return result;
387}
388
389struct native_comp_lut
390{
391 auto is_valid() const -> bool
392 {
393 return add_native != nullptr;
394 }
395 std::function<bool(size_t type_hash, entt::handle e)> add_native;
396 std::function<bool(size_t type_hash, entt::handle e)> has_native;
397 std::function<bool(size_t type_hash, entt::handle e)> remove_native;
398
399 static auto get_registry() -> std::unordered_map<size_t, native_comp_lut>&
400 {
401 static std::unordered_map<size_t, native_comp_lut> lut;
402 return lut;
403 }
404
405 static auto get_action_table(size_t type_hash) -> const native_comp_lut&
406 {
407 const auto& registry = get_registry();
408 auto it = registry.find(type_hash);
409 if(it != registry.end())
410 {
411 return it->second;
412 }
413
414 static const native_comp_lut empty;
415 return empty;
416 }
417
418 template<typename T>
419 static auto register_native_component(const std::string& name)
420 {
421 size_t hash = dotnet::type::get_hash(name);
422 native_comp_lut lut;
423 lut.add_native = [hash](size_t type_hash, entt::handle e)
424 {
425 if(type_hash == hash)
426 {
427 auto& native = e.get_or_emplace<T>();
428 return true;
429 }
430
431 return false;
432 };
433
434 lut.has_native = [hash](size_t type_hash, entt::handle e)
435 {
436 if(type_hash == hash)
437 {
438 return e.all_of<T>();
439 }
440
441 return false;
442 };
443
444 lut.remove_native = [hash](size_t type_hash, entt::handle e)
445 {
446 if(type_hash == hash)
447 {
448 return e.remove<T>() > 0;
449 }
450
451 return false;
452 };
453
454 get_registry()[hash] = lut;
455 }
456};
457
458int register_componetns = []()
459{
460 native_comp_lut::register_native_component<transform_component>("Unravel.Core.TransformComponent");
461 native_comp_lut::register_native_component<id_component>("Unravel.Core.IdComponent");
462 native_comp_lut::register_native_component<model_component>("Unravel.Core.ModelComponent");
463 native_comp_lut::register_native_component<camera_component>("Unravel.Core.CameraComponent");
464 native_comp_lut::register_native_component<light_component>("Unravel.Core.LightComponent");
465 native_comp_lut::register_native_component<reflection_probe_component>("Unravel.Core.ReflectionProbeComponent");
466 native_comp_lut::register_native_component<physics_component>("Unravel.Core.PhysicsComponent");
467 native_comp_lut::register_native_component<animation_component>("Unravel.Core.AnimationComponent");
468 native_comp_lut::register_native_component<audio_listener_component>("Unravel.Core.AudioListenerComponent");
469 native_comp_lut::register_native_component<audio_source_component>("Unravel.Core.AudioSourceComponent");
470 native_comp_lut::register_native_component<bone_component>("Unravel.Core.BoneComponent");
471 native_comp_lut::register_native_component<submesh_component>("Unravel.Core.SubmeshComponent");
472 native_comp_lut::register_native_component<text_component>("Unravel.Core.TextComponent");
473 native_comp_lut::register_native_component<particle_emitter_component>("Unravel.Core.ParticleEmitterComponent");
474 native_comp_lut::register_native_component<ui_document_component>("Unravel.Core.UIDocumentComponent");
475 native_comp_lut::register_native_component<character_controller_component>("Unravel.Core.CharacterControllerComponent");
476
477 return 0;
478}();
479
480auto internal_add_native_component(const dotnet::type& type, entt::handle e, script_component& script_comp)
481 -> dotnet::object
482{
483 // TODO OPTIMIZE
484
485 const auto& type_hash = type.get_hash();
486 bool add = false;
487
488 const auto& lut = native_comp_lut::get_action_table(type_hash);
489 if(lut.is_valid())
490 {
491 add = lut.add_native(type_hash, e);
492 }
493
494 if(add)
495 {
496 auto comp = script_comp.get_native_component(type);
497
498 if(!comp.pinned)
499 {
500 comp = script_comp.add_native_component(type);
501 }
502 return comp.pinned->get_object();
503 }
504
505 return {};
506}
507
508auto internal_get_native_component_impl(const dotnet::type& type,
509 entt::handle e,
510 script_component& script_comp,
511 bool exists) -> dotnet::object
512{
513 auto comp = script_comp.get_native_component(type);
514 if(exists)
515 {
516 if(!comp.pinned)
517 {
518 comp = script_comp.add_native_component(type);
519 }
520 return comp.pinned->get_object();
521 }
522
523 if(comp.pinned)
524 {
525 script_comp.remove_native_component(comp.pinned->get_object());
526 }
527
528 return {};
529}
530
531auto internal_get_native_component(const dotnet::type& type, entt::handle e, script_component& script_comp)
532 -> dotnet::object
533{
534 const auto& type_hash = type.get_hash();
535
536 // TODO OPTIMIZE
537 bool native = false;
538 bool has = false;
539
540 const auto& lut = native_comp_lut::get_action_table(type_hash);
541 if(lut.is_valid())
542 {
543 has = lut.has_native(type_hash, e);
544 native = true;
545 }
546
547 if(native)
548 {
549 return internal_get_native_component_impl(type, e, script_comp, has);
550 }
551
552 return {};
553}
554
555auto internal_remove_native_component(const dotnet::object& obj, entt::handle e, script_component& script_comp)
556 -> bool
557{
558 const auto& type = obj.get_type();
559 const auto& type_hash = type.get_hash();
560
561 // TODO OPTIMIZE
562
563 bool removed = false;
564 const auto& lut = native_comp_lut::get_action_table(type_hash);
565 if(lut.is_valid())
566 {
567 removed = lut.remove_native(type_hash, e);
568 }
569
570 if(removed)
571 {
572 return script_comp.remove_native_component(obj);
573 }
574
575 return false;
576}
577
578auto internal_remove_native_component(const dotnet::type& type, entt::handle e, script_component& script_comp)
579 -> bool
580{
581 const auto& type_hash = type.get_hash();
582
583 // TODO OPTIMIZE
584
585 bool removed = false;
586 const auto& lut = native_comp_lut::get_action_table(type_hash);
587 if(lut.is_valid())
588 {
589 removed = lut.remove_native(type_hash, e);
590 }
591
592 if(removed)
593 {
594 return script_comp.remove_native_component(type);
595 }
596
597 return false;
598}
599
600auto internal_m2n_add_component(entt::entity id, const dotnet::type& type) -> dotnet::object
601{
602 auto e = get_entity_from_id(id);
603 if(!e)
604 {
606 return {};
607 }
608 auto& script_comp = e.get_or_emplace<script_component>();
609
610 if(auto native_comp = internal_add_native_component(type, e, script_comp))
611 {
612 return native_comp;
613 }
614
615 auto component = script_comp.add_script_component(type);
616 return component.pinned->get_object();
617}
618
619auto internal_m2n_get_component(entt::entity id, const dotnet::type& type) -> dotnet::object
620{
621 auto e = get_entity_from_id(id);
622 if(!e)
623 {
625 return {};
626 }
627
628 auto& script_comp = e.get_or_emplace<script_component>();
629
630 if(auto native_comp = internal_get_native_component(type, e, script_comp))
631 {
632 return native_comp;
633 }
634
635 auto component = script_comp.get_script_component(type);
636
637 if(component.pinned)
638 {
639 // Validate the object is still valid before returning
640 // Even with pinned handles, objects can be finalized or corrupted
641 if(!component.is_marked_for_destroy())
642 {
643 return component.pinned->get_object();
644 }
645 }
646
647 return {};
648}
649
650
651auto internal_m2n_get_components_impl(entt::entity id, const dotnet::type& type) -> std::vector<dotnet::object>
652{
653 auto e = get_entity_from_id(id);
654 if(!e)
655 {
657 return {};
658 }
659
660 auto& script_comp = e.get_or_emplace<script_component>();
661
662 if(auto native_comp = internal_get_native_component(type, e, script_comp))
663 {
664 return {native_comp};
665 }
666
667 return script_comp.get_script_components(type);
668}
669
670auto internal_m2n_get_components(entt::entity id, const dotnet::type& type) -> dotnet::array<dotnet::object>
671{
672 auto components = internal_m2n_get_components_impl(id, type);
673 return dotnet::array<dotnet::object>(components, type);
674}
675
676auto internal_m2n_get_component_in_children(entt::entity id, const dotnet::type& type) -> dotnet::object
677{
678 auto comp = internal_m2n_get_component(id, type);
679 if(comp.valid())
680 {
681 return comp;
682 }
684 {
685 const auto& children = comp->get_children();
686 for(const auto& child : children)
687 {
688 if(auto result = internal_m2n_get_component(child, type))
689 {
690 return result;
691 }
692 }
693 }
694
695 return {};
696}
697
698auto internal_m2n_get_components_in_children(entt::entity id, const dotnet::type& type)
699 -> dotnet::array<dotnet::object>
700{
701 auto components = internal_m2n_get_components_impl(id, type);
703 {
704 const auto& children = comp->get_children();
705 for(const auto& child : children)
706 {
707 auto child_components = internal_m2n_get_components_impl(child, type);
708 std::move(child_components.begin(), child_components.end(), std::back_inserter(components));
709 }
710 }
711 return dotnet::array<dotnet::object>(components, type);
712}
713
714auto internal_m2n_get_transform_component(entt::entity id, const dotnet::type& type) -> dotnet::object
715{
716 auto e = get_entity_from_id(id);
717 if(!e)
718 {
720 return {};
721 }
722
723 auto& script_comp = e.get_or_emplace<script_component>();
724 return internal_get_native_component_impl(type, e, script_comp, true);
725}
726
727auto internal_m2n_get_name(entt::entity id) -> const std::string&
728{
729 if(auto comp = safe_get_component<tag_component>(id))
730 {
731 return comp->name;
732 }
733
734 static const std::string empty;
735 return empty;
736}
737
738void internal_m2n_set_name(entt::entity id, const std::string& name)
739{
740 if(auto comp = safe_get_component<tag_component>(id))
741 {
742 comp->name = name;
743 }
744}
745
746auto internal_m2n_get_tag(entt::entity id) -> const std::string&
747{
748 if(auto comp = safe_get_component<tag_component>(id))
749 {
750 return comp->tag;
751 }
752
753 static const std::string empty;
754 return empty;
755}
756
757void internal_m2n_set_tag(entt::entity id, const std::string& tag)
758{
759 if(auto comp = safe_get_component<tag_component>(id))
760 {
761 comp->tag = tag;
762 }
763}
764
765auto internal_m2n_get_layers(entt::entity id) -> int
766{
767 if(auto comp = safe_get_component<layer_component>(id))
768 {
769 return comp->layers.mask;
770 }
771
773}
774
775void internal_m2n_set_layers(entt::entity id, int mask)
776{
777 if(auto comp = safe_get_component<layer_component>(id))
778 {
779 comp->layers.mask = mask;
780 }
781}
782
783auto internal_m2n_get_active_global(entt::entity id) -> bool
784{
786 {
787 return comp->is_active_global();
788 }
789
790 return false;
791}
792
793auto internal_m2n_get_active_local(entt::entity id) -> bool
794{
796 {
797 return comp->is_active();
798 }
799
800 return false;
801}
802
803void internal_m2n_set_active_local(entt::entity id, bool active)
804{
806 {
807 comp->set_active(active);
808 }
809}
810
811auto internal_m2n_has_component(entt::entity id, const dotnet::type& type) -> bool
812{
813 auto comp = internal_m2n_get_component(id, type);
814
815 return comp.valid();
816}
817
818auto internal_m2n_find_entities_with_component(const dotnet::type& component_type) -> hpp::small_vector<entt::entity>
819{
820 auto& ctx = engine::context();
821 auto& ec = ctx.get_cached<ecs>();
822 auto& scn = ec.get_scene();
823 auto& registry = *scn.registry;
824
825 hpp::small_vector<entt::entity> result;
826
827 // Iterate through all entities using the storage directly
828 for(auto [entity] : registry.storage<entt::entity>().each())
829 {
830 if(registry.valid(entity))
831 {
832 // Check if entity has the component using the same logic as internal_m2n_has_component
833 auto comp = internal_m2n_get_component(entity, component_type);
834 if(comp.valid())
835 {
836 result.emplace_back(entity);
837 }
838 }
839 }
840
841 return result;
842}
843
844auto internal_m2n_find_entities_with_components(const std::vector<dotnet::type>& component_types) -> hpp::small_vector<entt::entity>
845{
846 auto& ctx = engine::context();
847 auto& ec = ctx.get_cached<ecs>();
848 auto& scn = ec.get_scene();
849 auto& registry = *scn.registry;
850
851 hpp::small_vector<entt::entity> result;
852
853 if(component_types.empty())
854 {
855 return result;
856 }
857
858 // Iterate through all entities using the storage directly
859 for(auto [entity] : registry.storage<entt::entity>().each())
860 {
861 if(registry.valid(entity))
862 {
863 bool has_all_components = true;
864
865 // Check if entity has all required components
866 for(const auto& component_type : component_types)
867 {
868 auto comp = internal_m2n_get_component(entity, component_type);
869 if(!comp.valid())
870 {
871 has_all_components = false;
872 break;
873 }
874 }
875
876 if(has_all_components)
877 {
878 result.emplace_back(entity);
879 }
880 }
881 }
882
883 return result;
884}
885
886auto internal_m2n_remove_component_instance(entt::entity id, const dotnet::object& comp) -> bool
887{
888 auto e = get_entity_from_id(id);
889 if(!e)
890 {
892 return false;
893 }
894 auto& script_comp = e.get_or_emplace<script_component>();
895
896 if(internal_remove_native_component(comp, e, script_comp))
897 {
898 return true;
899 }
900
901 return script_comp.remove_script_component(comp);
902}
903
904auto internal_m2n_remove_component_instance_delay(entt::entity id, const dotnet::object& comp, float seconds_delay)
905 -> bool
906{
907 delta_t secs(seconds_delay);
908 auto dur = std::chrono::duration_cast<seq::duration_t>(secs);
909
910 auto delay = seq::delay(dur);
911 delay.on_end.connect(
912 [id, comp]()
913 {
914 internal_m2n_remove_component_instance(id, comp);
915 });
916
917 seq::start(delay, "script");
918
919 return true;
920}
921
922auto internal_m2n_remove_component(entt::entity id, const dotnet::type& type) -> bool
923{
924 auto e = get_entity_from_id(id);
925 if(!e)
926 {
928 return false;
929 }
930 auto& script_comp = e.get_or_emplace<script_component>();
931
932 if(internal_remove_native_component(type, e, script_comp))
933 {
934 return true;
935 }
936
937 return script_comp.remove_script_component(type);
938}
939
940auto internal_m2n_remove_component_delay(entt::entity id, const dotnet::type& type, float seconds_delay) -> bool
941{
942 delta_t secs(seconds_delay);
943 auto dur = std::chrono::duration_cast<seq::duration_t>(secs);
944
945 auto delay = seq::delay(dur);
946 delay.on_end.connect(
947 [id, type]()
948 {
949 internal_m2n_remove_component(id, type);
950 });
951
952 seq::start(delay, "script");
953
954 return true;
955}
956
957//-------------------------------------------------------------------------
958/*
959
960 _ ____ _____
961 | | / __ \ / ____|
962 | | | | | | | __
963 | | | | | | | |_ |
964 | |___| |__| | |__| |
965 |______\____/ \_____|
966
967
968*/
969//-------------------------------------------------------------------------
970
971} // namespace
972
974{
975 APPLOG_TRACE("{}", __func__);
976
977 auto reg = dotnet::internal_call_registry("Unravel.Core.Scene");
978 reg.add_internal_call("internal_m2n_load_scene", dotnet_internal_call(internal_m2n_load_scene));
979 reg.add_internal_call("internal_m2n_load_scene_uid", dotnet_internal_call(internal_m2n_load_scene_uid));
980 reg.add_internal_call("internal_m2n_reload_scene", dotnet_internal_call(internal_m2n_reload_scene));
981 reg.add_internal_call("internal_m2n_create_scene", dotnet_internal_call(internal_m2n_create_scene));
982 reg.add_internal_call("internal_m2n_destroy_scene", dotnet_internal_call(internal_m2n_destroy_scene));
983 reg.add_internal_call("internal_m2n_create_entity", dotnet_internal_call(internal_m2n_create_entity));
984 reg.add_internal_call("internal_m2n_create_entity_from_prefab_uid",
985 dotnet_internal_call(internal_m2n_create_entity_from_prefab_uid));
986 reg.add_internal_call("internal_m2n_create_entity_from_prefab_key",
987 dotnet_internal_call(internal_m2n_create_entity_from_prefab_key));
988 reg.add_internal_call("internal_m2n_create_entity_from_prefab_uid_with_parent",
989 dotnet_internal_call(internal_m2n_create_entity_from_prefab_uid_with_parent));
990 reg.add_internal_call("internal_m2n_create_entity_from_prefab_key_with_parent",
991 dotnet_internal_call(internal_m2n_create_entity_from_prefab_key_with_parent));
992 reg.add_internal_call("internal_m2n_create_entity_from_prefab_uid_with_position",
993 dotnet_internal_call(internal_m2n_create_entity_from_prefab_uid_with_position));
994 reg.add_internal_call("internal_m2n_create_entity_from_prefab_key_with_position",
995 dotnet_internal_call(internal_m2n_create_entity_from_prefab_key_with_position));
996 reg.add_internal_call("internal_m2n_create_entity_from_prefab_uid_with_position_parent",
997 dotnet_internal_call(internal_m2n_create_entity_from_prefab_uid_with_position_parent));
998 reg.add_internal_call("internal_m2n_create_entity_from_prefab_key_with_position_parent",
999 dotnet_internal_call(internal_m2n_create_entity_from_prefab_key_with_position_parent));
1000 reg.add_internal_call("internal_m2n_create_entity_from_prefab_uid_with_position_rotation_parent",
1001 dotnet_internal_call(internal_m2n_create_entity_from_prefab_uid_with_position_rotation_parent));
1002 reg.add_internal_call("internal_m2n_create_entity_from_prefab_key_with_position_rotation_parent",
1003 dotnet_internal_call(internal_m2n_create_entity_from_prefab_key_with_position_rotation_parent));
1004 reg.add_internal_call("internal_m2n_clone_entity", dotnet_internal_call(internal_m2n_clone_entity));
1005 reg.add_internal_call("internal_m2n_destroy_entity", dotnet_internal_call(internal_m2n_destroy_entity));
1006 reg.add_internal_call("internal_m2n_destroy_entity_immediate",
1007 dotnet_internal_call(internal_m2n_destroy_entity_immediate));
1008
1009 reg.add_internal_call("internal_m2n_is_entity_valid", dotnet_internal_call(internal_m2n_is_entity_valid));
1010 reg.add_internal_call("internal_m2n_find_entity_by_name", dotnet_internal_call(internal_m2n_find_entity_by_name));
1011 reg.add_internal_call("internal_m2n_find_entities_by_name", dotnet_internal_call(internal_m2n_find_entities_by_name));
1012 reg.add_internal_call("internal_m2n_find_entity_by_tag", dotnet_internal_call(internal_m2n_find_entity_by_tag));
1013 reg.add_internal_call("internal_m2n_find_entities_by_tag", dotnet_internal_call(internal_m2n_find_entities_by_tag));
1014 reg.add_internal_call("internal_m2n_find_entities_with_component", dotnet_internal_call(internal_m2n_find_entities_with_component));
1015 reg.add_internal_call("internal_m2n_find_entities_with_components", dotnet_internal_call(internal_m2n_find_entities_with_components));
1016}
1017
1019{
1020 APPLOG_TRACE("{}", __func__);
1021
1022 auto reg = dotnet::internal_call_registry("Unravel.Core.Entity");
1023 reg.add_internal_call("internal_m2n_add_component", dotnet_internal_call(internal_m2n_add_component));
1024 reg.add_internal_call("internal_m2n_get_component", dotnet_internal_call(internal_m2n_get_component));
1025 reg.add_internal_call("internal_m2n_get_component_in_children",
1026 dotnet_internal_call(internal_m2n_get_component_in_children));
1027 reg.add_internal_call("internal_m2n_has_component", dotnet_internal_call(internal_m2n_has_component));
1028 reg.add_internal_call("internal_m2n_get_components", dotnet_internal_call(internal_m2n_get_components));
1029 reg.add_internal_call("internal_m2n_get_components_in_children",
1030 dotnet_internal_call(internal_m2n_get_components_in_children));
1031
1032 reg.add_internal_call("internal_m2n_remove_component_instance",
1033 dotnet_internal_call(internal_m2n_remove_component_instance));
1034 reg.add_internal_call("internal_m2n_remove_component_instance_delay",
1035 dotnet_internal_call(internal_m2n_remove_component_instance_delay));
1036
1037 reg.add_internal_call("internal_m2n_remove_component", dotnet_internal_call(internal_m2n_remove_component));
1038 reg.add_internal_call("internal_m2n_remove_component_delay",
1039 dotnet_internal_call(internal_m2n_remove_component_delay));
1040
1041 reg.add_internal_call("internal_m2n_get_transform_component",
1042 dotnet_internal_call(internal_m2n_get_transform_component));
1043 reg.add_internal_call("internal_m2n_get_name", dotnet_internal_call(internal_m2n_get_name));
1044 reg.add_internal_call("internal_m2n_set_name", dotnet_internal_call(internal_m2n_set_name));
1045 reg.add_internal_call("internal_m2n_get_tag", dotnet_internal_call(internal_m2n_get_tag));
1046 reg.add_internal_call("internal_m2n_set_tag", dotnet_internal_call(internal_m2n_set_tag));
1047 reg.add_internal_call("internal_m2n_get_layers", dotnet_internal_call(internal_m2n_get_layers));
1048 reg.add_internal_call("internal_m2n_set_layers", dotnet_internal_call(internal_m2n_set_layers));
1049
1050 reg.add_internal_call("internal_m2n_get_active_global", dotnet_internal_call(internal_m2n_get_active_global));
1051 reg.add_internal_call("internal_m2n_get_active_local", dotnet_internal_call(internal_m2n_get_active_local));
1052 reg.add_internal_call("internal_m2n_set_active_local", dotnet_internal_call(internal_m2n_set_active_local));
1053}
1054
1055} // namespace unravel
std::chrono::duration< float > delta_t
math::vec3 position
Definition defaults.cpp:52
uint16_t view
std::vector< render_pass_node > children
std::string name
Definition hub.cpp:33
std::string tag
Definition hub.cpp:32
#define APPLOG_TRACE(...)
Definition logging.h:17
texture_job_type type
auto start(seq_action action, const seq_scope_policy &scope_policy, hpp::source_location location) -> seq_id_t
Starts a new action.
Definition seq.cpp:8
auto queue(seq_action action, const seq_scope_policy &scope_policy, hpp::source_location location) -> seq_id_t
Queues a new action.
Definition seq.cpp:14
auto delay(const duration_t &duration, const sentinel_t &sentinel) -> seq_action
Creates a delay action.
Definition seq_core.cpp:182
@ nothing_layer
Definition layer_mask.h:13
@ mask
Hard alpha cutoff; casts cutout shadows.
void register_scene_script_bindings()
void raise_invalid_entity_exception()
auto get_entity_from_id(entt::entity id) -> entt::handle
void register_entity_script_bindings()
auto safe_get_component(entt::entity id) -> T *
bool is_valid(octet_iterator start, octet_iterator end)
Definition core.h:467
std::vector< math::quat > rotation
entt::handle entity
std::function< bool(size_t type_hash, entt::handle e)> has_native
std::function< bool(size_t type_hash, entt::handle e)> remove_native
std::function< bool(size_t type_hash, entt::handle e)> add_native
static auto context() -> rtti::context &
Definition engine.cpp:111