#pragma once #include "../entt_meta_helper.h" #include #include #include #include #include #include #include namespace simpleengine::scripting::lua { class ECSBindings { private: template static auto is_valid(const entt::registry *registry, entt::entity entity) { assert(registry); return registry->valid(entity); } template static auto emplace_component(entt::registry *registry, entt::entity entity, const sol::table& instance, sol::this_state s) { assert(registry); auto& comp = registry->emplace_or_replace(entity, instance.valid() ? instance.as() : Component{}); return sol::make_reference(s, std::ref(comp)); } template static auto get_component(entt::registry *registry, entt::entity entity, sol::this_state s) { assert(registry); auto& comp = registry->get_or_emplace(entity); return sol::make_reference(s, std::ref(comp)); } template static bool has_component(entt::registry *registry, entt::entity entity) { assert(registry); return registry->any_of(entity); } template static auto remove_component(entt::registry *registry, entt::entity entity) { assert(registry); return registry->remove(entity); } template static void clear_component(entt::registry *registry) { assert(registry); registry->clear(); } template static void register_meta_component() { using namespace entt::literals; entt::meta() .type() .template func<&is_valid>("valid"_hs) .template func<&emplace_component>("emplace"_hs) .template func<&get_component>("get"_hs) .template func<&has_component>("has"_hs) .template func<&clear_component>("clear"_hs) .template func<&remove_component>("remove"_hs); } static auto collect_types(const sol::variadic_args& va) { std::set types; std::transform(va.cbegin(), va.cend(), std::inserter(types, types.begin()), [](const auto& obj) { return EnttMetaHelper::deduce_type(obj); }); return types; } public: /// This binds ALL of the ECS to Lua under the `ecs` table static sol::table bind_full_ecs(sol::this_state s); /// This binds an entt registry to lua. It binds the registry type as `ecs.registry` static sol::table bind_registry(sol::this_state s); /// Bind all components to Lua. This will put all components under `ecs.component.*` static sol::table bind_components(sol::this_state s); }; }