It's a bit of a loaded request.
I'm browsing through the Cocos2dx sources and searching their forums and it looks to me as async loading of assets are constrained to a small subset of asset types (images, audio, armature).
Cocos2dx doesn't have great async loading support. They explicitly state that most of the API is non-thread-safe, especially the Reference Counting/ AutoRelease pools. Looking through their multithreaded code, it has some pretty common mistakes (lazy initialization) and generally a poor design. TextureCache::addImageAsync can't even be called asynchronously, which creates problems for loading.
I'm not trying to be hyper critical of Cocos2dx, but multithreading tends to expose flaws.
Here are the two major causes of performance issues that are generally solved by multithreading:
Unless you have made some particularly boneheaded mistakes, loading from disk is going to be the easiest form of asynchronization.
Example Loading Spine animation w/ multithreading
To load a spine animation, you need to load the following files:
atlas
images referenced in atlas
JSON
While you are processing the atlas, it's going to kick out image load requests that you are going to want to perform asynchronously. Depending on how the references/pointers are setup, you may have to wait for all images in the atlas to load before completing. Remember earlier how I said "TextureCache::addImageAsync" wasn't thread-safe? All of those calls need to be issued on the main thread.
Another kicker: image file-loading and pixel-preprocessing can be done on a worker thread, but texture upload to GPU has to be done on the main thread.
Loading and processing a JSON file should be fine, but remember that the Atlas needs to be completely loaded before loading the JSON.
Loading would look something like:
Read Atlas File [Worker Thread]
Process Atlas File [MainThread] // to issue addImageAsync
Wait for images to Load
Load Image File [Worker Thread]
Upload to GPU [MainThread]
Read JSON from Disk [Worker Thread]
Parse JSON [Worker Thread]
Design
To account for the [Worker Thread] / [Main Thread] split, your JOB should have 2 phases: one for background on worker thread and the other foreground on main thread. To process the foreground phase, you'll need a JobScheduler class running on the main thread listening for the engine update() tick.
The back and forth between main/worker thread is best handled by splitting up into sub jobs. {1,2} would be the first job, waiting on CCTextureCache to perform {3} would be the second, and {4,5} would be the third. To orchestrate that you'll need some sort of controller with a state machine and probably a callback mechanism.
You'll also have to create thread pools, concurrent queues, signals and mutexes, etc.. etc.. etc...
Example Pre-loading files w/o Spine
Does the previous approach sound complicated? It is. Every step along the way is probably more complex that what I've let on and a potential bug.
Remember the image from earlier? https://d262ilb51hltx0.cloudfront.net/m ... vZCNLL.png
The IO from disk is a major culprit in causing the loading issues. What if instead of loading a Spine animation asynchronously, you only loaded the data from disk?
Spine has methods spSkeletonJson_readSkeletonData and spAtlas_create which take character buffers instead of file names. If you use multithreaded loading to load the files into character buffers, it should decrease loading times noticeably.
You could simply copy CCTextureCache and rewrite it to load files from disk (generically) into a character buffer. e.g. "CCFileDataCache"
Issue calls to load ALL of the JSON/Atlas files async and then hit the cache when creating the SkeletonData.
The word 'load' appears 31 times in this post