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);