Lime Future of multiple Futures

I need to load two things and complete a Future when they are done but I don’t understand these classes in the lime.app.Promise/Future.

I’m used to Promises the way it works in javascript and node.js.
You can use Promise.all(array) to return a promise that will complete when all the array is completed.


If I has a class in Haxe implemented like the js Promise, to load a shader I could do this:

[code]
function loadShader() {
return new Promise(function(resolve, reject) {
function onFail(error:Dynamic) {
state = ResourceState.failed;
reject(error);
}

    var sources = [];

    var frag = loadText(fragID);
    frag.then(function(asset:AssetText) {
        fragmentSource = asset.text;
    }).error(function(error) {
        trace(error);
    });
    sources.push(frag);

    var vert = loadText(vertID);
    vert.then(function(asset:AssetText) {
        vertexSource = asset.text;
    }).error(function(error) {
        trace(error);
    });
    sources.push(vert);

    Promise.all(sources).then(function() {
        if (buildProgram(vertexSource, fragmentSource)) {
            state = ResourceState.loaded;
            resolve(this);
        } else {
            state = ResourceState.failed;
            onFail(trace('$id failed to create'));
        }
    }).error(function(error) {
        onFail(trace('$id failed to create - $error'));
    });
});

}[/code]

But how I do it with lime.app.Future?
I can load the assets this way but there is no way to make a Future that will return when the two are done or control when it will be completed or be an error

var f = loadText('assets/shader.frag');
f.onComplete(function (string:String) {
    trace(string);
});

var v = loadText('assets/shader.vert');
v.onComplete(function (string:String) {
    trace(string);
});

return ????

Probably you can use one of following libraries:

  • thx.promise
  • continuation
  • hxbolts

And wrap Promise / Future from lime into more traditional promises

I used hxbolts and got my resource management working for desktop quickly. I really like how it works.
However I’m not sure how to deal with the TaskExecutor in a multiplatform way.
The code doesn’t compile for HTML5 or flash because places that use Mutex.

You don’t need any executors for html or flash, because non of them supports real multithreading. Also not sure why you need task executors on desktop - do you make some complex calculations on background thread?

If you just want to load resources, than you can do this without background executors, because openfl (and lime) correctly load everything at background thread itself.

That’s what I use for network - https://github.com/restorer/zame-haxe-miscutils/blob/master/org/zamedev/lib/NetLoader.hx (it not for lime, but for openfl)

public static function send(method:String, request:DynamicExt):Task<DynamicExt> {
    // ...

    return (new NetLoader(url))
        .forPostJson(request)
        .loadJson()
        .onSuccess(function(task:Task<DynamicExt>):DynamicExt {
            if (task.result["error"] != null) {
                throw new ApiError(task.result["error"]);
            }

            return task.result;
        });
}

No executors needed.

P. S. If you really need executors for some reason, you can do something like this:

public static inline function getBackgroundExecutor() : TaskExecutor {
    #if (cpp || neko || java)
         return TaskExt.BACKGROUND_EXECUTOR;
    #else
         return TaskExt.UI_EXECUTOR;
    #end
}

This will use BACKGROUND_EXECUTOR on native targets, with fallback to UI_EXECUTOR for other targets.

I know. The issue is that it doesn’t compile.
It doesn’t work for lime only projects.
I have modified the code to work.

I don’t use openfl. I’m porting my custom engine to lime.
The default asset system of lime seems to be sandboxed (can’t load outside the Asset folder) even for desktop and all files need to be registered at start-up. The Assets.load functions quietly crash and close the app when there is a problem instead of throw an error.
This makes hard to use the same code for games and tools as well so I’m implementing other file loader for my framework.
My framework is very automated do speedup development, it reloads images and process texture atlas, models and other files at runtime whenever they are changed in the disk. The system is done in a way that if the resource is not completely loaded it doesn’t cause errors so I’m looking to use threads.

Can you fill issue on github?

Thanks, PR merged. Also I add demo for lime, to be sure that everything works correctly.

Lime Assets.* is designed to work with files known at runtime. You can choose to embed or not, but if you want to load other files, you should use either a network loader or APIs such as Image.fromFile and Image.fromBytes directly.

Since it is cross-platform, you need to package assets on mobile platforms, and need to relocate on certain desktops.

As for Future/Promise, I’m open to suggestions to improve. promise.completeWith exists for chains, but that may not be as nice as being able to cleanly set multiple dependent futures