AsyncSystem Question

Hi again! I’m trying to implement a wrapper around Cesium Native and I’m running into an issue where it looks like the async system won’t call out to the main thread, so the tile set loader never finishes, etc. Here’s a very simple implementation that illustrates the issue.

I’ve created an asset accessor and async system very similar to how they are created in the unreal implementation. When I run the first block, the asset accessor pipeline runs fine and retrieves the url, etc and then the thenImmediately block runs.

    _runThread = std::make_shared<std::thread>([asyncSystem, url, headers, pAssetAccessor](){
        pAssetAccessor->get(asyncSystem, url, headers).thenImmediately([
            url = url](std::shared_ptr<CesiumAsync::IAssetRequest>&&
                       pRequest) {
            
            // This code  gets executed
            std::cout << "thenImmediately\n";
            
        });
    });

But when I change it to be thenInMainThread, the asset accessor runs the same as above, but that thenInMainThread block never runs.

    _runThread = std::make_shared<std::thread>([asyncSystem, url, headers, pAssetAccessor](){
        pAssetAccessor->get(asyncSystem, url, headers).thenInMainThread([
            url = url](std::shared_ptr<CesiumAsync::IAssetRequest>&&
                       pRequest) {
            
            // This code never gets executed
            std::cout << "thenInMainThread\n";
            
        });
    });

I’ve tried kicking off the pAssetAccessor->get several ways including just on the main thread (removing the std::thread stuff) and using a dispatch queue (I’m on iOS).

I’m sure I’m just setting up the environment wrong, but curious how to get thenInMainThread to work right.
Thank you!

I actually just sorted this out. Looks like the main thread activities that are queued up in asyncSystem have to be manually drained and that’s part of the Tileset::updateView method. I just wasn’t calling that yet.

const ViewUpdateResult&
Tileset::updateView(const std::vector<ViewState>& frustums, float deltaTime) {
.
.
-> Here
  this->_asyncSystem.dispatchMainThreadTasks();
1 Like

Yep, that’s right. There’s no way for us to preempt whatever other work the main thread is doing in order to dispatch our tasks (if we even knew which thread is the main one). If we could assume a Windows event loop or something, we could use that to dispatch the tasks, but cesium-native is platform agnostic. So its up to users to dispatch the main thread tasks at an appropriate time.