Mercurial > code
diff C++/Luae.h @ 200:617459270743
Add XML parser
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 28 Dec 2013 11:16:11 +0100 |
parents | 9fc5f917872b |
children | 8ee4a34e166c |
line wrap: on
line diff
--- a/C++/Luae.h Sat Nov 30 09:58:48 2013 +0100 +++ b/C++/Luae.h Sat Dec 28 11:16:11 2013 +0100 @@ -1,5 +1,5 @@ /* - * Lua.h -- Lua helpers and such + * Luae.h -- Lua helpers and such * * Copyright (c) 2013 David Demelier <markand@malikania.fr> * @@ -23,10 +23,13 @@ #include <functional> #include <memory> #include <string> +#include <unordered_map> #include <vector> #include <lua.hpp> +namespace malikania { + /* {{{ LuaeState */ /** @@ -49,6 +52,8 @@ Ptr m_state; + void initRegistry(); + public: LuaeState(const LuaeState &) = delete; LuaeState &operator=(const LuaeState &) = delete; @@ -223,6 +228,137 @@ /* }}} */ +/* {{{ LuaeClass */ + +/** + * @class LuaeClass + * @brief Support for object oriented programming between C++ and Lua + * + * This class provides functions for passing and retrieving objects from C++ and + * Lua. + */ +class LuaeClass { +public: + using Methods = std::vector<luaL_Reg>; + + template <typename T> + using Ptr = std::shared_ptr<T>; + + struct Def { + std::string name; //! metatable name + Methods methods; //! methods + Methods metamethods; //! metamethods + const Def *parent; //! optional parent class + }; + + static void create(lua_State *L, const Def &def); + + /** + * Push a shared object to Lua, it also push it to the "refs" + * table with __mode = "v". That is if we need to push the object + * again we use the same reference so Lua get always the same + * userdata and gain the following benefits: + * + * 1. The user can use the userdata as table key + * 2. A performance gain thanks to less allocations + * + * @param L the Lua state + * @param o the object to push + * @param name the object metatable name + */ + template <typename T> + static void push(lua_State *L, Ptr<T> o, const std::string &name) + { + lua_getfield(L, LUA_REGISTRYINDEX, "refs"); + assert(lua_type(L, -1) == LUA_TTABLE); + + lua_rawgetp(L, -1, o.get()); + + if (lua_type(L, -1) == LUA_TNIL) { + lua_pop(L, 1); + + new (L, name.c_str()) std::shared_ptr<T>(o); + + lua_pushvalue(L, -1); + lua_rawsetp(L, -3, o.get()); + } + + lua_replace(L, -2); + } + + /** + * Get an object from Lua that was previously push with pushShared. + * + * @param L the Lua state + * @param index the object index + * @param meta the object metatable name + * @return the object + */ + template <typename T> + static Ptr<T> get(lua_State *L, int index, const char *meta) + { + Ptr<T> *ptr = static_cast<Ptr<T> *>(luaL_checkudata(L, index, meta)); + + return *ptr; + } +}; + +/* }}} */ + +/* {{{ LuaeEnum */ + +/** + * @class LuaeEnum + * @brief Binds and get enumeration + * + * Bind C/C++ enumeration as tables to Lua in the key-value form. Two + * methods push and get are also available for enumeration flags. + */ +class LuaeEnum { +public: + /** + * The definition of the enumeration + */ + using Def = std::unordered_map<std::string, int>; + + /** + * Bind the enumeration as a table into an existing table. + * + * @param L the Lua state + * @param def the definition + * @param index the table index + * @param name the field name to store the enumeration + */ + static void create(lua_State *L, + const Def &def, + int index, + const std::string &name); + + /** + * Push the value enumeration as a table to Lua. This is used + * as the OR replacement. + * + * @param L the Lua state + * @param def the definition + * @param value the value + */ + static void push(lua_State *L, const Def &def, int value); + + /** + * Get the enumeration from Lua. Raises an error if the + * value at the index is not a table. + * + * This is used as the OR replacement. + * + * @param L the Lua state + * @param index the value index + * @return the value + */ + static int get(lua_State *L, int index); +}; + +/* }}} */ + /* {{{ Luae */ /** @@ -262,66 +398,6 @@ bool global); /** - * Initialize the registry for shared objects. - * - * @param L the Lua state - */ - static void initRegistry(lua_State *L); - - /** - * Push a shared object to Lua, it also push it to the "refs" - * table with __mode = "v". That is if we need to push the object - * again we use the same reference so Lua get always the same - * userdata and gain the following benefits: - * - * 1. The user can use the userdata as table key - * 2. A performance gain thanks to less allocations - * - * @param L the Lua state - * @param o the object to push - * @param name the object metatable name - */ - template <typename T> - static void pushShared(lua_State *L, - std::shared_ptr<T> o, - const std::string &name) - { - lua_getfield(L, LUA_REGISTRYINDEX, "refs"); - assert(lua_type(L, -1) == LUA_TTABLE); - - lua_rawgetp(L, -1, o.get()); - - if (lua_type(L, -1) == LUA_TNIL) { - lua_pop(L, 1); - - new (L, name.c_str()) std::shared_ptr<T>(o); - - lua_pushvalue(L, -1); - lua_rawsetp(L, -3, o.get()); - } - - lua_replace(L, -2); - } - - /** - * Get an object from Lua that was previously push with pushShared. - * - * @param L the Lua state - * @param index the object index - * @param meta the object metatable name - * @return the object - */ - template <typename T> - static std::shared_ptr<T> getShared(lua_State *L, int index, const char *meta) - { - using Ptr = std::shared_ptr<T>; - - Ptr *ptr = static_cast<Ptr *>(luaL_checkudata(L, index, meta)); - - return *ptr; - } - - /** * Convert a new placement made object, without testing if its a real * object. * @@ -334,20 +410,6 @@ { return reinterpret_cast<T>(lua_touserdata(L, idx)); } - - /** - * Convert a class created with new placement. - * - * @param L the Lua state - * @param idx the value index - * @param metaname the metatable name - * @return the converted object - */ - template <typename T> - static T toType(lua_State *L, int idx, const char *metaname) - { - return reinterpret_cast<T>(luaL_checkudata(L, idx, metaname)); - } }; /* }}} */ @@ -371,6 +433,8 @@ #endif +} // !malikania + void *operator new(size_t size, lua_State *L); void *operator new(size_t size, lua_State *L, const char *metaname);