Best way to use async callbacks with C++ modules?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Maël Nison
:warning: Old Version Published before Godot 3 was released.

I wrote a C++ library to manage a core part of my game, so that I can then use it with some non game-related purposes. This library has a kind of event loop, and works like this:

Game().setActionCallback([](Game& game, Action& action) {
    // ... some logging code
}).setPlayerCallback([](Game& game, Environment& environment, ...) {
    // ... should return the action the player wants to do
}).setBattleCallback([](Game& game, Environment& environment, ...) {
    // ... should return the opponent the player wants to attack
}).startAndRun(getTestEnvironment());

As you can see, we instanciate a Game object, inserts a few callbacks, and let the core run its course. When we reach a point in the game where some user input is required, the core will call the user-defined callback, and use its answer to get going. If the task is synchronous (for example if an AI is computing the next move) then the callback will also be synchronous, and if it is asynchronous (for example if we need to wait for a user to click on a button), then we can use std::async inside our callback to put the core on hold until we get the answer we want.

Now my question is, what’s the best way to integrate this with Godot? Is there some schenanigans I should be aware when using threads with Godot? I saw there was something called Signals, but couldn’t find in the documentation how to use them with my C++ code. Can I use them to dispatch “events” from my C++ library to my Godot game, and vice versa? Is there an API for this?

:bust_in_silhouette: Reply From: hungrymonkey

If you want to store simple callbacks into a c++ module you kinda have to use funcRef object in godot. This code is godot 3.0

In you script.

func print_string(s):
    print(s)

var cb = funcref(self,'print_string')
var m = YourModule.new()
m.setCallback( cb )

In you set function use

//_r is a Ref<FuncRef>
void YourModules::setCallback(Ref<FuncRef> r){
      _r = r;
}

to call the callback

void YourModule::emit(){
        String s( "i am a cow");
        Variant v(s);
        Variant *args[1] = {&v};
        Variant::CallError err;
        _r -> call_func( args, 1, err);
}

I am only answer because of this

http://docs.godotengine.org/en/latest/classes/class_funcref.html