Our game engine Cocos2d-x runs natively on android on its own non-Java-UI-thread. We need to call certain Java functions from C++ via
Another option is to use the Arcana.cpp C++ library, which includes an Android Looper based "scheduler." In its simplest form, you can use it like this:
#include
void SomeFunctionCalledFromUIThread()
{
// Note: The '64' below is the max size of the callables passed to the scheduler.
// This is done to reduce allocations and make schedulers more efficient.
auto looper_scheduler = arcana::looper_scheduler<64>::get_for_current_thread();
// Get on a background thread to test getting back on the UI thread.
std::thread worker([looper_scheduler = std::move(looper_scheduler)]() {
looper_scheduler([]() {
// Do something on the UI (looper) thread
});
});
}
Schedulers are a general construct in Arcana.cpp, and are also used in the low overhead cross platform async task system, so if you opt to use that then you can do typical async task programming with this scheduler:
#include
#include
#include
// Schedulers need to outlive task chains, so imagine m_looper_scheduler and m_background_dispatcher are created and stored from some constructor.
// "Dispatchers" in Arcana.cpp are a class of schedulers that own their own work queue.
arcana::task SomeFunctionCalledFromUIThread() {
return arcana::make_task(m_background_dispatcher, arcana::cancellation::none(), []() {
// Do something on a background thread (via background_dispatcher).
}).then(m_looper_scheduler, arcana::cancellation::none(), []() {
// Do something on the UI thread (via looper_scheduler).
});
}
If you want to get more adventurous, C++ coroutines can be used with tasks, or directly with schedulers:
#include
#include
#include
#include
arcana::task SomeFunctionCalledFromUIThread() {
auto looper_scheduler = arcana::looper_scheduler<64>::get_for_current_thread();
arcana::background_dispatcher<64> background_dispatcher;
// Code executing here is on the UI thread (since the function is called from the UI thread).
co_await arcana::switch_to(background_dispatcher);
// Code executing here is on a background thread.
co_await arcana::switch_to(looper_scheduler);
// Code executing here is back on the UI thread.
}
You can read more about Arcana.cpp schedulers, tasks, and coroutines here: https://github.com/microsoft/arcana.cpp/blob/master/Source/Arcana.Tasks.md