Receive all `onProgress` events from asset loading

In my app, I’m changing individual parts of the scene pretty often and interactively, often loading them on demand. Until recently, I’ve used to track Babylon’s loading progress globally by monkey-patching FileTools.RequestFile:

import { FileTools } from '@babylonjs/core/Misc/fileTools';

FileTools.RequestFile = () => {...}

Since 5.0 this is not possible anymore, because RequestFile is not namespaced in 5.0.

Is there any other way to avoid adding onProgress handlers everywhere?

would scene._requestFile despite being private fit your needs ?

That’s a good pointer, thanks! I’ll probably have to monkey-patch scene._loadFile too, but this might be a proper way.

Let me know if that works and we ll try to make it a more official feature.

1 Like

Hi @rassie just checking in how are things? Would you like any more help?

@carolhmj I’m sorry, I haven’t got around to actually implementing this. I’m about 90% certain it will work as desired, but have no proof yet.

2 Likes

For completeness sake: I’ve come around to trying this. I ended up extending Engine._loadFile instead of Scene._loadFile / Scene._requestFile, which seems to work fine for now (but I expect to find side effects any minute now). The code I’m using:

export class CustomEngine extends Engine {
    public _loadFile(
        url: string,
        onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void,
        onProgress?: (event: ProgressEvent) => void,
        offlineProvider?: IOfflineProvider,
        useArrayBuffer?: boolean,
        onError?: (request?: IWebRequest, exception?: unknown) => void
    ): IFileRequest {
        const success = (data: string | ArrayBuffer, responseURL?: string) => {
            notifySuccess(url, data);
            onSuccess(data, responseURL);
        };

        const progress = (event: ProgressEvent) => {
            const { loaded, total } = event;

            notifyProgress(url, loaded, total);

            if (onProgress) {
                onProgress(event);
            }
        };

        const error = (request?: IWebRequest, exception?: unknown) => {
            notifyError(url);
            if (onError) {
                onError(request, exception);
            }
        };

        return super._loadFile(url, success, progress, offlineProvider, useArrayBuffer, error);
    }
}

About making this official: I find this useful, since I’m (re-)integrating BabylonJS’ loading progress into my global progress indicator, but I don’t know whether it’s needed by others on a regular basis. If there is a simple and concise way to integrate it, I’m all for it, but I don’t think there is much sense in expending a lot of effort on this.

3 Likes

glad to know you found an easy way and agree, lets wait on another need to make it public.