Generators and yield feature in Sciter Script

yield-sign

In Sciter any function that contains yield keyword is treated as a generator function.

Main purpose of the generator is to produce sequence of values – on each generator invocation it returns next value.
Generator returns next value when yield <expression> is executed by the generator.

Consider this generator function:

function  ordinals() {
   yield "first";
   yield "second";
   yield "third";
}

And the code that uses it:

for(var ordinal in ordinals()) 
  stdout.println(ordinal);

Body of the loop will be executed three times as on each generator invocation next yield will emit its value.
And so you will get this output:

> first
> second
> third

The yield (in generators) and await (asynchronous tasks) are internal incarnations of the same mechanism – coroutines.

task/await feature in TIScript

At the moment I am working on await feature in TIScript.

Await is a way to solve callback / promise “hell” in languages like JavaScript and so Sciter Script:

Callback hell

Consider the following code that uses await:

function setupUsersMottoTask(userName)
{
  try {
     var user = await request(#get, "http://example.com/user/" + userName);
     var userMotto = await request(#get, "http://example.com/user/" + user.id + "/avatar");
     self.$(#user > .motto).text = userMotto;
  } catch (e) {
     self.$(#user > .motto).text = "motto unavailable";
  }
}
setupUsersMottoTask("monster"); // runs asynchronously as it is a Task function.

Without await that code above would look like as a ladder of callbacks and error handlers.

Essentially await linearize asynchronous code making it running as normal sequential code.

In Sciter Script any function that uses await inside is automatically declared as asynchronous task function. Invocation of such function starts the task and returns immediately. Such function returns promise and so it’s call can also be used in other awaits.

Sciter and DirectX

Sciter 3.3.1.4 adds an ability to render HTML/CSS directly onto DirectX window:

Basic ideas:

  • Sciter engine is attached to the window where DirectX renders its 3D scene. WndProc uses SciterProcND delegation in Mixin integration mode.  Therefore Sciter sees all UI messages coming to the window and reacts on them. Instance is created by SciterCreateOnDirectXWindow API function.
  • Application calls SciterRenderOnDirectXWindow API function to render content when it is appropriate. With the function following rendering modes are supported:
    • Document is rendered on background of 3D scene;
    • Document is rendered in front of 3D scene (on top of it). In this case document should have transparent background and transparent element through which 3D scene can be seen;
    • Document may contain so called layers – dedicated DOM elements (<section>s, <div>s) representing background and foreground UI layers with 3D scene rendered in between. The screen cast above represents such type of rendering. Below is an illustration of such layers:

sciter DOM layers on DirectX window

Sciter’s DirectX API also contains SciterRenderOnDirectXTexture API function. It is used to render HTML/CSS content on DirectX 2D textures.

If your setup requires DOM layers then it makes sense to consider adding native behavior to DOM element on front layer that will establish view on 3D scene. Such a behavior will catch mouse and keyboard events and reroute them to view/model manipulations.

Scripts can also be used to manipulate 3D view/model variables. Check  {sciter-sdk}/demos.win/sciter-directx/ demo project – it demonstrates all this.