lundi 26 avril 2010

Développement modulaire en C++: Fichier de configuration LUA (suite)

Si vous avez suivi mon premier article sur le sujet, Développement modulaire en C++: Fichier de configuration LUA, vous avez une application qui possède un fichier de configuration plus évolué que la moyenne.

Mais laissons maintenant à notre utilisateur des possibilités bien plus grandes, et pour ce faire je vous propose d'appeler une fonction LUA à chaque ligne afin de récupérer les texte à afficher ainsi qu'une autre fonction à l'initialisation.

Voici le code C++ modifié :
// Librairies LUA
extern "C" {
 #include <lauxlib.h>
 #include <lualib.h>
}
#include <stdlib.h>
#include <stdio.h>
#include <string>

using namespace std;

int main(void)
{
    lua_State *L;
    string text = "Hello world\n";
    int nbLines = 5;
    
    /*
     * Instance de l'interface LUA
     */
    L = luaL_newstate();
    luaL_openlibs(L); /* Chargement des libraries standard */
    if ( luaL_dofile(L, "configuration.lua") ) {  /* Chargement du fichier */
        fprintf(stderr, "Impossible de charger le fichier de configuration: %s\n", lua_tostring(L, -1));
        exit(1);
    }
 
    // Execute la fonction d'init
    lua_getfield(L, LUA_GLOBALSINDEX, "onstart");
    if (lua_pcall(L, 0, LUA_MULTRET, 0)!=0) {
     printf("Impossible de charger la fonction onstart : %s", (char*)lua_tostring(L,-1));
    }

 // recupere la variable nbLines
    lua_settop(L,0);
 lua_getfield(L, LUA_GLOBALSINDEX, "NB_LINES");
 if (lua_isnumber(L, -1)) {
  nbLines = lua_tonumber(L, -1);
 }
 lua_pop(L, 1);

 for (int i=0; i<nblines; i++)="" {
     lua_getfield(L, LUA_GLOBALSINDEX, "gettext");
     if (lua_pcall(L, 0, LUA_MULTRET, 0)!=0) {
      printf("Impossible de charger la fonction gettext : %s", (char*)lua_tostring(L,-1));
     }
     if ( lua_tostring(L, -1) != 0 ) {
      text = lua_tostring(L, -1);
      lua_pop(L, 1);  /* Supprime de la pile la valeur retournée */
     }
  printf(text.c_str());
 }

    return 0;
}



Vous pouvez utiliser le fichier de configuration suivant :
NB_LINES = 2

-- Fonction d'initialisation
function onstart() end

-- Retourne la bonne ligne
function gettext() return "Hello World [MODIFIE]\n" end



Voici un autre fichier qui transforme votre "Hello world multiligne" en lecteur de flux RSS (cet exemple nécessite d'avoir curl installé sur sa machine) :
NB_LINES = 0
RSS_URL = "http://www.marcbuils.fr/feed/" -- marcbuils.fr
-- "http://www.marcbuils.fr/feed/" -- marcbuils.fr
-- "http://www.monprogrammetele.tv/blog/feed/" -- Programme TV du soir
-- "http://www.lua.org/news.rss" -- NEWS LUA

function onstart()
 _TEXT = {}

 -- Enregistre le fichier en local
 os.execute("curl " .. RSS_URL .. " > tmp.rss 2> /dev/null")

 -- Prse le fichier
 for line in io.lines("tmp.rss") do
  if string.find(line, "") or string.find(line, "") then
   NB_LINES = NB_LINES+1
   _TEXT[NB_LINES] = "\n"
  end
  if string.find(line, "title>") then
   _TEXT[NB_LINES] = _TEXT[NB_LINES] .. string.sub(line, string.find(line, ">")+1, -9) .. "\n"
  end
  if string.find(line, "link>") then
   _TEXT[NB_LINES] = _TEXT[NB_LINES] .. string.sub(line, string.find(line, ">")+1, -8) .. "\n"
  end
 end
end

-- Retourne la bonne ligne
_I = 0
function gettext()
 _I = _I+1
 return _TEXT[_I]
end



Vous avez maintenant une application qui déporte ses limitations au niveau de l'imagination de ses utilisateurs (qui peut aller très loin...)

Téléchargement des sources (+ binaires Mac osX)

Aucun commentaire:

Enregistrer un commentaire