15#ifdef INK_ENABLE_UNREAL
16# include "../InkVar.h"
19namespace ink::runtime::internal
21class basic_eval_stack;
29 virtual ~callback_base() =
default;
33class callback final :
public callback_base
35 using traits = function_traits<F>;
36 static_assert(traits::arity < 3);
38 template<ink::runtime::value::Type Ty>
41 if constexpr (traits::arity == 2) {
42 if (old_val.has_value()) {
45 typename traits::template argument<1>::type{old_val.value().get<Ty>()}
51 functor(new_val.
get<Ty>());
56 callback(
const callback&) =
delete;
57 callback(callback&&) =
delete;
58 callback& operator=(
const callback&) =
delete;
59 callback& operator=(callback&&) =
delete;
69 auto check_type = [&new_val, &old_val](
value::Type type) {
71 new_val.
type == type,
"Missmatch type for variable observer: expected %i, got %i",
72 static_cast<int>(type),
static_cast<int>(new_val.
type)
74 if constexpr (traits::arity == 2) {
80 if constexpr (traits::arity > 0) {
81 using arg_t =
typename remove_cvref<typename traits::template argument<0>::type>::type;
82 if constexpr (is_same<arg_t, value>::value) {
83 if constexpr (traits::arity == 2) {
84 functor(new_val, old_val);
88 }
else if constexpr (is_same<arg_t, bool>::value) {
90 call_functor<value::Type::Bool>(new_val, old_val);
91 }
else if constexpr (is_same<arg_t, uint32_t>::value) {
93 call_functor<value::Type::Uint32>(new_val, old_val);
94 }
else if constexpr (is_same<arg_t, int32_t>::value) {
96 call_functor<value::Type::Int32>(new_val, old_val);
97 }
else if constexpr (is_same<arg_t, const char*>::value) {
99 call_functor<value::Type::String>(new_val, old_val);
100 }
else if constexpr (is_same<arg_t, float>::value) {
102 call_functor<value::Type::Float>(new_val, old_val);
103 }
else if constexpr (is_same<arg_t, list_interface*>::value) {
105 call_functor<value::Type::List>(new_val, old_val);
108 always_false<arg_t>::value,
"Unsupported value for variable observer callback!"
124 function_base(
bool lookaheadSafe)
125 : _lookaheadSafe(lookaheadSafe)
129 virtual ~function_base() {}
133#ifdef INK_ENABLE_UNREAL
135 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists)
139 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists)
143 bool lookaheadSafe()
const {
return _lookaheadSafe; }
149 static T pop(basic_eval_stack* stack, list_table& lists);
153 static void push(basic_eval_stack* stack,
const T& value);
155 static void push_void(basic_eval_stack* stack);
158 static void push_string(basic_eval_stack* stack,
const char* dynamic_string);
161 static char* allocate(string_table& strings,
ink::size_t len);
166class function :
public function_base
169 function(F functor,
bool lookaheadSafe)
170 : function_base(lookaheadSafe)
177 basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists
180 call(stack, length, strings, lists, GenSeq<traits::arity>());
188 using traits = function_traits<F>;
192 using arg_type =
typename function_traits<F>::template argument<index>::type;
196 arg_type<index> pop_arg(basic_eval_stack* stack, list_table& lists)
199 return pop<arg_type<index>>(stack, lists);
202 static constexpr bool is_array_call()
204 if constexpr (traits::arity == 2) {
211 template<
size_t... Is>
213 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists, seq<Is...>)
216 is_array_call() ||
sizeof...(Is) == length,
217 "Attempting to call functor with too few/many arguments"
219 static_assert(
sizeof...(Is) == traits::arity);
220 if_t<is_array_call(), value[config::maxArrayCallArity],
char> vals;
221 if constexpr (is_array_call()) {
223 length <= config::maxArrayCallArity,
224 "AIttampt to call array call with more arguments then supportet, please change in "
227 for (
size_t i = 0; i < length; ++i) {
228 vals[i] = pop<ink::runtime::value>(stack, lists);
232 if constexpr (is_same<void, typename traits::return_type>::value) {
234 if constexpr (is_array_call()) {
235 functor(length, vals);
237 functor(pop_arg<Is>(stack, lists)...);
243 typename traits::return_type res;
244 if constexpr (is_array_call()) {
245 res = functor(length, vals);
247 res = functor(pop_arg<Is>(stack, lists)...);
249 if constexpr (is_string<typename traits::return_type>::value) {
254 size_t len = string_handler<typename traits::return_type>::length(res);
257 char* buffer = allocate(strings, len + 1);
258 string_handler<typename traits::return_type>::src_copy(res, buffer);
261 push_string(stack, buffer);
262 }
else if constexpr (is_same<value, remove_cvref<typename traits::return_type>>::value) {
264 auto src = res.template get<ink::runtime::value::Type::String>();
265 size_t len = string_handler<
decltype(src)>::length(src);
266 char* buffer = allocate(strings, len + 1);
267 string_handler<
decltype(src)>::src_copy(src, buffer);
268 push_string(stack, buffer);
280#ifdef INK_ENABLE_UNREAL
282class function_array_delegate :
public function_base
285 function_array_delegate(
const D& del,
bool lookaheadSafe)
286 : function_base(lookaheadSafe)
287 , invocableDelegate(del)
293 basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists
296 constexpr bool RET_VOID
297 = is_same<
typename function_traits<
decltype(&D::Execute)>::return_type,
void>::value;
299 TArray<FInkVar> variables;
300 for (
size_t i = 0; i < length; i++) {
301 variables.Add(pop<FInkVar>(stack, lists));
303 if constexpr (RET_VOID) {
304 invocableDelegate.Execute(variables);
308 auto ret = invocableDelegate.Execute(variables);
312 size_t len = string_handler<const char*>::length(src);
313 char* buffer = allocate(strings, len + 1);
std::optional< T > optional
custom optional implementation for usage if STL is disabled
Definition system.h:243
unsigned int size_t
Used for the size of arrays.
Definition system.h:75
constexpr std::nullopt_t nullopt
an empty optional
Definition system.h:245
A Ink variable.
Definition types.h:36
Type
Type labels for ink::runtime::value
Definition types.h:49
@ Float
containing a float
@ String
contaning a const char*
@ Uint32
containing uint32_t
@ List
containing a list_interface
@ Int32
containing int32_t
enum ink::runtime::value::Type type
Label of type currently contained in value.
const auto & get() const
Get value to corresponding type.
Definition types.h:123