Tuesday, 22 May 2018

Async/await with Animations

Years ago I had fun coding an animation matrix (the sample has been moved here). Most cases involved a sequence of animations, each one starting after the previous one had finished. It was one more case where I had to simulate an asynchronous loop, where at the end of each "iteration" I would callback into an "orchestrator function" that would launch the next iteration. I realized that now that we have async/await, this could be done in a much more straight forward way, so I've prepared some sample code.

For the kind of animation that I'm doing it would have been more simple to just animate divs rather than drawing squares on a canvas, but lately I've been playing around with particle systems on a canvas, and I've preferred to continue with the canvas route.

Whatever item we are animating, the thing is that starting the animation should return a Promise that will get resolved when the animation completes. For this sample I'm animating a square that falls from the top to the bottom of the canvas and bounces a couple of times until it stops. You can see it here. The code (yep, I've jumped into the TypeScript trend) looks like this:


abstract class AnimationItem{
 currentPosition:Vector;
    endPosition:Vector;
    moving:boolean;
 resolveCurrentAnimationFunc:any;

 public abstract update():void;
 public abstract draw():void;
 
 public animate():Promise<void>{
  this.moving = true;
        return new Promise<void>((res, rej) => {
            this.resolveCurrentAnimationFunc = res;
        });
    }
}


//in our child, concrete class:
    public update():void{
        if(!this.moving){
            return;
        }

        this.ySpeed += this.gravity;
        //this.logger.log("speed: " + this.ySpeed + ", pos:" + this.currentPosition.y + ", " + this.acceleration);
        this.currentPosition.y += this.ySpeed;
        if(this.currentPosition.y >= this.endPosition.y){
            //let's place it just in the limit
            this.currentPosition.y = this.endPosition.y;
            if(this.bounces > 0){
                this.bounces--;
                this.ySpeed = -1 * this.ySpeed/2;
                this.logger.log("bouncing: pos:" + this.currentPosition.y + ", speed: " + this.ySpeed + ", " + this.acceleration);
            }
            else{
                //stop it
                this.moving = false;
                this.resolveCurrentAnimationFunc();
            }
        }
    }

So we have an animate method that returns a newly created Promise and stores in our class a reference to the resolve handle of this Promise. The update method takes care of updating the position of the object and resolving the Promise once the final position is reached.

I'm animating several of these items (rows and columns), one after another. With the power of async/await our code is so simple as just writing normal loops like this:

for (let y=0; y<2; y++){
        for (let x=0; x<3; x++){
            let item:AnimationItem = new FallingSquare(ctx, 
                new Vector(x * size, 0), //currentPosition:Vector, 
                new Vector(x * size, canvas.height - (size * (y + 1))), //endPosition:Vector,
                0, //speed:number, 
                size,
                "red",
                logger);
            
            animationSystem.addItem(item);   
            await item.animate();
        }
    }

I've uploaded along with the transpiled and bundled javascript file the original typescript source code and the source map, so to see the full code just launch the debugger!

Friday, 18 May 2018

Foreach Async Gotcha

Today I came up with an interesting gotcha with async/await. I transformed a normal for loop containing await calls into an Array.prototype.forEach call, and realised that it was not working properly. Let's see:

Let's say that we have this nice async loop:

//asynchrnous function returning a Promise
function formatTextAsync(txt){
    return new Promise((res, rej) => {
        setTimeout(()=> res(txt.toUpperCase()),
         2000);
    });
}

async function loop1(){
    console.log("loop1 start");
    let items = ["bonjour", "hi", "hola"];
    for (item of items){
        console.log(Date.now() + " input: " + item);
        item = await formatTextAsync(item);
        console.log(Date.now() + " output: " + item);
    }
    console.log("loop1 end");
}

console.log("before main");
loop1();
//loop2();
//loop3();
console.log("after main");

// before main
// loop1 start
// 1526678289508 input: bonjour
// after main
// 1526678291514 output: BONJOUR
// 1526678291515 input: hi
// 1526678293518 output: HI
// 1526678293518 input: hola
// 1526678295521 output: HOLA
// loop1 end

If we decide to move the loop body into an Array.prototype.forEach method call, the output is quite different:

async function loop2(){
    console.log("loop2 start");
    ["bonjour", "hi", "hola"].forEach(async (item) => {
        console.log(Date.now() + " input: " + item);
        item = await formatTextAsync(item);
        console.log(Date.now() + " output: " + item);
    });
     console.log("loop2 end");
}

// before main
// loop2 start
// 1526678543105 input: bonjour
// 1526678543109 input: hi
// 1526678543109 input: hola
// loop2 end
// after main
// 1526678545109 output: BONJOUR
// 1526678545111 output: HI
// 1526678545111 output: HOLA

So in the second code, the next iteration is launched without waiting for the async call in the previous iteration to complete. This means that the async calls end up running in parallel rather than in sequence.

The explanation for this behaviour is quite simple. We've moved the loop body containing the async call into a new function that we've marked as async, but, is anyone awaiting for this new function?, the answer is No, so the next iteration is started without waiting.

We can guess that the implementation of Array.forEach is something along these lines:

Array.prototype.forEach = function (fn) {
    for (let item of this) { fn(item) }
}

In order to get the correct async behaviour that we have when using a normal loop, we would need something like this:

Array.prototype.forEachAsync = async function (fn) {
    for (let item of this) { await fn(item) }
}

Lisbon Documentaries

Some months ago I wrote about how a lovely city Lisbon is. I've recently watched 2 pretty interesting documentaries showing 2 complementary views of the city, and I've thought that it would be nice to share them here.

DW (Deutsche Welt) has some excellent documentaries in English, dealing with a broad range of topics: social, politics, technology, travel... This one shows a really interesting portrait of life in Lisbon. It's from 2013 I think, which seems to me like the time when Lisbon was starting to become a trendy city attracting foreigners not just for regular vacation, but for longer/permanent stays. In some of the amazing panoramas one can see some construction cranes, but little to do with the huge number of them that I could see last November. I really enjoy when I see in films or documentaries places that occupy a place in the memories of my heart, and this documentary has quite a few of them.

This one from 2018 by BBC puts its focus on the artistic side of the city and how it has been modelled by the Portuguese history. I share with the female host the fascination with the Mosteiro dos Jeronimos and its Manueline gothic. I remember how amazed and excited I felt in my first time there. On the other side, though I understand that they want to focus on Portuguese art, I find it hard to believe that their filming in the Museu Nacional de Arte Antiga has not included any reference to the most amazing work located there, the Temptation of Saint Anthony. For sure Hieronymus Bosch has little to do with the History of Portugal, but any art lover visiting Lisbon should not miss spending quite a while in front of this heartbreaking Triptych.

Thursday, 10 May 2018

La Charia au Paradis

Some weeks ago I watched La Charia au Paradis a quite disturbing documentary about Maldives, that small island country in the Indian Ocean. Until then my basic knowledge about these islands could be summed up in these few points.

  • An idyllic tourist destination
  • One of the places that was hit hard by the 2004 tsunami
  • One of those places particularly threatened by the sea level rise (the whole country could just disappear)

I had no idea about the politics of these islands, and though I had the impression that it was mainly a muslim country, I was not aware of particular problems caused by the "religion of peace". Well, I was quite far from the true. In the last years fundamentalist Muslims have taken control of the country and are imposing their madness to the rest of the population. The law system is based on the shariah, and Saudi Arabia has been more than happy to host and train Maldivian guys in the "true Islam" so that they can return to the islands to teach/impose their Medieval learnings to a population that until recently was for the most part rather moderate. Hum, lovely Saudi Arabia, exporting love an tolerance not only to the European "Quartiers Sensibles", but also to peaceful, idyllic islands.

For the moment, given that the whole country lives on tourism, shariah law is not applied to the foreigners that fill the touristic resorts, but that could be changing in the future. Maybe they are planning to replace Western amoral couples with Saudi families. In the meantime, if I were a tourist I would be a bit scared that one day one bunch of beardy Islamist could decide to raid one of the resorts...

Sunday, 29 April 2018

Promises and the Event Loop

I've been reading some documents/articles about the JavaScript event loop (particularly for node.js) and I've found the explanation for what I had noticed in this post regarding awaiting an already resolved promise and the "jumping out" of the async function.

This series looks particulary good. The documentation about the event loop tends to be confusing (particularly the node.js documentation, this discussion helps to clarify it a bit though), but this one seems rather clear (hope it's not simplifying things too much and getting things not fully correctly).

The main idea is that the event loop goes through several phases, traversing several queues where different events/handlers/callbacks have been enqueued. There are 2 "intermediate queues" with a sort of high priority, as they are checked several times per iteration (one time after the traversal of any of the other queues). One of these 2 queues is the Micro task queue. This queue is used for Promises, well, for Promises callbacks, I mean, the handlers attacched to a Promise via then or catch. These callbacks/handlers are added to that queue when the corresponding Promise is resolved. If you add the handlers to an already resolved Promise, the handlers are added to the queue. So contrary to Tasks in .NET, the callback is not executed immediately, but added to the queue. This is what explains the behaviour that I mentioned in my previous article. An example (I'm not using await this time, just then().

let p1 = Promise.resolve("hi");
p1.then(it => console.log("the result is: " + it));

console.log("after resolve and then");

p1.then(it => console.log("and again is: " + it));

// after resolve and then
// the result is: hi
// and again is: hi

You can see how the "console.log" is executed before the "then handler" that got added in a previous line to an already resolved Promise. This answer fully matches with my understanding of Promises and the queue.

When a promise fulfills or rejects, the promise library puts tasks onto the queue for all the attached then or catch handlers. (If a then or catch handler is attached after the promise fulfills or rejects, then the task is put on the queue immediately.)

Thursday, 26 April 2018

Reentrant Function

The wikipedia article about coroutines makes an interesting read. In simple terms we can say that a coroutine is a function with multiple entry points, so that it can exit and start its execution later in a different point.

This should sound familiar. You could create a reentrant function by means of a closure, that would keep a state dictating what to do in the ensuing call. Both in C# and JavaScript the yield and await keywords allow us to create reentrant functions (well, await is a bit different, we could say that the function is reentring itself). Indeed, the terminology used in JavaScript, generator, is in accordance with the Computer Science nomenclature used to define a limited type of coroutines.

The thing is that invoking a generator function (javascript) or an iterator method (C#) return a generator/IEnumerable-IEnumerator object on which we will invoke the next or MoveNext methods. So we don't really have a reentrant function, but invocations on the same method of an object that maintains state. If we really want the effect of invoking a reentrant function we can easily leverage a generator/Iterator. I'm using C# iterators for my samples, it would be basically the same in JavaScript.

We can define a Factory method that will return a reentrant function (delegate). This factory method contains a local function defining an iterator and creates a closure that manages the iteration.

        public static Func<string> CreateMessageProvider<T>()
        {
            IEnumerator<string> messageProvider(){
                yield return "Bonjour";
                yield return "Hola";
                yield return "Hello";
                
            }

            IEnumerator<string> enumerator = messageProvider();
            return () => {
                if (!(enumerator.MoveNext())){
                    throw new Exception("Finished");
                }
                return enumerator.Current;   
            };
        }

//main

coroutine = CreateMessageProvider<string>();
Console.WriteLine(coroutine());
Console.WriteLine(coroutine());
Console.WriteLine(coroutine());

We can generalize the above code to create a reentrant function from any provided IEnumerable:

        public static Func<T> CreateCoroutine<T>(IEnumerable<T> enumerable)
        {
            IEnumerator<T> enumerator = enumerable.GetEnumerator();
            return () => {
                if (!(enumerator.MoveNext())){
                    throw new Exception("Finished");
                }
                return enumerator.Current;   
            };
        }

Monday, 23 April 2018

Converted Idiot

I have a particular disdain for those that coming from a non-Muslim background (their families are not Muslim and the society where they live is not mostly Muslim) decide on their own accord to convert to Islam. One thing is that you are indoctrinated into it since birth, and another thing is that you decide to freely plunge into it. Choosing to be a slave and lock your chains... Europeans that convert to Islam have a tendency to embrace the worst parts of Islam and adhere to the Salafist/Fundamentalist crap. For me authorities should do a close follow-up of anyone converting to Islam in Europe.

On the other side I hate far-right, racist, xenophobic, ultra-nationalist scum. While I think that some of the political parties that the mainstream media classify as far-right are not really far-right (I don't like the French Front National, but honestly I would not say that they are a bunch of neo-nazis), AfD (Alternative fur Deutschland) falls into the real far-right side for me. Their only good thing, their anti-Islamisation stance, does not make up for all the xenophobic and ethnic nationalist views shown by many of their high level members.

One could think that the only point where AfD militants and Muslims could converge is in a street fight, but to my astonishment I've just found about one pretty vocal AfD member that has converted to Islam!. You can also watch this video.

Maybe someone could think that this is not so odd, as the good relations between Nazi Germany and Islamists are well known. Hitler was a supporter of Hassan al-Banna and the Muslim Brotherhood, and had Haj Amin al-Husseini, the Grand Mufti of Jerusalem, as guest in Berlin for several years. One huge SS division, SS Handschar, was made up mainly by Muslims, and Himmler had a fascination for Islam and for how it created "fearless soldiers". Well, I guess many far-right idiots can be OK with Islam as long as it stays in "lands of Islamic culture" (I mean, areas where it has been dominant for centuries), but when an "European aboriginal", living in Europe converts to Islam, it would sound as an act of treason. For me it's an act of stupidity. I would happily embrace a culture more advanced than that of my ancestors, but embracing a Middle Age ideology... no way.

Well, it seems the guy finds that Christianity has turned too open and liberal (it no longer burns gays in the stake!), while Islam represents the conservative moral values that he likes. Nice... It remains me of when Conservative Christian groups and Muslims joined together in France some years ago to protest against Gay marriage.