Cauldron


Les 30 et 31 janvier 2010, j'étais dans les locaux de d'Iliad (Free) pour les Elixir Dev' Days 2010 pour une formation sur Elixir.

Qu'est-ce qu'Elixir me direz-vous ? C'est tout simplement une application disponible sur la freebox V5 pour exécuter des applications Javascript[1]. Cette application est également disponible sous Linux.

Placez un fichier à l'extension .js sur le disque dur de votre Freebox et il sera reconnu comme une application Elixir !

Mais que fait-on avec du Javascript sur une freebox ?

Ici pas de HTML, pas d'objets DOM, en fait on ne trouve qu'un objet propre à Elixir, j'ai nommé elx.

Voici un exemple tout bête :
elx.print(elx.version + "\n");

Si vous placez ce code dans un fichier Exemple.js sur votre Freebox, vous obtiendrez un écran noir et puis un retour au disque. Pas très intéressant, mais dans la version Linux, vous obtiendrez la version d'Elixir ... à la console. Console qui n'est pas visible sur la Freebox :)

Ok, mais alors on fait quoi sur la Freebox avec Elixir ? On utilise EFL pour afficher des informations à l'écran. Vous trouverez des tutoriaux sur le site d'Elixir.

Personnellement, je trouve que cette API est assez moche...sans doute ai-je trop longtemps travaillé sur le langage Delphi et ne suis pas à même de comprendre toute la beauté qui se cache derrière ce code C...mais quoi qu'il en soit, il reste possible de faire des choses sympa avec Elixir grâce à Javascript.

Et c'est comme cela qu'est né Cauldron


Un peu de code c'est mieux qu'un long discours...aussi voici le même code en version "Elixir" classique et en version "Cauldron" :

D'abord la version classique reprise sur le groupe google d'Elixir.

Il permet d'afficher une boîte de couleur douteuse qui rebondi sur les bords de l'écran.

var FN = "/.fonts/";
var test = true;

test &= elx.load("evas");
test &= elx.load("ecore");
test &= elx.load("ecore-evas");

function anim_cb(obj)
{
   var geom = evas_object_geometry_get(obj);
   var dx, x;
   var dy, y;

   dx = evas_object_data_get(obj, "dx");
   dy = evas_object_data_get(obj, "dy");

   x = geom.x + dx;
   y = geom.y + dy;

   if (x + 250 > 720 || x < 0)
     {
	dx = -dx;
	x += 2 * dx;

	evas_object_data_set(obj, "dx", dx);
     }

   if (y + 200 > 576 || y < 0)
     {
	dy = -dy;
	y += 2 * dy;

	evas_object_data_set(obj, "dy", dy);
     }

   evas_object_move(obj, x, y);

   return 1;
}

function key_up_cb(data, e, obj, event)
{
   switch (event.keyname)
     {
      case "b":
      case "Red":
      case "equal":
      case "Stop":
      case "Home":
      case "Escape":
      case "Start":
	 ecore_main_loop_quit();
	 break;
     }
}

function main()
{
   var bg;
   var obj;

   ecore_init();
   ecore_evas_init();

   ecore_animator_frametime_set(1 / 20);

   ee = ecore_evas_new(null, 0, 0, 720, 576, "name=Test;");

   var evas = ecore_evas_get(ee);

   evas_image_cache_set(evas, 10 * 1024 * 1024);
   evas_font_path_prepend(evas, FN);
   evas_font_cache_set(evas, 512 * 1024);

   obj = evas_object_rectangle_add(evas);
   evas_object_resize(obj, 720, 576);
   evas_object_color_set(obj, 0, 0, 0, 255);
   evas_object_show(obj);
   bg = obj;

   evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_UP, key_up_cb, null);
   evas_object_focus_set(bg, 1);

   obj = evas_object_rectangle_add(evas);
   evas_object_resize(obj, 250, 200);
   evas_object_color_set(obj, 128, 64, 0, 180);
   evas_object_move(obj, 50, 50);
   evas_object_show(obj);

   evas_object_data_set(obj, "dx", +20);
   evas_object_data_set(obj, "dy", +10);
   ecore_animator_add(anim_cb, obj);

   ecore_evas_show(ee);
   ecore_main_loop_begin();

   evas_object_del(obj);
   evas_object_del(bg);

   ecore_evas_free(ee);

   ecore_evas_shutdown();
   ecore_shutdown();
}

if (test)
  main();

Maintenant le même code vu par Cauldron :
elx.include('Cauldron.js');

var obj = new TRectangle(50, 50, 250, 200, 0x804000);
obj.dx = 20;
obj.dy = 10;
obj.onChange = function() {
  var x = obj.x + obj.dx;
  var y = obj.y + obj.dy;

  if (x + obj.width > screen.width || x < 0)
  {
	  obj.dx = - obj.dx;
 	  x += 2 * obj.dx;
  }

  if (y + obj.height > screen.height || y < 0)
  {
	  obj.dy = - obj.dy;
	  y += 2 * obj.dy;
  }

   obj.move(x, y);
}
var anim = new TAnimator(obj, 1/20);

screen.onKeyup = function(event) {
  switch (event.keyname)
  {
    case "b":
    case "Red":
    case "equal":
    case "Stop":
    case "Home":
    case "Escape":
    case "Start":	    
      screen.quit();
    break;
  }
}

screen.main();

En fait Cauldron utilise exactement les mêmes fonctions que le premier exemple, mais elles sont encapsulées dans des objets Javascript :)

Vous pouvez consulter le source de Cauldron.js.

En prime, vous y trouvez l'objet TClientSocket non encore disponible sur les Freebox qui exploite l'API réseau...voici un exemple d'utilisation qui interroge le service météo de Google:
elx.include('Cauldron.js');

var text = new TTextBlock(50, 110, 620, 480, 0x808080);
// utilisation directe de l'API evas sur le Handle de l'objet
   st = evas_textblock_style_new();
   evas_textblock_style_set(st, "DEFAULT='font=Vera,Kochi font_size=8 align=left color=#FFFFFF wrap=word'")
   evas_object_textblock_style_set(text.handle, st);
   evas_textblock_style_free(st);
   cursor = evas_object_textblock_cursor_new(text.handle);

var google = new TClientSocket();

google.onConnect = function(event) {
   var header = "GET http://www.google.com/ig/api?weather=Paris HTTP/1.1\r\n"
               +"Host: www.google.com\r\n\r\n";
   google.send(header);
};

google.onDisconnect = function(event) {
  elx.print("bye\n");
}

google.onData = function(event) {
  evas_textblock_cursor_text_append(cursor, event.data);
}

google.connect(ECORE_CON_REMOTE_TCP, 'www.google.com', 80);

screen.onKeyup = function(event) {
  google.close();
  screen.quit();
};


screen.main();

[1] ou Edje, mais cela sort du cadre de cette page

Date de dernière modification : 01/02/2010