lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Great, but some samples on how to use it properly would be nice! :-)


----- Mensagem original ----
De: Panagiotis Vossos <pavossos@gmail.com>
Para: Lua list <lua@bazar2.conectiva.com.br>
Enviadas: Terça-feira, 16 de Outubro de 2007 20:12:08
Assunto: user data with pointer template

I have written the following template to help me when wrapping C/C++
pointers in lua userdata.  Any comments or ideas?

regards,
panagiotis.

/*
  User Data With Pointer AUXiliary template.

  Mostly inspired by `User Data With Pointer Example' on the lua wiki,
  provides definitions for various almost-always-used functions.  The
  second argument is a trait that has only one method `name', that
  returns a string for the wrapped type.  Note that `alloc' does not
  allocate anything (we do not know if the wrapped type has a default
  constructor), just sets up the passed pointer on the lua stack.
*/

#ifndef PAVUDWPAUX_HPP
#define PAVUDWPAUX_HPP

#include <cassert>
#include <string>
#include <cstdio>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

namespace pav {

    template<typename T, typename Tr>
    struct udwpaux
    {
        typedef T* ptr;
        typedef T** pptr;

        static int setup(lua_State *L, const luaL_reg *m, const luaL_reg *f) {
            const std::string name = Tr::name();
            luaL_newmetatable(L, name.c_str());
            lua_pushstring(L, "__index");
            lua_pushvalue(L, -2);
            lua_settable(L, -3);
            luaL_register(L, NULL, m);
            luaL_register(L, name.c_str(), f);
            return 1;
        }

        static ptr check(lua_State *L, int index) {
            const std::string name = Tr::name();
            luaL_checktype(L, index, LUA_TUSERDATA);
            pptr v = (pptr) luaL_checkudata(L, index, name.c_str());
            if (!v) luaL_typerror(L, index, name.c_str());
            ptr p = *v;
            if (!p) {
                char buf[100];
                std::sprintf(buf, "NULL %s", name.c_str());
                luaL_error(L, buf);
            }
            return p;
        }

        static pptr alloc(lua_State *L, ptr p) {
            const std::string name = Tr::name();
            pptr v = (pptr) lua_newuserdata(L, sizeof(ptr));
            *v = p;
            luaL_getmetatable(L, name.c_str());
            lua_setmetatable(L, -2);
#ifdef SHOWNEWDELETE
            std::printf("NEW %s [%p]\n", name.c_str(), v);
#endif
            return v;
        }

        static int gc(lua_State *L) {
            const std::string name = Tr::name();
            pptr p = (pptr) lua_touserdata(L, 1);
            if (!p) luaL_typerror(L, 1, name.c_str());
            assert(*p);
            delete *p;
#ifdef SHOWNEWDELETE
            std::printf("DELETE %s [%p]!\n", name.c_str(), p);
#endif
            return 0;
        }
    };

}

#endif // PAVUDWPAUX_HPP


      Abra sua conta no Yahoo! Mail, o único sem limite de espaço para armazenamento!
http://br.mail.yahoo.com/