2#include <dotnetpp/dotnetpp.h>
21 result.
point = {manifold.b.x, manifold.b.y, manifold.b.z};
22 result.
normal = {manifold.normal_on_b.x, manifold.normal_on_b.y, manifold.normal_on_b.z};
24 result.
impulse = manifold.impulse;
28 result.
point = {manifold.a.x, manifold.a.y, manifold.a.z};
29 result.
normal = {manifold.normal_on_a.x, manifold.normal_on_a.y, manifold.normal_on_a.z};
31 result.
impulse = manifold.impulse;
36auto to_managed_contact_points(
const std::vector<manifold_point>& manifolds,
bool use_b =
false) -> std::vector<dotnetpp_backend::managed_interface::manifold_point>
38 std::vector<dotnetpp_backend::managed_interface::manifold_point> result;
39 result.reserve(manifolds.size());
40 for(
const auto& manifold : manifolds)
42 result.push_back(to_managed_contact_point(manifold, use_b));
47auto engine_script_cache() ->
const script_system::engine_script_cache&
50 return ctx.get_cached<script_system>().get_cache();
79 safe_foreach(script_components_,
84 auto obj =
script.pinned->get_object();
94 safe_foreach(script_components_,
97 auto obj =
script.pinned->get_object();
104 safe_foreach(script_components_,
107 auto obj =
script.pinned->get_object();
114 auto managed_manifolds = to_managed_contact_points(manifolds,
true);
115 safe_foreach(script_components_,
118 auto obj =
script.pinned->get_object();
125 auto managed_manifolds = to_managed_contact_points(manifolds,
true);
126 safe_foreach(script_components_,
129 auto obj =
script.pinned->get_object();
136 auto managed_manifolds = to_managed_contact_points(manifolds, use_b);
137 safe_foreach(script_components_,
140 auto obj =
script.pinned->get_object();
147 auto managed_manifolds = to_managed_contact_points(manifolds, use_b);
148 safe_foreach(script_components_,
151 auto obj =
script.pinned->get_object();
158 if(script_obj.is_enabled() || script_obj.is_marked_for_destroy())
163 script_obj.state->active =
true;
167 if(!script_obj.is_create_called())
173 auto obj = script_obj.pinned->get_object();
182 auto method = dotnet::make_method_invoker<void()>(engine_script_cache().on_enable_method,
false);
185 catch(
const dotnet::exception& e)
193 if(script_obj.is_disabled() || script_obj.is_marked_for_destroy())
198 script_obj.state->active = 0;
202 if(!script_obj.is_create_called())
207 auto obj = script_obj.pinned->get_object();
215 auto method = dotnet::make_method_invoker<void()>(engine_script_cache().on_disable_method,
false);
218 catch(
const dotnet::exception& e)
226 if(script_obj.is_create_called())
231 script_obj.state->create_called =
true;
232 auto obj = script_obj.pinned->get_object();
241 auto method = dotnet::make_method_invoker<void()>(engine_script_cache().on_create_method,
false);
244 catch(
const dotnet::exception& e)
251 if(script_obj.is_start_called())
255 script_obj.state->start_called =
true;
256 auto obj = script_obj.pinned->get_object();
264 auto method = dotnet::make_method_invoker<void()>(engine_script_cache().on_start_method,
false);
267 catch(
const dotnet::exception& e)
275 auto obj = script_obj.pinned->get_object();
283 auto method = dotnet::make_method_invoker<void()>(engine_script_cache().on_destroy_method,
false);
286 catch(
const dotnet::exception& e)
292void script_component::set_entity(
const dotnet::object& obj, entt::handle e)
301 dotnet::make_method_invoker<void(entt::entity)>(engine_script_cache().set_entity_method,
false);
302 method(obj,
e.entity());
304 catch(
const dotnet::exception& e)
310void script_component::on_sensor_enter(
const dotnet::object& obj, entt::handle other,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>& manifolds)
314 auto method = dotnet::make_method_invoker<void(
315 entt::entity,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>&)>(
316 engine_script_cache().on_sensor_enter_method,
false);
317 method(obj, other.entity(), manifolds);
319 catch(
const dotnet::exception& e)
325void script_component::on_sensor_exit(
const dotnet::object& obj, entt::handle other,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>& manifolds)
329 auto method = dotnet::make_method_invoker<void(
330 entt::entity,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>&)>(
331 engine_script_cache().on_sensor_exit_method,
false);
332 method(obj, other.entity(), manifolds);
334 catch(
const dotnet::exception& e)
342 const std::vector<dotnetpp_backend::managed_interface::manifold_point>& manifolds)
346 auto method = dotnet::make_method_invoker<void(
347 entt::entity,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>&)>(
348 engine_script_cache().on_collision_enter_method,
false);
349 method(obj, other.entity(), manifolds);
351 catch(
const dotnet::exception& e)
359 const std::vector<dotnetpp_backend::managed_interface::manifold_point>& manifolds)
363 auto method = dotnet::make_method_invoker<void(
364 entt::entity,
const std::vector<dotnetpp_backend::managed_interface::manifold_point>&)>(
365 engine_script_cache().on_collision_exit_method,
false);
366 method(obj, other.entity(), manifolds);
368 catch(
const dotnet::exception& e)
377 auto& play = ctx.get_cached<
play_mode>();
380 if(play.is_simulation_running())
382 for(
auto&
script : script_components_)
384 if(
script.is_marked_for_destroy())
392 size_t erased = std::erase_if(script_components_,
395 return rhs.is_marked_for_destroy();
398 erased += std::erase_if(native_components_,
401 return rhs.is_marked_for_destroy();
407 while(!script_components_to_create_.empty())
409 auto comps = std::move(script_components_to_create_);
410 script_components_to_create_.clear();
414 if(!
script.is_marked_for_destroy())
424 while(!script_components_to_start_.empty())
426 auto comps = std::move(script_components_to_start_);
427 script_components_to_start_.clear();
431 if(!
script.is_marked_for_destroy())
448 auto& play = ctx.get_cached<
play_mode>();
454 if(
get_owner().all_of<active_component>())
456 enable(script_obj,
false);
468 auto obj =
type.new_instance();
469 return add_script_component(obj);
475 return add_script_component(script_obj);
480 script_components_.emplace_back(script_obj);
481 script_components_to_create_.emplace_back(script_obj);
482 script_components_to_start_.emplace_back(script_obj);
484 auto obj = script_obj.pinned->get_object();
486 set_entity(obj, get_owner());
488 if(process_callbacks)
490 process_pending_actions(script_obj);
498 for(
auto& comp : comps)
509 for(
auto& comp : comps)
513 auto obj = comp.pinned->get_object();
514 const auto&
type = obj.get_type();
527 auto obj =
type.new_instance();
528 auto& script_obj = native_components_.emplace_back(obj);
530 set_entity(obj, get_owner());
537 std::vector<dotnet::object> result;
538 for(
const auto& component : script_components_)
540 auto obj = component.pinned->get_object();
541 const auto& comp_type = obj.get_type();
543 if(comp_type.equals(
type) || comp_type.is_derived_from(
type))
546 if(!component.is_marked_for_destroy())
549 result.emplace_back(obj);
559 auto it = std::find_if(std::begin(script_components_),
560 std::end(script_components_),
561 [&](
const auto& component)
563 auto obj = component.pinned->get_object();
564 const auto& comp_type = obj.get_type();
565 return comp_type.equals(
type) || comp_type.is_derived_from(
type);
568 if(it != std::end(script_components_))
578 auto it = std::find_if(std::begin(native_components_),
579 std::end(native_components_),
580 [&](
const auto& component)
582 auto obj = component.pinned->get_object();
583 const auto& comp_type = obj.get_type();
584 return comp_type.equals(
type) || comp_type.is_derived_from(
type);
587 if(it != std::end(native_components_))
597 auto checker = [&](
const auto& rhs)
599 return rhs.pinned->get_object().equals(obj);
601 std::erase_if(script_components_to_create_, checker);
603 std::erase_if(script_components_to_start_, checker);
605 auto it = std::find_if(std::begin(script_components_), std::end(script_components_), checker);
607 if(it != std::end(script_components_))
609 auto& script_obj = *it;
615 if(script_obj.state->marked_for_destroy)
617 APPLOG_WARNING(
"Script component already queued for destruction");
622 script_obj.state->marked_for_destroy =
true;
633 auto checker = [&](
const auto& rhs)
635 return rhs.pinned->get_object().get_type().equals(
type);
637 std::erase_if(script_components_to_create_, checker);
639 std::erase_if(script_components_to_start_, checker);
641 auto it = std::find_if(std::begin(script_components_), std::end(script_components_), checker);
643 if(it != std::end(script_components_))
645 auto& script_obj = *it;
650 if(script_obj.state->marked_for_destroy)
652 APPLOG_WARNING(
"Script component already queued for destruction");
655 auto obj = script_obj.pinned->get_object();
658 script_obj.state->marked_for_destroy =
true;
671 auto it = std::find_if(std::begin(native_components_),
672 std::end(native_components_),
675 return rhs.pinned->get_object().equals(obj);
678 if(it != std::end(native_components_))
680 auto& script_obj = *it;
684 script_obj.state->marked_for_destroy =
true;
693 auto it = std::find_if(std::begin(native_components_),
694 std::end(native_components_),
697 return rhs.pinned->get_object().get_type().equals(
type);
700 if(it != std::end(native_components_))
702 auto& script_obj = *it;
704 auto obj = script_obj.pinned->get_object();
707 script_obj.state->marked_for_destroy =
true;
716 return script_components_;
721 return !script_components_.empty();
726 return std::any_of(std::begin(script_components_), std::end(script_components_), [&](
const auto& component)
728 return component.pinned->get_object().get_type().get_name() == type_name;
739 auto object = obj.pinned->get_object();
740 const auto&
type =
object.get_type();
743 auto attrs =
type.get_attributes();
744 for(
auto& attr : attrs)
746 if(attr.get_type().get_fullname() ==
"Unravel.Core.ScriptSourceFileAttribute")
748 auto invoker = dotnet::make_property_invoker<std::string>(attr.get_type(),
"Path");
749 return invoker.get_value(attr);
752 auto prop =
type.get_property(
"SourceFilePath");
753 auto invoker = dotnet::make_property_invoker<std::string>(prop);
754 return invoker.get_value(
object);
756 catch(
const dotnet::exception& e)
auto get_owner() const noexcept -> entt::const_handle
Gets the owner of the component.
void set_owner(entt::handle owner)
Sets the owner of the component.
Class that contains core data for audio listeners. There can only be one instance of it per scene.
auto get_script_source_location(const script_object &obj) const -> std::string
void on_collision_enter(entt::handle other, const std::vector< manifold_point > &manifolds, bool use_b)
auto get_script_component(const dotnet::type &type) -> script_object
void add_missing_script_components(const script_components_t &comps)
void on_collision_exit(entt::handle other, const std::vector< manifold_point > &manifolds, bool use_b)
void on_sensor_enter(entt::handle other, const std::vector< manifold_point > &manifolds)
auto remove_native_component(const dotnet::object &obj) -> bool
auto remove_script_component(const dotnet::object &obj) -> bool
void process_pending_actions_create(script_object script_obj)
void add_script_components(const script_components_t &comps)
static void on_destroy_component(entt::registry &r, entt::entity e)
Called when the component is destroyed.
auto get_script_components() const -> const script_components_t &
void process_pending_actions()
void process_pending_starts()
void on_sensor_exit(entt::handle other, const std::vector< manifold_point > &manifolds)
std::vector< script_object > script_components_t
auto add_script_component(const dotnet::type &type) -> script_object
auto has_script_components() const -> bool
static void on_create_component(entt::registry &r, entt::entity e)
Called when the component is created.
void process_pending_deletions()
auto add_native_component(const dotnet::type &type) -> script_object
auto get_native_component(const dotnet::type &type) -> script_object
void process_pending_creates()
#define APPLOG_WARNING(...)
static auto context() -> rtti::context &
Owns play-mode state and orchestrates the splash -> running lifecycle.
auto is_create_called() const -> bool
static void log_exception(const dotnet::exception &e, const hpp::source_location &loc=hpp::source_location::current())