LuaBinder.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (C) 2014, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "anki/script/LuaBinder.h"
  6. #include "anki/util/Exception.h"
  7. #include "anki/util/Logger.h"
  8. #include <iostream>
  9. #include <cstring>
  10. namespace anki {
  11. namespace detail {
  12. //==============================================================================
  13. void checkArgsCount(lua_State* l, I argsCount)
  14. {
  15. I actualArgsCount = lua_gettop(l);
  16. if(argsCount != actualArgsCount)
  17. {
  18. luaL_error(l, "Expecting %d arguments, got %d", argsCount,
  19. actualArgsCount);
  20. }
  21. }
  22. //==============================================================================
  23. void createClass(lua_State* l, const char* className)
  24. {
  25. lua_newtable(l); // push new table
  26. lua_setglobal(l, className); // pop and make global
  27. luaL_newmetatable(l, className); // push
  28. lua_pushstring(l, "__index"); // push
  29. lua_pushvalue(l, -2); // pushes copy of the metatable
  30. lua_settable(l, -3); // pop*2: metatable.__index = metatable
  31. // After all these the metatable is in the top of tha stack
  32. }
  33. //==============================================================================
  34. void pushCFunctionMethod(lua_State* l, const char* name, lua_CFunction luafunc)
  35. {
  36. lua_pushstring(l, name);
  37. lua_pushcfunction(l, luafunc);
  38. lua_settable(l, -3);
  39. }
  40. //==============================================================================
  41. void pushCFunctionStatic(lua_State* l, const char* className,
  42. const char* name, lua_CFunction luafunc)
  43. {
  44. lua_getglobal(l, className); // push
  45. lua_pushcfunction(l, luafunc); // push
  46. lua_setfield(l, -2, name); // pop global
  47. lua_pop(l, 1); // pop cfunc
  48. }
  49. } // end namespace lua_detail
  50. //==============================================================================
  51. static int luaPanic(lua_State* l)
  52. {
  53. std::string err(lua_tostring(l, -1));
  54. ANKI_LOGE("Lua panic attack: %s", err.c_str());
  55. abort();
  56. }
  57. //==============================================================================
  58. LuaBinder::LuaBinder(Allocator<U8>& alloc, void* parent)
  59. : m_parent(parent)
  60. {
  61. m_alloc = alloc;
  62. m_l = lua_newstate(luaAllocCallback, this);
  63. //m_l = luaL_newstate();
  64. luaL_openlibs(m_l);
  65. lua_atpanic(m_l, &luaPanic);
  66. lua_setuserdata(m_l, this);
  67. }
  68. //==============================================================================
  69. LuaBinder::~LuaBinder()
  70. {
  71. lua_close(m_l);
  72. ANKI_ASSERT(m_alloc.getMemoryPool().getAllocationsCount() == 0
  73. && "Leaking memory");
  74. }
  75. //==============================================================================
  76. void* LuaBinder::luaAllocCallback(
  77. void* userData, void* ptr, PtrSize osize, PtrSize nsize)
  78. {
  79. ANKI_ASSERT(userData);
  80. LuaBinder& binder = *(LuaBinder*)userData;
  81. void* out = nullptr;
  82. if(nsize == 0)
  83. {
  84. if(ptr != nullptr)
  85. {
  86. binder.m_alloc.getMemoryPool().free(ptr);
  87. }
  88. }
  89. else
  90. {
  91. // Should be doing something like realloc
  92. if(ptr == nullptr)
  93. {
  94. out = binder.m_alloc.allocate(nsize);
  95. }
  96. else if(nsize <= osize)
  97. {
  98. out = ptr;
  99. }
  100. else
  101. {
  102. // realloc
  103. out = binder.m_alloc.allocate(nsize);
  104. std::memcpy(out, ptr, osize);
  105. binder.m_alloc.getMemoryPool().free(ptr);
  106. }
  107. }
  108. return out;
  109. }
  110. //==============================================================================
  111. void LuaBinder::evalString(const CString& str)
  112. {
  113. int e = luaL_dostring(m_l, &str[0]);
  114. if(e)
  115. {
  116. ANKI_LOGE("%s", lua_tostring(m_l, -1));
  117. lua_pop(m_l, 1);
  118. }
  119. }
  120. } // end namespace anki