15#ifdef INK_ENABLE_UNREAL
16# include "../InkVar.h"
19namespace ink::runtime::internal
21class basic_eval_stack;
32class callback final :
public callback_base
34 using traits = function_traits<F>;
35 static_assert(traits::arity < 3);
37 template<ink::runtime::value::Type Ty>
40 if constexpr (traits::arity == 2) {
41 if (old_val.has_value()) {
44 typename traits::template argument<1>::type{old_val.value().get<Ty>()}
50 functor(new_val.
get<Ty>());
55 callback(
const callback&) =
delete;
56 callback(callback&&) =
delete;
57 callback& operator=(
const callback&) =
delete;
58 callback& operator=(callback&&) =
delete;
68 auto check_type = [&new_val, &old_val](
value::Type type) {
70 new_val.
type == type,
"Missmatch type for variable observer: expected %i, got %i",
71 static_cast<int>(type),
static_cast<int>(new_val.
type)
73 if constexpr (traits::arity == 2) {
79 if constexpr (traits::arity > 0) {
80 using arg_t =
typename remove_cvref<typename traits::template argument<0>::type>::type;
81 if constexpr (is_same<arg_t, value>::value) {
82 if constexpr (traits::arity == 2) {
83 functor(new_val, old_val);
87 }
else if constexpr (is_same<arg_t, bool>::value) {
89 call_functor<value::Type::Bool>(new_val, old_val);
90 }
else if constexpr (is_same<arg_t, uint32_t>::value) {
92 call_functor<value::Type::Uint32>(new_val, old_val);
93 }
else if constexpr (is_same<arg_t, int32_t>::value) {
95 call_functor<value::Type::Int32>(new_val, old_val);
96 }
else if constexpr (is_same<arg_t, const char*>::value) {
98 call_functor<value::Type::String>(new_val, old_val);
99 }
else if constexpr (is_same<arg_t, float>::value) {
101 call_functor<value::Type::Float>(new_val, old_val);
102 }
else if constexpr (is_same<arg_t, list_interface*>::value) {
104 call_functor<value::Type::List>(new_val, old_val);
107 always_false<arg_t>::value,
"Unsupported value for variable observer callback!"
123 function_base(
bool lookaheadSafe)
124 : _lookaheadSafe(lookaheadSafe)
128 virtual ~function_base() {}
132#ifdef INK_ENABLE_UNREAL
134 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists)
138 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists)
142 bool lookaheadSafe()
const {
return _lookaheadSafe; }
148 static T pop(basic_eval_stack* stack, list_table& lists);
152 static void push(basic_eval_stack* stack,
const T& value);
154 static void push_void(basic_eval_stack* stack);
157 static void push_string(basic_eval_stack* stack,
const char* dynamic_string);
160 static char* allocate(string_table& strings,
ink::size_t len);
165class function :
public function_base
168 function(F functor,
bool lookaheadSafe)
169 : function_base(lookaheadSafe)
176 basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists
179 call(stack, length, strings, lists, GenSeq<traits::arity>());
187 using traits = function_traits<F>;
191 using arg_type =
typename function_traits<F>::template argument<index>::type;
195 arg_type<index> pop_arg(basic_eval_stack* stack, list_table& lists)
198 return pop<arg_type<index>>(stack, lists);
201 static constexpr bool is_array_call()
203 if constexpr (traits::arity == 2) {
210 template<
size_t... Is>
212 call(basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists, seq<Is...>)
215 is_array_call() ||
sizeof...(Is) == length,
216 "Attempting to call functor with too few/many arguments"
218 static_assert(
sizeof...(Is) == traits::arity);
219 if_t<is_array_call(), value[config::maxArrayCallArity],
char> vals;
220 if constexpr (is_array_call()) {
222 length <= config::maxArrayCallArity,
223 "AIttampt to call array call with more arguments then supportet, please change in "
226 for (
size_t i = 0; i < length; ++i) {
227 vals[i] = pop<ink::runtime::value>(stack, lists);
231 if constexpr (is_same<void, typename traits::return_type>::value) {
233 if constexpr (is_array_call()) {
234 functor(length, vals);
236 functor(pop_arg<Is>(stack, lists)...);
242 typename traits::return_type res;
243 if constexpr (is_array_call()) {
244 res = functor(length, vals);
246 res = functor(pop_arg<Is>(stack, lists)...);
248 if constexpr (is_string<typename traits::return_type>::value) {
253 size_t len = string_handler<typename traits::return_type>::length(res);
256 char* buffer = allocate(strings, len + 1);
257 string_handler<typename traits::return_type>::src_copy(res, buffer);
260 push_string(stack, buffer);
261 }
else if constexpr (is_same<value, remove_cvref<typename traits::return_type>>::value) {
263 auto src = res.template get<ink::runtime::value::Type::String>();
264 size_t len = string_handler<
decltype(src)>::length(src);
265 char* buffer = allocate(strings, len + 1);
266 string_handler<
decltype(src)>::src_copy(src, buffer);
267 push_string(stack, buffer);
279#ifdef INK_ENABLE_UNREAL
281class function_array_delegate :
public function_base
284 function_array_delegate(
const D& del,
bool lookaheadSafe)
285 : function_base(lookaheadSafe)
286 , invocableDelegate(del)
292 basic_eval_stack* stack,
size_t length, string_table& strings, list_table& lists
295 constexpr bool RET_VOID
296 = is_same<
typename function_traits<
decltype(&D::Execute)>::return_type,
void>::value;
298 TArray<FInkVar> variables;
299 for (
size_t i = 0; i < length; i++) {
300 variables.Add(pop<FInkVar>(stack, lists));
302 if constexpr (RET_VOID) {
303 invocableDelegate.Execute(variables);
307 auto ret = invocableDelegate.Execute(variables);
311 size_t len = string_handler<const char*>::length(src);
312 char* buffer = allocate(strings, len + 1);
std::optional< T > optional
custom optional implementation for usage if STL is disabled
Definition system.h:229
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:231
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:122