Can't update values while doing multiple for loops


#1

Hi,

I have mutiple for loops inside other for loops and it takes a while to execute, which is normal.

At the end of a certain for loop, I want to update some values so see where the execution is at. In other words, I’m trying to create a loader that updates during the for loops. The thing is that those values don’t update during the loops and update only at the end when the loops are finished.

Do you have an idea what is wrong?

Thank you!


#2

Most work all occurs on the same “thread”, which means that it will do one thing, and then the other:

// occurs before
for (i in 0...100000000) {
 // do work
}
// occurs after

There are a couple approaches to update a loader while this occurs, the first is to use events, and to trigger only a little bit of work at a time. Another is to use a background thread.

Perhaps it would be possible to do your work in a background thread, so long as it doesn’t change any display objects, or values that might be needed from the main application at the same time?

If this is a native platform, you can do some work in a background thread like this:

import lime.app.Future;

...

var future = new Future (function () {
    
    // do work
    var result = 100;
    return result;
    
}, true);

future.onComplete (function (result) {
    trace (result);
});

On Flash and HTML5, threads are not supported in this way, so it would be necessary to split up your work:

addEventListener (Event.ENTER_FRAME, function (_) {

    var thisFrame = workPerFrame;
    if (workDone + thisFrame > workTotal) thisFrame = workTotal - workDone;
    
    for (i in 0...thisFrame) {
        // do work
    }
    
    workDone += thisFrame;
    
});

#3

Thank you for your reply.

I doesn’t seem to work… In fact, I need to change some textfields to show the progression of the loader. A simple trace work, but I want something to be shown on the app. I’m exporting using Neko.

I also just realized that this problem occurs even before the for loop!

Here’s an example of my code running in a Singleton:

private function _export_levels():Void {
	loader.update_title("Exporting...");
	loader.update_progression(0, LevelsManager.get_nb_levels());
	levels_exported = 0;
	levels = LevelsManager.get_all_levels();
	
	//Get all the different sizes of levels (ex.: 1x2)
	//levels:Map<String, Array<Level_Datas>>
	for (size in levels.keys()) {
		
		//Get all levels of a size
		var levels_from_size:Array<Level_Datas> = levels.get(size);
		
		//Check all levels from a specific size
		for (i in 0...levels_from_size.length) {
			var level:Level_Datas = levels_from_size[i];
			
			//Main
			for (row in 0...level.main.length) {
				for (column in 0...level.main[row].length) {
					...
				}
			}
			
			//Second
			for (row in 0...level.second.length) {
				for (column in 0...level.second[row].length) {
					...
				}
			}
			...
			
			//THIS IS WHERE I WANT TO SHOW THE PROGRESSION
			levels_exported++;
			loader.update_progression(levels_exported, LevelsManager.get_nb_levels());
		}
	}

#4

Oh!! I think that I understand!

The code do everything in all the loops in a single frame and that’s why nothing is updating.

I’ll try somthing else!


#5

It finaly worked with Future!

I was just not using it the right way…

I’m using Future to execute all my for loops and an Enterframe to update my textfield to show the progression.

Thanks for the help!