Integrando Lua & C++
                               Vinicius Jarina (viniciusjarina@gmail.com)

                                           @viniciusjarina



Saturday, September 17, 2011
Overview linguagem Lua

                               Vantagens de utilizar Lua

                               Entendendo melhor o Lua

                               Introdução a API C

                               Chamando funções Lua do C

                               Chamando funções C do Lua

                               Usando modelo OO

                               Utilizando geradores de código (toLua++)

Saturday, September 17, 2011
Lua

                                                             Normalized fraction of total hits (%)
                               Linguagem leve e rápida
                                                                                                          2
                               Portável (ANSI C)
                                                                                                         1.5
                               Facilmente embarcável
                                                                                                     1

                               Licença livre (MIT)                                                   0.5
                                                           2003
                                                                   2006
                               Projeto ativo e crescendo                      2009              0
                                                                                          2011/Q2




Saturday, September 17, 2011
Lua

                               Alguns exemplos de projetos que usam Lua

                                 SimCity / The Sims

                                 World of Warcraft

                                 Adobe Lightroom

                                 CryENGINE




Saturday, September 17, 2011
Vantagens
                               Mas afinal para que utilizar uma linguagem
                               script na minha aplicação?

                                 Isolamento

                                 Abstração

                                 Extensão e personalização




Saturday, September 17, 2011
Primeiros Passos
                               Exemplo código Lua:
                          local count = 10
                          -- comentário

                          g = 2*count

                          print("count = ", count, " g = ", g)




                                  http://www.lua.org/demo.html




Saturday, September 17, 2011
Tipos de dado
                               Lua suporta 8 tipos básico de dado: nil,
                               boolean, number, string, userdata, function,
                               thread, table

                               print(type(x))    -- nil (variáveis nascem nil)
                               x = "farandula"
                               print(type(x))    -- string
                               x = 10
                               print(type(x))    -- number
                               x = print
                               x(type(x))        -- function




Saturday, September 17, 2011
Tabelas

                               Tabelas são arrays associativos, podem ser
                               indexados por qualquer valor, exceto nil.

                        t = {} -- cria uma tabela, associa uma ref. a t
                        t2 = { x = 20, y = "foo" }

                        t["bar"] = "value"     -- sintáxe dicionário
                        t.campo = 10           -- sintáxe registro

                        print(t.bar)        -- value
                        print(t["campo"])   -- 10
                        print(t2.x, t2["y"])-- 20 foo




Saturday, September 17, 2011
Funções
                      Definindo funções:
                   function soma(a, b)         soma = function(a, b)
                       return a + b               return a + b
                   end                         end


                      Retornando múltiplos resultados:

                   function func(a, b)
                       return b, a, 10
                   end

                   x, y, z    = func(15, 20) -- x = 20, y = 15 , z = 10
                   p, q, r, s = func(2,1) -- p = 1,q = 2,r = 10, s = nil




Saturday, September 17, 2011
+Funções
                      Funções anônimas:

                   function inverso(f)
                      return function(x) return 1/(f(x)) end
                   end


                      Exemplo:

                   function square(x) return x*x end

                   f = inverso(square)

                   print(f(2), f(3)) -- 0.25   0.11111111111111




Saturday, September 17, 2011
Closures
                    Exemplo de closure (usando up-values):
                         function fibbo_gen()
                             local i = 0
                             local j = 1
                             return function()
                                 local k = i + j
                                i = j
                                 j = k
                                 return k
                             end
                         end
                    Exemplo:
                         f1 = fibbo_gen()
                         print(f1()) -- 1
                         print(f1()) -- 2
                         print(f1()) -- 3
                         print(f1()) -- 5


Saturday, September 17, 2011
Metatabelas
                    Permitem alterar comportamento através de
                    metametodos ex: __tostring, __index,
                    __add, __eq, etc...
                         t = {}
                         mt = { __index = function(table, key)
                                             return "fixo"
                                          end
                         }

                         setmetatable(t, mt)

                      Exemplo:
                         print(t[1]) -- fixo (não encontrou 1, invoca __index)
                         t[1] = "casa"
                         print(t[1]) -- casa



Saturday, September 17, 2011
Objetos
                   Usando tabela com cara de objeto:
                t = { }
                t.func   = function (a, ...)
                               print("func:", a, ...)
                           end
                t.membro = 10
                function t:getmembro() return self.membro end
                -- t.getmembro = function(self) return self.membro end

                    Exemplo:
                 t.func(10)      -- func:! 10
                 t:func(11)      -- func:! table: 0x256a3f0! 11
                 t.func(t, 12)   -- func:! table: 0x256a3f0! 12

                 print(t:getmembro())   -- 10




Saturday, September 17, 2011
Módulos
                   Definindo um módulo:
               module (..., package.seeall) -- size.lua
               function new (x, y)
                return {x = x, y = y}
               end

               function area(s)
                  return s.x * s.y
               end

                    Usando módulo:
               require ‘size’

               local s1 = size.new(10,20)

               print(size.area(s1)) -- 200




Saturday, September 17, 2011
Compilação Dinâmica
                   Compilando uma string:
               i = 10 -- global i
               f = loadstring(“i = i + 10; print(i)”)
               g = function() i = i + 10; print(i) end

               f() -- 20

                Compilando uma arquivo Lua:
           -- file_foo.lua
           function foo() print(“inside foo”) end


          f = loadfile(“file_foo.lua”) -- compilou foo mas não executou
          print(foo)              -- nil, pois foo ainda nao existe
          f()                     -- definiu foo
          foo()                   -- inside foo



Saturday, September 17, 2011
Tratando Erros
                     Usando pcall e error
                i = 101
                status, err = pcall( function() -- pcall (try)
                    i = i + 1
                    if(i > 100) then
                      error(“i maior que 100”) -- error (throw)
                    end
                    print(“i = “,i ) -- i será sempre menor que 100
                  end)
                if not status then -- (catch, se pcall false, houve erro)
                  print(err)       -- i maior que 100
                end




Saturday, September 17, 2011
Overview linguagem Lua

                               Vantagens de utilizar Lua

                               Entendendo melhor o Lua

                               Introdução a API C

                               Chamando funções Lua do C

                               Chamando funções C do Lua

                               Utilizando geradores de código (toLua++)


Saturday, September 17, 2011
API C
                     Funções API Lua lua_* e luaL_*
                #include “lua.h”     /* header principal do Lua */
                #include “lauxlib.h” /* header lib auxiliar do lua (luaL) */
                #include “lualib.h” /* header para usar std libs do lua */

                int main() {
                  lua_State * L = luaL_newstate(); /* */
                  luaL_openlibs(L); /* carrega libs std (string, table, etc*/
                  const char * szScript = “ i = 0 ; function test(a) n“
                                           “ return 2*a + 1 n end    n“
                                           “ print(test(i))           n”
                  int nErr = luaL_loadstring(L,szScript) ||
                             lua_pcall(L, 0, 0, 0);
                  if(nErr) {
                    printf(lua_tostring(L, -1));
                    lua_pop(L, 1);
                  }
                  lua_close(L);
                  return 0;
                }

Saturday, September 17, 2011
Pilha
                      Empilhando e desempilhando valores

                lua_pushboolean(L, 1);              6        nil
                lua_pushnumber(L, 10);
                lua_pushnil(L);                     5        nil
                lua_pushstring(L, "hello");
                                                    4      “hello”
                lua_pushvalue(L, -4);
                lua_replace(L, 3);
                lua_settop(L, 6);
                                                    3        nil
                lua_remove(L, -3);
                lua_settop(L, -5);              -5 2         10
                                                -5
                                                -4
                                                -3
                                                -2 1
                                                -1
                                                -6          true




Saturday, September 17, 2011
Chamando funções Lua
                     Chamando uma função global:
                         -- file_modulo.lua
                         function modulo(real, imag)
                             return math.sqrt(real*real + imag*imag)
                         end

               luaL_dofile(“file_modulo.lua”); // compila e executa o
                                               // arquivo file_modulo.lua
               double real = 3;
               double imag = 5;

               lua_getglobal(L,“modulo”); // empilha a global modulo
               lua_pushnumber(L, real);   // empilha param 1 (real)
               lua_pushnumber(L, imag);   // empilha param 2 (imag)

               lua_pcall(L, 2, 1, 0); // chama modulo(2 entradas, 1 saída)

               double mod = lua_tonumber(L, -1); // mod == 5

               lua_pop(L, 1);
Saturday, September 17, 2011
Chamando funções C
                Registrando função C
          static int pow_l(lua_State *L) {
               double a = luaL_checknumber (L, 1);
               double b = luaL_checknumber (L, 2);
               lua_pushnumber (L, pow (a, b));
               return 1;
          }
          static const struct luaL_Reg mylib [] = {
            {"pow", pow_l},
            {NULL, NULL}
          };

          int luaopen_mylib (lua_State *L) {
             luaL_register (L, "mylib", mylib);
             return 1;
          }

                        print(“chamando mylib.pow”, mylib.pow(3))
                        -- chamando mylib.pow   9



Saturday, September 17, 2011
Usando toLua++
             Exportando uma classe:
          class car { // tolua_export
                   int m_speed;
              public:
          ! !     //tolua_begin                  // arquivo: car.pkg
                  car();                         $cfile "car.h"
                  ~ car();
                  void set_speed(int speed);
                  int get_speed();
          }; // tolua_end


             #>toluapp -o tolua_car.cpp -H tolua_car.h -n car car.pkg

        -- cria um novo carro, e seta velocidade
        local c1 = car:new_local("McQueen")
        c1:set_speed(10)
        print("Carro: " .. c1:name() .. " velocidade:" .. c1:speed());
        -- Carro: McQueen velocidade: 10




Saturday, September 17, 2011
DEMO
Saturday, September 17, 2011
Dúvidas?

Saturday, September 17, 2011
Fim
       http://lua-users.org/wiki/
       Programming in Lua, 2Nd Edition   @viniciusjarina
       http://www.lua.org/docs.html      viniciusjarina@gmail.com

Saturday, September 17, 2011

Lua & C++

  • 1.
    Integrando Lua &C++ Vinicius Jarina (viniciusjarina@gmail.com) @viniciusjarina Saturday, September 17, 2011
  • 2.
    Overview linguagem Lua Vantagens de utilizar Lua Entendendo melhor o Lua Introdução a API C Chamando funções Lua do C Chamando funções C do Lua Usando modelo OO Utilizando geradores de código (toLua++) Saturday, September 17, 2011
  • 3.
    Lua Normalized fraction of total hits (%) Linguagem leve e rápida 2 Portável (ANSI C) 1.5 Facilmente embarcável 1 Licença livre (MIT) 0.5 2003 2006 Projeto ativo e crescendo 2009 0 2011/Q2 Saturday, September 17, 2011
  • 4.
    Lua Alguns exemplos de projetos que usam Lua SimCity / The Sims World of Warcraft Adobe Lightroom CryENGINE Saturday, September 17, 2011
  • 5.
    Vantagens Mas afinal para que utilizar uma linguagem script na minha aplicação? Isolamento Abstração Extensão e personalização Saturday, September 17, 2011
  • 6.
    Primeiros Passos Exemplo código Lua: local count = 10 -- comentário g = 2*count print("count = ", count, " g = ", g) http://www.lua.org/demo.html Saturday, September 17, 2011
  • 7.
    Tipos de dado Lua suporta 8 tipos básico de dado: nil, boolean, number, string, userdata, function, thread, table print(type(x)) -- nil (variáveis nascem nil) x = "farandula" print(type(x)) -- string x = 10 print(type(x)) -- number x = print x(type(x)) -- function Saturday, September 17, 2011
  • 8.
    Tabelas Tabelas são arrays associativos, podem ser indexados por qualquer valor, exceto nil. t = {} -- cria uma tabela, associa uma ref. a t t2 = { x = 20, y = "foo" } t["bar"] = "value" -- sintáxe dicionário t.campo = 10 -- sintáxe registro print(t.bar) -- value print(t["campo"]) -- 10 print(t2.x, t2["y"])-- 20 foo Saturday, September 17, 2011
  • 9.
    Funções Definindo funções: function soma(a, b) soma = function(a, b) return a + b return a + b end end Retornando múltiplos resultados: function func(a, b) return b, a, 10 end x, y, z = func(15, 20) -- x = 20, y = 15 , z = 10 p, q, r, s = func(2,1) -- p = 1,q = 2,r = 10, s = nil Saturday, September 17, 2011
  • 10.
    +Funções Funções anônimas: function inverso(f) return function(x) return 1/(f(x)) end end Exemplo: function square(x) return x*x end f = inverso(square) print(f(2), f(3)) -- 0.25 0.11111111111111 Saturday, September 17, 2011
  • 11.
    Closures Exemplo de closure (usando up-values): function fibbo_gen() local i = 0 local j = 1 return function() local k = i + j i = j j = k return k end end Exemplo: f1 = fibbo_gen() print(f1()) -- 1 print(f1()) -- 2 print(f1()) -- 3 print(f1()) -- 5 Saturday, September 17, 2011
  • 12.
    Metatabelas Permitem alterar comportamento através de metametodos ex: __tostring, __index, __add, __eq, etc... t = {} mt = { __index = function(table, key) return "fixo" end } setmetatable(t, mt) Exemplo: print(t[1]) -- fixo (não encontrou 1, invoca __index) t[1] = "casa" print(t[1]) -- casa Saturday, September 17, 2011
  • 13.
    Objetos Usando tabela com cara de objeto: t = { } t.func = function (a, ...) print("func:", a, ...) end t.membro = 10 function t:getmembro() return self.membro end -- t.getmembro = function(self) return self.membro end Exemplo: t.func(10) -- func:! 10 t:func(11) -- func:! table: 0x256a3f0! 11 t.func(t, 12) -- func:! table: 0x256a3f0! 12 print(t:getmembro()) -- 10 Saturday, September 17, 2011
  • 14.
    Módulos Definindo um módulo: module (..., package.seeall) -- size.lua function new (x, y) return {x = x, y = y} end function area(s) return s.x * s.y end Usando módulo: require ‘size’ local s1 = size.new(10,20) print(size.area(s1)) -- 200 Saturday, September 17, 2011
  • 15.
    Compilação Dinâmica Compilando uma string: i = 10 -- global i f = loadstring(“i = i + 10; print(i)”) g = function() i = i + 10; print(i) end f() -- 20 Compilando uma arquivo Lua: -- file_foo.lua function foo() print(“inside foo”) end f = loadfile(“file_foo.lua”) -- compilou foo mas não executou print(foo) -- nil, pois foo ainda nao existe f() -- definiu foo foo() -- inside foo Saturday, September 17, 2011
  • 16.
    Tratando Erros Usando pcall e error i = 101 status, err = pcall( function() -- pcall (try) i = i + 1 if(i > 100) then error(“i maior que 100”) -- error (throw) end print(“i = “,i ) -- i será sempre menor que 100 end) if not status then -- (catch, se pcall false, houve erro) print(err) -- i maior que 100 end Saturday, September 17, 2011
  • 17.
    Overview linguagem Lua Vantagens de utilizar Lua Entendendo melhor o Lua Introdução a API C Chamando funções Lua do C Chamando funções C do Lua Utilizando geradores de código (toLua++) Saturday, September 17, 2011
  • 18.
    API C Funções API Lua lua_* e luaL_* #include “lua.h” /* header principal do Lua */ #include “lauxlib.h” /* header lib auxiliar do lua (luaL) */ #include “lualib.h” /* header para usar std libs do lua */ int main() { lua_State * L = luaL_newstate(); /* */ luaL_openlibs(L); /* carrega libs std (string, table, etc*/ const char * szScript = “ i = 0 ; function test(a) n“ “ return 2*a + 1 n end n“ “ print(test(i)) n” int nErr = luaL_loadstring(L,szScript) || lua_pcall(L, 0, 0, 0); if(nErr) { printf(lua_tostring(L, -1)); lua_pop(L, 1); } lua_close(L); return 0; } Saturday, September 17, 2011
  • 19.
    Pilha Empilhando e desempilhando valores lua_pushboolean(L, 1); 6 nil lua_pushnumber(L, 10); lua_pushnil(L); 5 nil lua_pushstring(L, "hello"); 4 “hello” lua_pushvalue(L, -4); lua_replace(L, 3); lua_settop(L, 6); 3 nil lua_remove(L, -3); lua_settop(L, -5); -5 2 10 -5 -4 -3 -2 1 -1 -6 true Saturday, September 17, 2011
  • 20.
    Chamando funções Lua Chamando uma função global: -- file_modulo.lua function modulo(real, imag) return math.sqrt(real*real + imag*imag) end luaL_dofile(“file_modulo.lua”); // compila e executa o // arquivo file_modulo.lua double real = 3; double imag = 5; lua_getglobal(L,“modulo”); // empilha a global modulo lua_pushnumber(L, real); // empilha param 1 (real) lua_pushnumber(L, imag); // empilha param 2 (imag) lua_pcall(L, 2, 1, 0); // chama modulo(2 entradas, 1 saída) double mod = lua_tonumber(L, -1); // mod == 5 lua_pop(L, 1); Saturday, September 17, 2011
  • 21.
    Chamando funções C Registrando função C static int pow_l(lua_State *L) { double a = luaL_checknumber (L, 1); double b = luaL_checknumber (L, 2); lua_pushnumber (L, pow (a, b)); return 1; } static const struct luaL_Reg mylib [] = { {"pow", pow_l}, {NULL, NULL} }; int luaopen_mylib (lua_State *L) { luaL_register (L, "mylib", mylib); return 1; } print(“chamando mylib.pow”, mylib.pow(3)) -- chamando mylib.pow 9 Saturday, September 17, 2011
  • 22.
    Usando toLua++ Exportando uma classe: class car { // tolua_export int m_speed; public: ! ! //tolua_begin // arquivo: car.pkg car(); $cfile "car.h" ~ car(); void set_speed(int speed); int get_speed(); }; // tolua_end #>toluapp -o tolua_car.cpp -H tolua_car.h -n car car.pkg -- cria um novo carro, e seta velocidade local c1 = car:new_local("McQueen") c1:set_speed(10) print("Carro: " .. c1:name() .. " velocidade:" .. c1:speed()); -- Carro: McQueen velocidade: 10 Saturday, September 17, 2011
  • 23.
  • 24.
  • 25.
    Fim http://lua-users.org/wiki/ Programming in Lua, 2Nd Edition @viniciusjarina http://www.lua.org/docs.html viniciusjarina@gmail.com Saturday, September 17, 2011