Utilities.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include <RmlUi/Core/Variant.h>
  2. #include <RmlUi/Lua/Utilities.h>
  3. namespace Rml {
  4. namespace Lua {
  5. #if LUA_VERSION_NUM < 502
  6. void lua_len(lua_State* L, int i)
  7. {
  8. switch (lua_type(L, i))
  9. {
  10. case LUA_TSTRING: lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); break;
  11. case LUA_TTABLE:
  12. if (!luaL_callmeta(L, i, "__len"))
  13. lua_pushnumber(L, (lua_Number)lua_objlen(L, i));
  14. break;
  15. case LUA_TUSERDATA:
  16. if (luaL_callmeta(L, i, "__len"))
  17. break;
  18. /* FALLTHROUGH */
  19. default: luaL_error(L, "attempt to get length of a %s value", lua_typename(L, lua_type(L, i)));
  20. }
  21. }
  22. lua_Integer luaL_len(lua_State* L, int i)
  23. {
  24. lua_Integer res = 0;
  25. int isnum = 0;
  26. luaL_checkstack(L, 1, "not enough stack slots");
  27. lua_len(L, i);
  28. res = lua_tointegerx(L, -1, &isnum);
  29. lua_pop(L, 1);
  30. if (!isnum)
  31. luaL_error(L, "object length is not an integer");
  32. return res;
  33. }
  34. #endif
  35. void PushVariant(lua_State* L, const Variant* var)
  36. {
  37. if (!var)
  38. {
  39. lua_pushnil(L);
  40. return;
  41. }
  42. switch (var->GetType())
  43. {
  44. case Variant::BOOL: lua_pushboolean(L, var->Get<bool>()); break;
  45. case Variant::BYTE:
  46. case Variant::CHAR:
  47. case Variant::INT: lua_pushinteger(L, var->Get<int>()); break;
  48. case Variant::INT64: lua_pushinteger(L, var->Get<int64_t>()); break;
  49. case Variant::UINT: lua_pushinteger(L, var->Get<unsigned int>()); break;
  50. case Variant::UINT64: lua_pushinteger(L, var->Get<uint64_t>()); break;
  51. case Variant::FLOAT:
  52. case Variant::DOUBLE: lua_pushnumber(L, var->Get<double>()); break;
  53. case Variant::COLOURB: LuaType<Colourb>::push(L, new Colourb(var->Get<Colourb>()), true); break;
  54. case Variant::COLOURF: LuaType<Colourf>::push(L, new Colourf(var->Get<Colourf>()), true); break;
  55. case Variant::STRING:
  56. {
  57. const String& s = var->GetReference<Rml::String>();
  58. lua_pushlstring(L, s.c_str(), s.length());
  59. }
  60. break;
  61. case Variant::VECTOR2:
  62. // according to Variant.inl, it is going to be a Vector2f
  63. LuaType<Vector2f>::push(L, new Vector2f(var->Get<Vector2f>()), true);
  64. break;
  65. case Variant::VOIDPTR: lua_pushlightuserdata(L, var->Get<void*>()); break;
  66. default: lua_pushnil(L); break;
  67. }
  68. }
  69. void GetVariant(lua_State* L, int index, Variant* variant)
  70. {
  71. if (!variant)
  72. return;
  73. switch (lua_type(L, index))
  74. {
  75. case LUA_TBOOLEAN: *variant = (bool)lua_toboolean(L, index); break;
  76. case LUA_TNUMBER: *variant = lua_tonumber(L, index); break;
  77. case LUA_TSTRING: *variant = Rml::String(lua_tostring(L, index)); break;
  78. case LUA_TLIGHTUSERDATA: *variant = lua_touserdata(L, index); break;
  79. case LUA_TNIL:
  80. default: // todo: support other types
  81. *variant = Variant();
  82. break;
  83. }
  84. }
  85. void PushIndex(lua_State* L, int index)
  86. {
  87. lua_pushinteger(L, index + 1);
  88. }
  89. int GetIndex(lua_State* L, int index)
  90. {
  91. return (int)luaL_checkinteger(L, index) - 1;
  92. }
  93. } // namespace Lua
  94. } // namespace Rml