Asset loading (priority, concurrent loads)

Hi

How can i prioritize asset? How can i limit count of concurrent loads?

If it is possible to set priority for asset loading, how to change it later?

For example i have 15 “scenes”(objects). They are connected by portals(many to many/one to many/randomly). We can move to neighbor scenes only when our scene is loaded.

We start in scene1 and load it’s content and after it’s done we load neighbors.
scene1 is loaded and we move to scene2. Then we start loading it’s neighbors. We need to load scene2 ASAP and start loading neighbors.
But now it’s very slow, cose we will load a BUNCH of scenes concurrently.

We had similar case where some limit of concurrent loading of assets was required and some priority in place. But after experimenting there were many different scenarios to go with, so we couldn’t find generic approach that would work for everybody so idea of making it a part of assets loading functionality was dismissed.

So you could make it to your case in specifics. For example, you can say when to load an asset, and you know exactly which assets you are loading. You could make a priority yourself and then limit number of assets.load methods you call until some are loaded, and even more you could evaluate what should be loaded by type, like - load models first, then materials and only then textures of particular world behind portals, and only then start loading other portals.

If you uncheck preload from all assets, that way they are not loaded on start. Then you need to maintain your own list of assets and trigger app.assets.load(asset) on them when not too many assets are loading and sorted by your priority logic.

Other useful thing to use for this - are Tags. It is convenient way to tag things based on their priority or which world they belong to.

thanks

I just have one big texture (2mb) per “scene”, so tags are irrelevant for me. I load it by app.assets.load(asset).

I see way to do priority, but as i know i can’t pause and resume loading of specific asset. (app.assets.pauseLoad(asset) for example).

No you cannot pause, but you could do something like so:

var assets = [ ];
var loading = 0;
var loadingLimit = 4;

var chooseNextAsset = function() {
    var asset = null;
    var ind;

    for(var i = 0; i < assets.length; i++) {
        if (! asset) {
            asset = assets[i];
            ind = i;
            continue;
        } else {
            if (assets[i].priority > asset.priority) {
                asset = assets[i];
                ind = i;
                continue;
            }
        }
    }

    if (asset) {
        // remove asset from queue
        assets.splice(ind, 1);
    }

    return asset;
};

var addAssetToQueue = function(asset, priority) {
    assets.push(asset);
    asset.priority = priority;
    loadNext();
};

var loadNext = function() {
    if (loading === loadingLimit || ! assets.length)
        return;
        
    var asset = chooseNextAsset();

    if (! asset.resource) {
        // not already loaded
        loading++;
        asset.once('load', function() {
            // loaded asset
            loading--;
            loadNext();
        });
        app.assets.load(asset);
    }

    loadNext();
};

So you have three methods:
chooseNextAsset - is logic of choosing next asset, in this case it chooses who has largest priority number. You could change that logic to whatever you want.
addAssetToQueue - adds asset to queue of loading, and triggers loading if needed.
loadNext - starts loading, you don’t need to call it yourself, it will be called when some assets are loaded or added to queue.

So this will limit number of assets loading to 4, and will pick next asset to load based on priority.
All you need is to define priority logic.

1 Like

You rock :smiley:

I’ll try to use this.