Mercurial > code
comparison 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 |
comparison
equal
deleted
inserted
replaced
199:08eb7b00b950 | 200:617459270743 |
---|---|
1 /* | 1 /* |
2 * Lua.h -- Lua helpers and such | 2 * Luae.h -- Lua helpers and such |
3 * | 3 * |
4 * Copyright (c) 2013 David Demelier <markand@malikania.fr> | 4 * Copyright (c) 2013 David Demelier <markand@malikania.fr> |
5 * | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | 6 * Permission to use, copy, modify, and/or distribute this software for any |
7 * purpose with or without fee is hereby granted, provided that the above | 7 * purpose with or without fee is hereby granted, provided that the above |
21 | 21 |
22 #include <cassert> | 22 #include <cassert> |
23 #include <functional> | 23 #include <functional> |
24 #include <memory> | 24 #include <memory> |
25 #include <string> | 25 #include <string> |
26 #include <unordered_map> | |
26 #include <vector> | 27 #include <vector> |
27 | 28 |
28 #include <lua.hpp> | 29 #include <lua.hpp> |
30 | |
31 namespace malikania { | |
29 | 32 |
30 /* {{{ LuaeState */ | 33 /* {{{ LuaeState */ |
31 | 34 |
32 /** | 35 /** |
33 * @class LuaeState | 36 * @class LuaeState |
47 | 50 |
48 using Ptr = std::unique_ptr<lua_State, Deleter>; | 51 using Ptr = std::unique_ptr<lua_State, Deleter>; |
49 | 52 |
50 Ptr m_state; | 53 Ptr m_state; |
51 | 54 |
55 void initRegistry(); | |
56 | |
52 public: | 57 public: |
53 LuaeState(const LuaeState &) = delete; | 58 LuaeState(const LuaeState &) = delete; |
54 LuaeState &operator=(const LuaeState &) = delete; | 59 LuaeState &operator=(const LuaeState &) = delete; |
55 | 60 |
56 /** | 61 /** |
221 const std::string &name); | 226 const std::string &name); |
222 }; | 227 }; |
223 | 228 |
224 /* }}} */ | 229 /* }}} */ |
225 | 230 |
226 /* {{{ Luae */ | 231 /* {{{ LuaeClass */ |
227 | 232 |
228 /** | 233 /** |
229 * @class Luae | 234 * @class LuaeClass |
230 * @brief Add lot of convenience for Lua | 235 * @brief Support for object oriented programming between C++ and Lua |
231 * | 236 * |
232 * This class adds lot of functions for Lua and C++. | 237 * This class provides functions for passing and retrieving objects from C++ and |
233 */ | 238 * Lua. |
234 class Luae { | 239 */ |
235 public: | 240 class LuaeClass { |
236 /** | 241 public: |
237 * Preload a library, it will be added to package.preload so the | 242 using Methods = std::vector<luaL_Reg>; |
238 * user can successfully call require "name". In order to work, you need | 243 |
239 * to open luaopen_package and luaopen_base first. | 244 template <typename T> |
240 * | 245 using Ptr = std::shared_ptr<T>; |
241 * @param L the Lua state | 246 |
242 * @param name the module name | 247 struct Def { |
243 * @param func the opening library | 248 std::string name; //! metatable name |
244 * @see require | 249 Methods methods; //! methods |
245 */ | 250 Methods metamethods; //! metamethods |
246 static void preload(lua_State *L, | 251 const Def *parent; //! optional parent class |
247 const std::string &name, | 252 }; |
248 lua_CFunction func); | 253 |
249 | 254 static void create(lua_State *L, const Def &def); |
250 | |
251 /** | |
252 * Load a library just like it was loaded with require. | |
253 * | |
254 * @param L the Lua state | |
255 * @param name the module name | |
256 * @param func the function | |
257 * @param global store as global | |
258 */ | |
259 static void require(lua_State *L, | |
260 const std::string &name, | |
261 lua_CFunction func, | |
262 bool global); | |
263 | |
264 /** | |
265 * Initialize the registry for shared objects. | |
266 * | |
267 * @param L the Lua state | |
268 */ | |
269 static void initRegistry(lua_State *L); | |
270 | 255 |
271 /** | 256 /** |
272 * Push a shared object to Lua, it also push it to the "refs" | 257 * Push a shared object to Lua, it also push it to the "refs" |
273 * table with __mode = "v". That is if we need to push the object | 258 * table with __mode = "v". That is if we need to push the object |
274 * again we use the same reference so Lua get always the same | 259 * again we use the same reference so Lua get always the same |
280 * @param L the Lua state | 265 * @param L the Lua state |
281 * @param o the object to push | 266 * @param o the object to push |
282 * @param name the object metatable name | 267 * @param name the object metatable name |
283 */ | 268 */ |
284 template <typename T> | 269 template <typename T> |
285 static void pushShared(lua_State *L, | 270 static void push(lua_State *L, Ptr<T> o, const std::string &name) |
286 std::shared_ptr<T> o, | |
287 const std::string &name) | |
288 { | 271 { |
289 lua_getfield(L, LUA_REGISTRYINDEX, "refs"); | 272 lua_getfield(L, LUA_REGISTRYINDEX, "refs"); |
290 assert(lua_type(L, -1) == LUA_TTABLE); | 273 assert(lua_type(L, -1) == LUA_TTABLE); |
291 | 274 |
292 lua_rawgetp(L, -1, o.get()); | 275 lua_rawgetp(L, -1, o.get()); |
310 * @param index the object index | 293 * @param index the object index |
311 * @param meta the object metatable name | 294 * @param meta the object metatable name |
312 * @return the object | 295 * @return the object |
313 */ | 296 */ |
314 template <typename T> | 297 template <typename T> |
315 static std::shared_ptr<T> getShared(lua_State *L, int index, const char *meta) | 298 static Ptr<T> get(lua_State *L, int index, const char *meta) |
316 { | 299 { |
317 using Ptr = std::shared_ptr<T>; | 300 Ptr<T> *ptr = static_cast<Ptr<T> *>(luaL_checkudata(L, index, meta)); |
318 | |
319 Ptr *ptr = static_cast<Ptr *>(luaL_checkudata(L, index, meta)); | |
320 | 301 |
321 return *ptr; | 302 return *ptr; |
322 } | 303 } |
304 }; | |
305 | |
306 /* }}} */ | |
307 | |
308 /* {{{ LuaeEnum */ | |
309 | |
310 /** | |
311 * @class LuaeEnum | |
312 * @brief Binds and get enumeration | |
313 * | |
314 * Bind C/C++ enumeration as tables to Lua in the key-value form. Two | |
315 * methods push and get are also available for enumeration flags. | |
316 */ | |
317 class LuaeEnum { | |
318 public: | |
319 /** | |
320 * The definition of the enumeration | |
321 */ | |
322 using Def = std::unordered_map<std::string, int>; | |
323 | |
324 /** | |
325 * Bind the enumeration as a table into an existing table. | |
326 * | |
327 * @param L the Lua state | |
328 * @param def the definition | |
329 * @param index the table index | |
330 * @param name the field name to store the enumeration | |
331 */ | |
332 static void create(lua_State *L, | |
333 const Def &def, | |
334 int index, | |
335 const std::string &name); | |
336 | |
337 /** | |
338 * Push the value enumeration as a table to Lua. This is used | |
339 * as the OR replacement. | |
340 * | |
341 * @param L the Lua state | |
342 * @param def the definition | |
343 * @param value the value | |
344 */ | |
345 static void push(lua_State *L, const Def &def, int value); | |
346 | |
347 /** | |
348 * Get the enumeration from Lua. Raises an error if the | |
349 * value at the index is not a table. | |
350 * | |
351 * This is used as the OR replacement. | |
352 * | |
353 * @param L the Lua state | |
354 * @param index the value index | |
355 * @return the value | |
356 */ | |
357 static int get(lua_State *L, int index); | |
358 }; | |
359 | |
360 /* }}} */ | |
361 | |
362 /* {{{ Luae */ | |
363 | |
364 /** | |
365 * @class Luae | |
366 * @brief Add lot of convenience for Lua | |
367 * | |
368 * This class adds lot of functions for Lua and C++. | |
369 */ | |
370 class Luae { | |
371 public: | |
372 /** | |
373 * Preload a library, it will be added to package.preload so the | |
374 * user can successfully call require "name". In order to work, you need | |
375 * to open luaopen_package and luaopen_base first. | |
376 * | |
377 * @param L the Lua state | |
378 * @param name the module name | |
379 * @param func the opening library | |
380 * @see require | |
381 */ | |
382 static void preload(lua_State *L, | |
383 const std::string &name, | |
384 lua_CFunction func); | |
385 | |
386 | |
387 /** | |
388 * Load a library just like it was loaded with require. | |
389 * | |
390 * @param L the Lua state | |
391 * @param name the module name | |
392 * @param func the function | |
393 * @param global store as global | |
394 */ | |
395 static void require(lua_State *L, | |
396 const std::string &name, | |
397 lua_CFunction func, | |
398 bool global); | |
323 | 399 |
324 /** | 400 /** |
325 * Convert a new placement made object, without testing if its a real | 401 * Convert a new placement made object, without testing if its a real |
326 * object. | 402 * object. |
327 * | 403 * |
332 template<class T> | 408 template<class T> |
333 static T toType(lua_State *L, int idx) | 409 static T toType(lua_State *L, int idx) |
334 { | 410 { |
335 return reinterpret_cast<T>(lua_touserdata(L, idx)); | 411 return reinterpret_cast<T>(lua_touserdata(L, idx)); |
336 } | 412 } |
337 | |
338 /** | |
339 * Convert a class created with new placement. | |
340 * | |
341 * @param L the Lua state | |
342 * @param idx the value index | |
343 * @param metaname the metatable name | |
344 * @return the converted object | |
345 */ | |
346 template <typename T> | |
347 static T toType(lua_State *L, int idx, const char *metaname) | |
348 { | |
349 return reinterpret_cast<T>(luaL_checkudata(L, idx, metaname)); | |
350 } | |
351 }; | 413 }; |
352 | 414 |
353 /* }}} */ | 415 /* }}} */ |
354 | 416 |
355 #if !defined(NDEBUG) | 417 #if !defined(NDEBUG) |
369 #define LUAE_STACK_CHECKEQUALS(L) | 431 #define LUAE_STACK_CHECKEQUALS(L) |
370 #define LUAE_STACK_CHECKEND(L, cond) | 432 #define LUAE_STACK_CHECKEND(L, cond) |
371 | 433 |
372 #endif | 434 #endif |
373 | 435 |
436 } // !malikania | |
437 | |
374 void *operator new(size_t size, lua_State *L); | 438 void *operator new(size_t size, lua_State *L); |
375 | 439 |
376 void *operator new(size_t size, lua_State *L, const char *metaname); | 440 void *operator new(size_t size, lua_State *L, const char *metaname); |
377 | 441 |
378 void operator delete(void *ptr, lua_State *L); | 442 void operator delete(void *ptr, lua_State *L); |