Allowing latent actions in functions?

Macros don’t permit local variables. In order to avoid a forest of spagetti in the EventGraph one would like to factor it into subroutines, however since some operations (latent actions) can’t be used in Functions, macros are the only alternative in such cases. Unfortunately, the lack of local variables means that can’t be done cleanly in many cases.

[Edit]

It seems the bytecode interpreter uses stack allocation (FMemory_Alloca). for the stack frame to hold local variables. Perhaps this is why latent actions are only permitted at the top level? Heap allocating such frames would make it easy to support proper continuations (and hence latent actions in functions).

So it seems there are two issues here w/r to allowing latent actions in functions:

  1. Functions called from c++ are expected to return synchronously.

  2. The call frames leading up to the call site of the latent action would have to be preserved (each with its local variables and program counter).

I can think of solutions to both which are relatively easy to implement, but the question is whether you’d be amenable to considering them. Or if I’m overlooking something please let me know.

Thanks.

I think reason is simplicity, same as blueprints don’t inherent 8 integer types from C++

Macro is not a function, it pastes blueprint inside macro to blueprint where macro is used (same as macro in C++). It would mean macro would need to create those variables inside blueprint which it is placed, which could create compatibility issues between macro and blueprint, or there some other blockage that prevents pasting macro variables in to blueprints

Laten action (I assume you mean delay… which didn’t know you can use them in functions) is most likely because asynchronous behavior of it and VM limitations related to it.

Ok, so I went ahead and implemented proper (still one-shot) continuations in this commit. This enables using latent actions in functions. The implementation wasn’t done in necessarily the “best” way but rather in the way that required the least changes to the existing code. The basic idea is very straightforward: keep the stack frames as part of the latent info, when the latent callback occurs jump to the linkage offset and call ProcessInternal on the saved stack.

Pull request