You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dbcc_lua_wrapper.cpp 4.3 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "lua.hpp"
  2. #include "dbcc/dbc_iterator.h"
  3. #include "dbcc/message.h"
  4. #include "dbcc/signal.h"
  5. #include "dbcc/version.h"
  6. #define LUA_MODULE_NAME "dbcc"
  7. #define LUA_DBC_ITERATOR_CLASS_NAME "DbcIterator"
  8. // These are the definitions for the C functions that Lua will use to call the member functions.
  9. // Consructor of 'ad::dbcc::DbcIterator'
  10. static int lua_DbcIterator_new(lua_State* L)
  11. {
  12. if (lua_gettop(L) != 1)
  13. {
  14. luaL_pushfail(L);
  15. return 1;
  16. }
  17. std::strting filePath = luaL_checkstring(L, 1);
  18. ad::dbcc::DbcIterator** iter = reinterpret_cast<ad::dbcc::DbcIterator**>(lua_newuserdata(L, sizeof(ad::dbcc::DbcIterator**)));
  19. *iter = new ad::dbcc::DbcIterator(filePath);
  20. luaL_setmetatable(L, LUA_DBC_ITERATOR_CLASS_NAME);
  21. return 1;
  22. }
  23. // `ad::dbcc::DbcIterator` destructor, which corresponds to the `__gc` metamethod in Lua.
  24. int lua_DbcIterator_delete(lua_State* L)
  25. {
  26. ad::dbcc::DbcIterator* iter = *reinterpret_cast<ad::dbcc::DbcIterator**>(luaL_checkudata(L, 1, LUA_DBC_ITERATOR_CLASS_NAME));
  27. delete iter;
  28. return 0;
  29. }
  30. // C function corresponding to the `ad::dbcc::DbcIterator` iterator.
  31. int lua_MyClass_index(lua_State* L)
  32. {
  33. ad::dbcc::DbcIterator* iter = *reinterpret_cast<ad::dbcc::DbcIterator**>(luaL_checkudata(L, 1, LUA_DBC_ITERATOR_CLASS_NAME));
  34. int something_in = static_cast<int>(luaL_checkinteger(L, 2));
  35. (*iter)[]->set(something_in);
  36. return 0;
  37. }
  38. // C function corresponding to `MyClass::get`.
  39. int lua_MyClass_get(lua_State* L)
  40. {
  41. ad::dbcc::DbcIterator* iter = *reinterpret_cast<ad::dbcc::DbcIterator**>(luaL_checkudata(L, 1, LUA_DBC_ITERATOR_CLASS_NAME));
  42. // Push a lua object
  43. lua_pushinteger(L, (*iter)[]);
  44. return 1;
  45. }
  46. // `__newindex` metamethod for `MyClass` userdata that prevents any members from being added.
  47. int lua_MyClass_newindex(lua_State* L)
  48. {
  49. return luaL_error(L, "attempt to modify a read-only object");
  50. }
  51. // `__newindex` metamethod for the `MyClass` table that prevents any methods from being added--I will explain more below.
  52. int lua_MyClass_table_newindex(lua_State* L)
  53. {
  54. return luaL_error(L, "attempt to modify a read-only table");
  55. }
  56. // Function to register all the above functions for use in Lua; this gets called in `main.cpp`.
  57. void lua_MyClass_register(lua_State* L)
  58. {
  59. // Create a global table that will contain all the `MyClass` methods as functions.
  60. // Include `lua_MyClass_new` as a constructor in the form `MyClass.new`.
  61. lua_newtable(L);
  62. lua_pushcfunction(L, lua_MyClass_new);
  63. lua_setfield(L, -2, "new");
  64. // Include `MyClass::get` and `MyClass::set` in this table as well.
  65. luaL_setfuncs(L, MyClass_methods, 0);
  66. // Create a metatable for the global table `MyClass`--which was just created.
  67. lua_newtable(L);
  68. // Prevent access to the metatable.
  69. lua_pushliteral(L, "metatable");
  70. lua_setfield(L, -2, "__metatable");
  71. lua_pushcfunction(L, lua_MyClass_table_newindex);
  72. lua_setfield(L, -2, "__newindex");
  73. // Set this second table as the metatable for the one created above.
  74. lua_setmetatable(L, -2);
  75. // Call the first table "MyClass" and add it to the global environment table (_ENV).
  76. lua_setglobal(L, LUA_MYCLASS);
  77. // Create a metatable to be used by `MyClass` objects--this is different from the above tables because it will not contain the `new` method.
  78. luaL_newmetatable(L, LUA_MYCLASS);
  79. // Same as before, lock the metatable.
  80. lua_pushliteral(L, "metatable");
  81. lua_setfield(L, -2, "__metatable");
  82. // Add metamethods contained in the `luaL_Reg` struct `MyClass_metamethods`.
  83. luaL_setfuncs(L, MyClass_metamethods, 0);
  84. // Create an index--the `__index` metamethod--for the above table to use for `MyClass` objects.
  85. lua_newtable(L);
  86. // Add methods.
  87. luaL_setfuncs(L, MyClass_methods, 0);
  88. lua_setfield(L, -2, "__index");
  89. // This pop operation is probably unnecessary since the Lua stack should be cleaned up when this function returns.
  90. lua_pop(L, 1);
  91. return;
  92. }
  93. #if defined(OS_WINDOWS)
  94. #define __EXPORT extern "C" __declspec(dllexport)
  95. #else
  96. #define __EXPORT extern "C"
  97. #endif //
  98. __EXPORT int luaopen_dbcc(lua_State *L)
  99. {
  100. static const struct luaL_Reg methods[] = {
  101. {"new", },
  102. {NULL, NULL}
  103. };
  104. luaL_newlib(L, methods);
  105. return 1;
  106. }