Callbacks
Supported bindings: ossia, Max, Pd, Python
Just like messages allow to define functions that will be called from an outside request, it is also possible to define callbacks: functions that our processor will call, and which will be sent to the outside world.
Just like for messages, this does not really make sense for instance for audio processors ; however it is pretty much necessary to make useful Max or Pd objects.
Callbacks are defined as part of the outputs
struct.
Defining a callback with std::function
This is a first possibility, which is pretty simple:
struct {
static consteval auto name() { return "bong"; }
std::function<void(float)> call;
};
The bindings will make sure that a function is present in call
, so that our code can call it:
struct MyProcessor {
static consteval auto name() { return "Distortion"; }
struct {
struct {
static consteval auto name() { return "overload"; }
std::function<void(float)> call;
} overload;
} outputs;
float operator()(float input)
{
if(input > 1.0)
outputs.overload.call(input);
return std::tanh(input);
}
};
However, we also want to be able to live without std:: types ; in particular, std::function is a quite complex beast which does type-erasure, potential dynamic memory allocations, and may not be available on all platforms.
Thus, it is also possible to define callbacks with a simple pair of function-pointer & context:
struct {
static consteval auto name() { return "overload"; }
struct {
void (*function)(void*, float);
void* context;
} call;
} overload;
The bindings will fill the function and function pointer, so that one can call them:
float operator()(float input)
{
if(input > 1.0)
{
auto& call = outputs.overload.call;
call.function(call.context, input);
}
return std::tanh(input);
}
Of course, this is fairly verbose: thankfully, helpers are provided to make this as simple as std::function
but without the overhead (until std::function_view
gets implemented):
struct {
static consteval auto name() { return "overload"; }
halp::basic_callback<void(float)> call;
} overload;