2#ifndef LIBSBX_SCRIPTING_MANAGED_OBJECT_HPP_
3#define LIBSBX_SCRIPTING_MANAGED_OBJECT_HPP_
13#include <libsbx/scripting/managed/fwd.hpp>
14#include <libsbx/scripting/managed/core.hpp>
15#include <libsbx/scripting/managed/string.hpp>
17namespace sbx::scripting::managed {
19enum class managed_type : std::uint8_t {
36template<
typename Type>
37constexpr auto get_managed_type() -> managed_type {
38 if constexpr (std::same_as<Type, std::uint8_t> || std::same_as<Type, std::byte>) {
39 return managed_type::uint8;
40 }
else if constexpr (std::same_as<Type, std::uint16_t>) {
41 return managed_type::uint16;
42 }
else if constexpr (std::same_as<Type, std::uint32_t> || (std::same_as<Type, unsigned long> &&
sizeof(Type) == 4u)) {
43 return managed_type::uint32;
44 }
else if constexpr (std::same_as<Type, std::uint64_t> || (std::same_as<Type, unsigned long> &&
sizeof(Type) == 8u)) {
45 return managed_type::uint64;
46 }
else if constexpr (std::same_as<Type, char8_t> || std::same_as<Type, std::int8_t>) {
47 return managed_type::int8;
48 }
else if constexpr (std::same_as<Type, std::int16_t>) {
49 return managed_type::int16;
50 }
else if constexpr (std::same_as<Type, std::int32_t> || (std::same_as<Type, long> &&
sizeof(Type) == 4u)) {
51 return managed_type::int32;
52 }
else if constexpr (std::same_as<Type, std::int64_t> || (std::same_as<Type, long> &&
sizeof(Type) == 8u)) {
53 return managed_type::int64;
54 }
else if constexpr (std::same_as<Type, std::float_t>) {
55 return managed_type::float32;
56 }
else if constexpr (std::same_as<Type, std::double_t>) {
57 return managed_type::float64;
58 }
else if constexpr (std::same_as<Type, bool>) {
59 return managed_type::boolean;
60 }
else if constexpr (std::is_same_v<Type, std::string> || std::is_same_v<Type, managed::string>) {
61 return managed_type::string;
63 return managed_type::unknown;
69template<std::
size_t Size,
typename Tuple, std::
size_t Index>
70inline auto add_to_array(std::array<const void*, Size>& arguments, std::array<managed_type, Size>& types,
const Tuple& tuple) ->
void {
71 using T = std::tuple_element_t<Index, Tuple>;
73 types[Index] = get_managed_type<std::remove_reference_t<T>>();
75 if constexpr (std::is_pointer_v<std::remove_reference_t<T>>) {
76 arguments[Index] =
static_cast<const void*
>(std::get<Index>(tuple));
78 arguments[Index] =
static_cast<const void*
>(&std::get<Index>(tuple));
84template<std::size_t Size,
typename Tuple, std::size_t... Indices>
85inline auto add_to_array(std::array<const void*, Size>& arguments, std::array<managed_type, Size>& types,
const Tuple& tuple, std::index_sequence<Indices...>) ->
void {
86 (detail::add_to_array<Size, Tuple, Indices>(arguments, types, tuple), ...);
96 template<
typename Result,
typename... Args>
97 auto invoke(std::string_view name, Args&&... args)
const -> Result {
98 constexpr auto parameter_count =
sizeof...(args);
100 auto result = Result{};
102 if constexpr (parameter_count > 0u) {
103 auto storage = std::tuple<std::decay_t<Args>...>{std::forward<Args>(args)...};
105 auto parameter_values = std::array<const void*, parameter_count>{};
106 auto parameter_types = std::array<managed_type, parameter_count>{};
108 add_to_array(parameter_values, parameter_types, storage, std::make_index_sequence<parameter_count>{});
110 _invoke_method_return_internal(name, parameter_values.data(), parameter_types.data(), parameter_count, &result);
112 _invoke_method_return_internal(name,
nullptr,
nullptr, 0, &result);
118 template<
typename... Args>
119 auto invoke(std::string_view name, Args&&... args)
const ->
void {
120 constexpr auto parameter_count =
sizeof...(args);
122 if constexpr (parameter_count > 0u) {
123 auto storage = std::tuple<std::decay_t<Args>...>{std::forward<Args>(args)...};
125 auto parameter_values = std::array<const void*, parameter_count>{};
126 auto parameter_types = std::array<managed_type, parameter_count>{};
128 add_to_array(parameter_values, parameter_types, storage, std::make_index_sequence<parameter_count>{});
130 _invoke_method_internal(name, parameter_values.data(), parameter_types.data(), parameter_count);
132 _invoke_method_internal(name,
nullptr,
nullptr, 0);
136 template<
typename Type>
137 auto set_field_value(std::string_view name,
const Type& value)
const ->
void {
138 set_field_value_raw(name, &value);
141 template<
typename Type>
142 auto get_field_value(std::string_view name)
const -> Type {
143 auto result = Type{};
145 get_field_value_raw(name, &result);
150 template<
typename Type>
151 auto set_property_value(std::string_view name, Type value)
const ->
void {
152 set_property_value_raw(name, &value);
155 template<
typename Type>
156 auto get_property_value(std::string_view name)
const -> Type {
157 auto result = Type{};
159 get_property_value_raw(name, &result);
164 auto set_field_value_raw(std::string_view name,
const void* value)
const -> void;
166 auto get_field_value_raw(std::string_view name,
void* value)
const -> void;
168 auto set_property_value_raw(std::string_view name,
const void* value)
const -> void;
170 auto get_property_value_raw(std::string_view name,
void* value)
const -> void;
172 auto get_type() ->
const type&;
174 auto destroy() -> void;
176 auto is_valid()
const -> bool;
180 auto _invoke_method_internal(std::string_view name,
const void** parameters,
const managed_type* parameter_types, std::size_t length)
const -> void;
182 auto _invoke_method_return_internal(std::string_view name,
const void** parameters,
const managed_type* parameter_types, std::size_t length,
void* result_storage)
const -> void;
184 void* _handle{
nullptr};
185 const type* _type{
nullptr};
192auto object::set_field_value<std::string>(std::string_view name,
const std::string& value)
const -> void;
195auto object::set_field_value<bool>(std::string_view name,
const bool& value)
const -> void;
198auto object::get_field_value<std::string>(std::string_view name)
const -> std::string;
201auto object::get_field_value<bool>(std::string_view name)
const -> bool;
Definition: assembly.hpp:27
Definition: object.hpp:89