您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

732 行
28 KiB

  1. /*
  2. * Copyright (c) 2010-2013 Alexander Ames
  3. * Alexander.Ames@gmail.com
  4. * See Copyright Notice at the end of this file
  5. */
  6. // API Summary:
  7. //
  8. // LuaWrapper is a library designed to help bridge the gab between Lua and
  9. // C++. It is designed to be small (a single header file), simple, fast,
  10. // and typesafe. It has no external dependencies, and does not need to be
  11. // precompiled; the header can simply be dropped into a project and used
  12. // immediately. It even supports class inheritance to a certain degree. Objects
  13. // can be created in either Lua or C++, and passed back and forth.
  14. //
  15. // The main functions of interest are the following:
  16. // luaW_is<T>
  17. // luaW_to<T>
  18. // luaW_check<T>
  19. // luaW_push<T>
  20. // luaW_register<T>
  21. // luaW_setfuncs<T>
  22. // luaW_extend<T, U>
  23. // luaW_hold<T>
  24. // luaW_release<T>
  25. //
  26. // These functions allow you to manipulate arbitrary classes just like you
  27. // would the primitive types (e.g. numbers or strings). If you are familiar
  28. // with the normal Lua API the behavior of these functions should be very
  29. // intuative.
  30. //
  31. // For more information see the README and the comments below
  32. #ifndef LUA_WRAPPER_H_
  33. #define LUA_WRAPPER_H_
  34. // If you are linking against Lua compiled in C++, define LUAW_NO_EXTERN_C
  35. #ifndef LUAW_NO_EXTERN_C
  36. extern "C"
  37. {
  38. #endif // LUAW_NO_EXTERN_C
  39. #include "lua.h"
  40. #include "lauxlib.h"
  41. #ifndef LUAW_NO_EXTERN_C
  42. }
  43. #endif // LUAW_NO_EXTERN_C
  44. #define LUAW_POSTCTOR_KEY "__postctor"
  45. #define LUAW_EXTENDS_KEY "__extends"
  46. #define LUAW_STORAGE_KEY "storage"
  47. #define LUAW_CACHE_KEY "cache"
  48. #define LUAW_CACHE_METATABLE_KEY "cachemetatable"
  49. #define LUAW_HOLDS_KEY "holds"
  50. #define LUAW_WRAPPER_KEY "LuaWrapper"
  51. // A simple utility function to adjust a given index
  52. // Useful for when a parameter index needs to be adjusted
  53. // after pushing or popping things off the stack
  54. inline int luaW_correctindex(lua_State* L, int index, int correction)
  55. {
  56. return index < 0 ? index - correction : index;
  57. }
  58. // These are the default allocator and deallocator. If you would prefer an
  59. // alternative option, you may select a different function when registering
  60. // your class.
  61. template <typename T>
  62. T* luaW_defaultallocator(lua_State*)
  63. {
  64. return new T();
  65. }
  66. template <typename T>
  67. void luaW_defaultdeallocator(lua_State*, T* obj)
  68. {
  69. delete obj;
  70. }
  71. // The identifier function is responsible for pushing a value unique to each
  72. // object on to the stack. Most of the time, this can simply be the address
  73. // of the pointer, but sometimes that is not adaquate. For example, if you
  74. // are using shared_ptr you would need to push the address of the object the
  75. // shared_ptr represents, rather than the address of the shared_ptr itself.
  76. template <typename T>
  77. void luaW_defaultidentifier(lua_State* L, T* obj)
  78. {
  79. lua_pushlightuserdata(L, obj);
  80. }
  81. // This class is what is used by LuaWrapper to contain the userdata. data
  82. // stores a pointer to the object itself, and cast is used to cast toward the
  83. // base class if there is one and it is necessary. Rather than use RTTI and
  84. // typid to compare types, I use the clever trick of using the cast to compare
  85. // types. Because there is at most one cast per type, I can use it to identify
  86. // when and object is the type I want. This is only used internally.
  87. struct luaW_Userdata
  88. {
  89. luaW_Userdata(void* vptr = NULL, luaW_Userdata(*udcast)(const luaW_Userdata&) = NULL)
  90. : data(vptr), cast(udcast) {}
  91. void* data;
  92. luaW_Userdata(*cast)(const luaW_Userdata&);
  93. };
  94. // This class cannot actually to be instantiated. It is used only hold the
  95. // table name and other information.
  96. template <typename T>
  97. class LuaWrapper
  98. {
  99. public:
  100. static const char* classname;
  101. static void(*identifier)(lua_State*, T*);
  102. static T* (*allocator)(lua_State*);
  103. static void(*deallocator)(lua_State*, T*);
  104. static luaW_Userdata(*cast)(const luaW_Userdata&);
  105. static void(*postconstructorrecurse)(lua_State* L, int numargs);
  106. private:
  107. LuaWrapper();
  108. };
  109. template <typename T> const char* LuaWrapper<T>::classname;
  110. template <typename T> void(*LuaWrapper<T>::identifier)(lua_State*, T*);
  111. template <typename T> T* (*LuaWrapper<T>::allocator)(lua_State*);
  112. template <typename T> void(*LuaWrapper<T>::deallocator)(lua_State*, T*);
  113. template <typename T> luaW_Userdata(*LuaWrapper<T>::cast)(const luaW_Userdata&);
  114. template <typename T> void(*LuaWrapper<T>::postconstructorrecurse)(lua_State* L, int numargs);
  115. // Cast from an object of type T to an object of type U. This template
  116. // function is instantiated by calling luaW_extend<T, U>(L). This is only used
  117. // internally.
  118. template <typename T, typename U>
  119. luaW_Userdata luaW_cast(const luaW_Userdata& obj)
  120. {
  121. return luaW_Userdata(static_cast<U*>(static_cast<T*>(obj.data)), LuaWrapper<U>::cast);
  122. }
  123. template <typename T, typename U>
  124. void luaW_identify(lua_State* L, T* obj)
  125. {
  126. LuaWrapper<U>::identifier(L, static_cast<U*>(obj));
  127. }
  128. template <typename T>
  129. inline void luaW_wrapperfield(lua_State* L, const char* field)
  130. {
  131. lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
  132. lua_getfield(L, -1, field); // ... LuaWrapper LuaWrapper.field
  133. lua_getfield(L, -1, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.field LuaWrapper.field.class
  134. lua_replace(L, -3); // ... LuaWrapper.field.class LuaWrapper.field
  135. lua_pop(L, 1); // ... LuaWrapper.field.class
  136. }
  137. // Analogous to lua_is(boolean|string|*)
  138. //
  139. // Returns 1 if the value at the given acceptable index is of type T (or if
  140. // strict is false, convertable to type T) and 0 otherwise.
  141. template <typename T>
  142. bool luaW_is(lua_State *L, int index, bool strict = false)
  143. {
  144. bool equal = false;// lua_isnil(L, index);
  145. if (!equal && lua_isuserdata(L, index) && lua_getmetatable(L, index))
  146. {
  147. // ... ud ... udmt
  148. luaL_getmetatable(L, LuaWrapper<T>::classname); // ... ud ... udmt Tmt
  149. equal = lua_rawequal(L, -1, -2) != 0;
  150. if (!equal && !strict)
  151. {
  152. lua_getfield(L, -2, LUAW_EXTENDS_KEY); // ... ud ... udmt Tmt udmt.extends
  153. for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
  154. {
  155. // ... ud ... udmt Tmt udmt.extends k v
  156. equal = lua_rawequal(L, -1, -4) != 0;
  157. if (equal)
  158. {
  159. lua_pop(L, 2); // ... ud ... udmt Tmt udmt.extends
  160. break;
  161. }
  162. }
  163. lua_pop(L, 1); // ... ud ... udmt Tmt
  164. }
  165. lua_pop(L, 2); // ... ud ...
  166. }
  167. return equal;
  168. }
  169. // Analogous to lua_to(boolean|string|*)
  170. //
  171. // Converts the given acceptable index to a T*. That value must be of (or
  172. // convertable to) type T; otherwise, returns NULL.
  173. template <typename T>
  174. T* luaW_to(lua_State* L, int index, bool strict = false)
  175. {
  176. if (luaW_is<T>(L, index, strict))
  177. {
  178. luaW_Userdata* pud = static_cast<luaW_Userdata*>(lua_touserdata(L, index));
  179. luaW_Userdata ud;
  180. while (!strict && LuaWrapper<T>::cast != pud->cast)
  181. {
  182. ud = pud->cast(*pud);
  183. pud = &ud;
  184. }
  185. return static_cast<T*>(pud->data);
  186. }
  187. return NULL;
  188. }
  189. // Analogous to luaL_check(boolean|string|*)
  190. //
  191. // Converts the given acceptable index to a T*. That value must be of (or
  192. // convertable to) type T; otherwise, an error is raised.
  193. template <typename T>
  194. T* luaW_check(lua_State* L, int index, bool strict = false)
  195. {
  196. T* obj = NULL;
  197. if (luaW_is<T>(L, index, strict))
  198. {
  199. luaW_Userdata* pud = static_cast<luaW_Userdata*>(lua_touserdata(L, index));
  200. luaW_Userdata ud;
  201. while (!strict && LuaWrapper<T>::cast != pud->cast)
  202. {
  203. ud = pud->cast(*pud);
  204. pud = &ud;
  205. }
  206. obj = (T*)pud->data;
  207. }
  208. else
  209. {
  210. const char *msg = lua_pushfstring(L, "%s expected, got %s", LuaWrapper<T>::classname, luaL_typename(L, index));
  211. luaL_argerror(L, index, msg);
  212. }
  213. return obj;
  214. }
  215. template <typename T>
  216. T* luaW_opt(lua_State* L, int index, T* fallback = NULL, bool strict = false)
  217. {
  218. if (lua_isnil(L, index))
  219. {
  220. return fallback;
  221. }
  222. else
  223. {
  224. return luaW_check<T>(L, index, strict);
  225. }
  226. }
  227. // Analogous to lua_push(boolean|string|*)
  228. //
  229. // Pushes a userdata of type T onto the stack. If this object already exists in
  230. // the Lua environment, it will assign the existing storage table to it.
  231. // Otherwise, a new storage table will be created for it.
  232. template <typename T>
  233. void luaW_push(lua_State* L, T* obj)
  234. {
  235. if (obj)
  236. {
  237. LuaWrapper<T>::identifier(L, obj); // ... id
  238. luaW_wrapperfield<T>(L, LUAW_CACHE_KEY); // ... id cache
  239. lua_pushvalue(L, -2); // ... id cache id
  240. lua_gettable(L, -2); // ... id cache obj
  241. if (lua_isnil(L, -1))
  242. {
  243. // Create the new luaW_userdata and place it in the cache
  244. lua_pop(L, 1); // ... id cache
  245. lua_insert(L, -2); // ... cache id
  246. luaW_Userdata* ud = static_cast<luaW_Userdata*>(lua_newuserdata(L, sizeof(luaW_Userdata))); // ... cache id obj
  247. ud->data = obj;
  248. ud->cast = LuaWrapper<T>::cast;
  249. lua_pushvalue(L, -1); // ... cache id obj obj
  250. lua_insert(L, -4); // ... obj cache id obj
  251. lua_settable(L, -3); // ... obj cache
  252. luaL_getmetatable(L, LuaWrapper<T>::classname); // ... obj cache mt
  253. lua_setmetatable(L, -3); // ... obj cache
  254. lua_pop(L, 1); // ... obj
  255. }
  256. else
  257. {
  258. lua_replace(L, -3); // ... obj cache
  259. lua_pop(L, 1); // ... obj
  260. }
  261. }
  262. else
  263. {
  264. lua_pushnil(L);
  265. }
  266. }
  267. // Instructs LuaWrapper that it owns the userdata, and can manage its memory.
  268. // When all references to the object are removed, Lua is free to garbage
  269. // collect it and delete the object.
  270. //
  271. // Returns true if luaW_hold took hold of the object, and false if it was
  272. // already held
  273. template <typename T>
  274. bool luaW_hold(lua_State* L, T* obj)
  275. {
  276. luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // ... holds
  277. LuaWrapper<T>::identifier(L, obj); // ... holds id
  278. lua_pushvalue(L, -1); // ... holds id id
  279. lua_gettable(L, -3); // ... holds id hold
  280. // If it's not held, hold it
  281. if (!lua_toboolean(L, -1))
  282. {
  283. // Apply hold boolean
  284. lua_pop(L, 1); // ... holds id
  285. lua_pushboolean(L, true); // ... holds id true
  286. lua_settable(L, -3); // ... holds
  287. lua_pop(L, 1); // ...
  288. return true;
  289. }
  290. lua_pop(L, 3); // ...
  291. return false;
  292. }
  293. // Releases LuaWrapper's hold on an object. This allows the user to remove
  294. // all references to an object in Lua and ensure that Lua will not attempt to
  295. // garbage collect it.
  296. //
  297. // This function takes the index of the identifier for an object rather than
  298. // the object itself. This is because needs to be able to run after the object
  299. // has already been deallocated. A wrapper is provided for when it is more
  300. // convenient to pass in the object directly.
  301. template <typename T>
  302. void luaW_release(lua_State* L, int index)
  303. {
  304. luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // ... id ... holds
  305. lua_pushvalue(L, luaW_correctindex(L, index, 1)); // ... id ... holds id
  306. lua_pushnil(L); // ... id ... holds id nil
  307. lua_settable(L, -3); // ... id ... holds
  308. lua_pop(L, 1); // ... id ...
  309. }
  310. template <typename T>
  311. void luaW_release(lua_State* L, T* obj)
  312. {
  313. LuaWrapper<T>::identifier(L, obj); // ... id
  314. luaW_release<T>(L, -1); // ... id
  315. lua_pop(L, 1); // ...
  316. }
  317. template <typename T>
  318. void luaW_postconstructorinternal(lua_State* L, int numargs)
  319. {
  320. // ... ud args...
  321. if (LuaWrapper<T>::postconstructorrecurse)
  322. {
  323. LuaWrapper<T>::postconstructorrecurse(L, numargs);
  324. }
  325. luaL_getmetatable(L, LuaWrapper<T>::classname); // ... ud args... mt
  326. lua_getfield(L, -1, LUAW_POSTCTOR_KEY); // ... ud args... mt postctor
  327. if (lua_type(L, -1) == LUA_TFUNCTION)
  328. {
  329. for (int i = 0; i < numargs + 1; i++)
  330. {
  331. lua_pushvalue(L, -3 - numargs); // ... ud args... mt postctor ud args...
  332. }
  333. lua_call(L, numargs + 1, 0); // ... ud args... mt
  334. lua_pop(L, 1); // ... ud args...
  335. }
  336. else
  337. {
  338. lua_pop(L, 2); // ... ud args...
  339. }
  340. }
  341. // This function is called from Lua, not C++
  342. //
  343. // Calls the lua post-constructor (LUAW_POSTCTOR_KEY or "__postctor") on a
  344. // userdata. Assumes the userdata is on the stack and numargs arguments follow
  345. // it. This runs the LUAW_POSTCTOR_KEY function on T's metatable, using the
  346. // object as the first argument and whatever else is below it as the rest of the
  347. // arguments This exists to allow types to adjust values in thier storage table,
  348. // which can not be created until after the constructor is called.
  349. template <typename T>
  350. void luaW_postconstructor(lua_State* L, int numargs)
  351. {
  352. // ... ud args...
  353. luaW_postconstructorinternal<T>(L, numargs); // ... ud args...
  354. lua_pop(L, numargs); // ... ud
  355. }
  356. // This function is generally called from Lua, not C++
  357. //
  358. // Creates an object of type T using the constructor and subsequently calls the
  359. // post-constructor on it.
  360. template <typename T>
  361. inline int luaW_new(lua_State* L, int numargs)
  362. {
  363. // ... args...
  364. T* obj = LuaWrapper<T>::allocator(L);
  365. luaW_push<T>(L, obj); // ... args... ud
  366. luaW_hold<T>(L, obj);
  367. lua_insert(L, -1 - numargs); // ... ud args...
  368. luaW_postconstructor<T>(L, numargs); // ... ud
  369. return 1;
  370. }
  371. template <typename T>
  372. int luaW_new(lua_State* L)
  373. {
  374. return luaW_new<T>(L, lua_gettop(L));
  375. }
  376. // This function is called from Lua, not C++
  377. //
  378. // The default metamethod to call when indexing into lua userdata representing
  379. // an object of type T. This will first check the userdata's environment table
  380. // and if it's not found there it will check the metatable. This is done so
  381. // individual userdata can be treated as a table, and can hold thier own
  382. // values.
  383. template <typename T>
  384. int luaW_index(lua_State* L)
  385. {
  386. // obj key
  387. T* obj = luaW_to<T>(L, 1);
  388. luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj key storage
  389. LuaWrapper<T>::identifier(L, obj); // obj key storage id
  390. lua_gettable(L, -2); // obj key storage store
  391. // Check if storage table exists
  392. if (!lua_isnil(L, -1))
  393. {
  394. lua_pushvalue(L, -3); // obj key storage store key
  395. lua_gettable(L, -2); // obj key storage store store[k]
  396. }
  397. // If either there is no storage table or the key wasn't found
  398. // then fall back to the metatable
  399. if (lua_isnil(L, -1))
  400. {
  401. lua_settop(L, 2); // obj key
  402. lua_getmetatable(L, -2); // obj key mt
  403. lua_pushvalue(L, -2); // obj key mt k
  404. lua_gettable(L, -2); // obj key mt mt[k]
  405. }
  406. return 1;
  407. }
  408. // This function is called from Lua, not C++
  409. //
  410. // The default metamethod to call when creating a new index on lua userdata
  411. // representing an object of type T. This will index into the the userdata's
  412. // environment table that it keeps for personal storage. This is done so
  413. // individual userdata can be treated as a table, and can hold thier own
  414. // values.
  415. template <typename T>
  416. int luaW_newindex(lua_State* L)
  417. {
  418. // obj key value
  419. T* obj = luaW_check<T>(L, 1);
  420. luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj key value storage
  421. LuaWrapper<T>::identifier(L, obj); // obj key value storage id
  422. lua_pushvalue(L, -1); // obj key value storage id id
  423. lua_gettable(L, -3); // obj key value storage id store
  424. // Add the storage table if there isn't one already
  425. if (lua_isnil(L, -1))
  426. {
  427. lua_pop(L, 1); // obj key value storage id
  428. lua_newtable(L); // obj key value storage id store
  429. lua_pushvalue(L, -1); // obj key value storage id store store
  430. lua_insert(L, -3); // obj key value storage store id store
  431. lua_settable(L, -4); // obj key value storage store
  432. }
  433. lua_pushvalue(L, 2); // obj key value ... store key
  434. lua_pushvalue(L, 3); // obj key value ... store key value
  435. lua_settable(L, -3); // obj key value ... store
  436. return 0;
  437. }
  438. // This function is called from Lua, not C++
  439. //
  440. // The __gc metamethod handles cleaning up userdata. The userdata's reference
  441. // count is decremented and if this is the final reference to the userdata its
  442. // environment table is nil'd and pointer deleted with the destructor callback.
  443. template <typename T>
  444. int luaW_gc(lua_State* L)
  445. {
  446. // obj
  447. T* obj = luaW_to<T>(L, 1);
  448. LuaWrapper<T>::identifier(L, obj); // obj key value storage id
  449. luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // obj id counts count holds
  450. lua_pushvalue(L, 2); // obj id counts count holds id
  451. lua_gettable(L, -2); // obj id counts count holds hold
  452. if (lua_toboolean(L, -1) && LuaWrapper<T>::deallocator)
  453. {
  454. LuaWrapper<T>::deallocator(L, obj);
  455. }
  456. luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj id counts count holds hold storage
  457. lua_pushvalue(L, 2); // obj id counts count holds hold storage id
  458. lua_pushnil(L); // obj id counts count holds hold storage id nil
  459. lua_settable(L, -3); // obj id counts count holds hold storage
  460. luaW_release<T>(L, 2);
  461. return 0;
  462. }
  463. // Thakes two tables and registers them with Lua to the table on the top of the
  464. // stack.
  465. //
  466. // This function is only called from LuaWrapper internally.
  467. inline void luaW_registerfuncs(lua_State* L, const luaL_Reg defaulttable[], const luaL_Reg table[])
  468. {
  469. // ... T
  470. #if LUA_VERSION_NUM == 502
  471. if (defaulttable)
  472. luaL_setfuncs(L, defaulttable, 0); // ... T
  473. if (table)
  474. luaL_setfuncs(L, table, 0); // ... T
  475. #else
  476. if (defaulttable)
  477. luaL_register(L, NULL, defaulttable); // ... T
  478. if (table)
  479. luaL_register(L, NULL, table); // ... T
  480. #endif
  481. }
  482. // Initializes the LuaWrapper tables used to track internal state.
  483. //
  484. // This function is only called from LuaWrapper internally.
  485. inline void luaW_initialize(lua_State* L)
  486. {
  487. // Ensure that the LuaWrapper table is set up
  488. lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
  489. if (lua_isnil(L, -1))
  490. {
  491. lua_newtable(L); // ... nil {}
  492. lua_pushvalue(L, -1); // ... nil {} {}
  493. lua_setfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... nil LuaWrapper
  494. // Create a storage table
  495. lua_newtable(L); // ... LuaWrapper nil {}
  496. lua_setfield(L, -2, LUAW_STORAGE_KEY); // ... nil LuaWrapper
  497. // Create a holds table
  498. lua_newtable(L); // ... LuaWrapper {}
  499. lua_setfield(L, -2, LUAW_HOLDS_KEY); // ... nil LuaWrapper
  500. // Create a cache table, with weak values so that the userdata will not
  501. // be ref counted
  502. lua_newtable(L); // ... nil LuaWrapper {}
  503. lua_setfield(L, -2, LUAW_CACHE_KEY); // ... nil LuaWrapper
  504. lua_newtable(L); // ... nil LuaWrapper {}
  505. lua_pushstring(L, "v"); // ... nil LuaWrapper {} "v"
  506. lua_setfield(L, -2, "__mode"); // ... nil LuaWrapper {}
  507. lua_setfield(L, -2, LUAW_CACHE_METATABLE_KEY); // ... nil LuaWrapper
  508. lua_pop(L, 1); // ... nil
  509. }
  510. lua_pop(L, 1); // ...
  511. }
  512. // Run luaW_register or luaW_setfuncs to create a table and metatable for your
  513. // class. These functions create a table with filled with the function from
  514. // the table argument in addition to the functions new and build (This is
  515. // generally for things you think of as static methods in C++). The given
  516. // metatable argument becomes a metatable for each object of your class. These
  517. // can be thought of as member functions or methods.
  518. //
  519. // You may also supply constructors and destructors for classes that do not
  520. // have a default constructor or that require special set up or tear down. You
  521. // may specify NULL as the constructor, which means that you will not be able
  522. // to call the new function on your class table. You will need to manually push
  523. // objects from C++. By default, the default constructor is used to create
  524. // objects and a simple call to delete is used to destroy them.
  525. //
  526. // By default LuaWrapper uses the address of C++ object to identify unique
  527. // objects. In some cases this is not desired, such as in the case of
  528. // shared_ptrs. Two shared_ptrs may themselves have unique locations in memory
  529. // but still represent the same object. For cases like that, you may specify an
  530. // identifier function which is responsible for pushing a key representing your
  531. // object on to the stack.
  532. //
  533. // luaW_register will set table as the new value of the global of the given
  534. // name. luaW_setfuncs is identical to luaW_register, but it does not set the
  535. // table globally. As with luaL_register and luaL_setfuncs, both funcstions
  536. // leave the new table on the top of the stack.
  537. template <typename T>
  538. void luaW_setfuncs(lua_State* L, const char* classname, const luaL_Reg* table, const luaL_Reg* metatable, T* (*allocator)(lua_State*) = luaW_defaultallocator<T>, void(*deallocator)(lua_State*, T*) = luaW_defaultdeallocator<T>, void(*identifier)(lua_State*, T*) = luaW_defaultidentifier<T>)
  539. {
  540. luaW_initialize(L);
  541. LuaWrapper<T>::classname = classname;
  542. LuaWrapper<T>::identifier = identifier;
  543. LuaWrapper<T>::allocator = allocator;
  544. LuaWrapper<T>::deallocator = deallocator;
  545. const luaL_Reg defaulttable[] =
  546. {
  547. { "new", luaW_new<T> },
  548. { NULL, NULL }
  549. };
  550. const luaL_Reg defaultmetatable[] =
  551. {
  552. { "__index", luaW_index<T> },
  553. { "__newindex", luaW_newindex<T> },
  554. { "__gc", luaW_gc<T> },
  555. { NULL, NULL }
  556. };
  557. // Set up per-type tables
  558. lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
  559. lua_getfield(L, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage
  560. lua_newtable(L); // ... LuaWrapper LuaWrapper.storage {}
  561. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.storage
  562. lua_pop(L, 1); // ... LuaWrapper
  563. lua_getfield(L, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds
  564. lua_newtable(L); // ... LuaWrapper LuaWrapper.holds {}
  565. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.holds
  566. lua_pop(L, 1); // ... LuaWrapper
  567. lua_getfield(L, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache
  568. lua_newtable(L); // ... LuaWrapper LuaWrapper.cache {}
  569. luaW_wrapperfield<T>(L, LUAW_CACHE_METATABLE_KEY); // ... LuaWrapper LuaWrapper.cache {} cmt
  570. lua_setmetatable(L, -2); // ... LuaWrapper LuaWrapper.cache {}
  571. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.cache
  572. lua_pop(L, 2); // ...
  573. // Open table
  574. lua_newtable(L); // ... T
  575. luaW_registerfuncs(L, allocator ? defaulttable : NULL, table); // ... T
  576. // Open metatable, set up extends table
  577. luaL_newmetatable(L, classname); // ... T mt
  578. lua_newtable(L); // ... T mt {}
  579. lua_setfield(L, -2, LUAW_EXTENDS_KEY); // ... T mt
  580. luaW_registerfuncs(L, defaultmetatable, metatable); // ... T mt
  581. lua_setfield(L, -2, "metatable"); // ... T
  582. }
  583. template <typename T>
  584. void luaW_register(lua_State* L, const char* classname, const luaL_Reg* table, const luaL_Reg* metatable, T* (*allocator)(lua_State*) = luaW_defaultallocator<T>, void(*deallocator)(lua_State*, T*) = luaW_defaultdeallocator<T>, void(*identifier)(lua_State*, T*) = luaW_defaultidentifier<T>)
  585. {
  586. luaW_setfuncs(L, classname, table, metatable, allocator, deallocator, identifier); // ... T
  587. lua_pushvalue(L, -1); // ... T T
  588. lua_setglobal(L, classname); // ... T
  589. }
  590. // luaW_extend is used to declare that class T inherits from class U. All
  591. // functions in the base class will be available to the derived class (except
  592. // when they share a function name, in which case the derived class's function
  593. // wins). This also allows luaW_to<T> to cast your object apropriately, as
  594. // casts straight through a void pointer do not work.
  595. template <typename T, typename U>
  596. void luaW_extend(lua_State* L)
  597. {
  598. if (!LuaWrapper<T>::classname)
  599. luaL_error(L, "attempting to call extend on a type that has not been registered");
  600. if (!LuaWrapper<U>::classname)
  601. luaL_error(L, "attempting to extend %s by a type that has not been registered", LuaWrapper<T>::classname);
  602. LuaWrapper<T>::cast = luaW_cast<T, U>;
  603. LuaWrapper<T>::identifier = luaW_identify<T, U>;
  604. LuaWrapper<T>::postconstructorrecurse = luaW_postconstructorinternal<U>;
  605. luaL_getmetatable(L, LuaWrapper<T>::classname); // mt
  606. luaL_getmetatable(L, LuaWrapper<U>::classname); // mt emt
  607. // Point T's metatable __index at U's metatable for inheritance
  608. lua_newtable(L); // mt emt {}
  609. lua_pushvalue(L, -2); // mt emt {} emt
  610. lua_setfield(L, -2, "__index"); // mt emt {}
  611. lua_setmetatable(L, -3); // mt emt
  612. // Set up per-type tables to point at parent type
  613. lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
  614. lua_getfield(L, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage
  615. lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.storage U
  616. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.storage
  617. lua_pop(L, 1); // ... LuaWrapper
  618. lua_getfield(L, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds
  619. lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.holds U
  620. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.holds
  621. lua_pop(L, 1); // ... LuaWrapper
  622. lua_getfield(L, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache
  623. lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.cache U
  624. lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.cache
  625. lua_pop(L, 2); // ...
  626. // Make a list of all types that inherit from U, for type checking
  627. lua_getfield(L, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends
  628. lua_pushvalue(L, -2); // mt emt mt.extends emt
  629. lua_setfield(L, -2, LuaWrapper<U>::classname); // mt emt mt.extends
  630. lua_getfield(L, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends emt.extends
  631. for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
  632. {
  633. // mt emt mt.extends emt.extends k v
  634. lua_pushvalue(L, -2); // mt emt mt.extends emt.extends k v k
  635. lua_pushvalue(L, -2); // mt emt mt.extends emt.extends k v k
  636. lua_rawset(L, -6); // mt emt mt.extends emt.extends k v
  637. }
  638. lua_pop(L, 4); // mt emt
  639. }
  640. /*
  641. * Copyright (c) 2010-2013 Alexander Ames
  642. *
  643. * Permission is hereby granted, free of charge, to any person obtaining a copy
  644. * of this software and associated documentation files (the "Software"), to
  645. * deal in the Software without restriction, including without limitation the
  646. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  647. * sell copies of the Software, and to permit persons to whom the Software is
  648. * furnished to do so, subject to the following conditions:
  649. *
  650. * The above copyright notice and this permission notice shall be included in
  651. * all copies or substantial portions of the Software.
  652. *
  653. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  654. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  655. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  656. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  657. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  658. * FROM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  659. * IN THE SOFTWARE.
  660. */
  661. #endif // LUA_WRAPPER_H_