usertypes.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <catch.hpp>
  2. #include <luwra.hpp>
  3. #include <memory>
  4. struct A {
  5. int a;
  6. A(int x = 1338): a(x) {}
  7. };
  8. TEST_CASE("UserTypeRegistration") {
  9. luwra::StateWrapper state;
  10. luwra::registerUserType<A>(state);
  11. }
  12. TEST_CASE("UserTypeConstruction") {
  13. luwra::StateWrapper state;
  14. luwra::registerUserType<A>(state);
  15. luwra::setGlobal(state, "A", LUWRA_WRAP_CONSTRUCTOR(A, int));
  16. // Construction
  17. REQUIRE(luaL_dostring(state, "return A(73)") == 0);
  18. // Check
  19. A* instance = luwra::read<A*>(state, -1);
  20. REQUIRE(instance != nullptr);
  21. REQUIRE(instance->a == 73);
  22. }
  23. struct B {
  24. int n;
  25. const int cn;
  26. volatile int vn;
  27. const volatile int cvn;
  28. B(int val):
  29. n(val),
  30. cn(val),
  31. vn(val),
  32. cvn(val)
  33. {}
  34. };
  35. TEST_CASE("UserTypeFields") {
  36. luwra::StateWrapper state;
  37. // Registration
  38. luwra::registerUserType<B>(
  39. state,
  40. {
  41. LUWRA_MEMBER(B, n),
  42. LUWRA_MEMBER(B, cn),
  43. LUWRA_MEMBER(B, vn),
  44. LUWRA_MEMBER(B, cvn)
  45. }
  46. );
  47. // Instantiation
  48. luwra::Value<B&>::push(state, 1338);
  49. lua_setglobal(state, "value");
  50. B& value = luwra::getGlobal<B&>(state, "value");
  51. // Unqualified get
  52. REQUIRE(luaL_dostring(state, "return value:n()") == 0);
  53. puts(lua_tostring(state, -1));
  54. REQUIRE(luwra::read<int>(state, -1) == value.n);
  55. // Unqualified set
  56. REQUIRE(luaL_dostring(state, "value:n(42)") == 0);
  57. REQUIRE(value.n == 42);
  58. // 'const'-qualified get
  59. REQUIRE(luaL_dostring(state, "return value:cn()") == 0);
  60. REQUIRE(luwra::read<int>(state, -1) == value.cn);
  61. // 'const'-qualified set
  62. REQUIRE(luaL_dostring(state, "value:cn(42)") == 0);
  63. REQUIRE(value.cn == 1338);
  64. // 'volatile' get
  65. REQUIRE(luaL_dostring(state, "return value:vn()") == 0);
  66. REQUIRE(luwra::read<int>(state, -1) == value.vn);
  67. // 'volatile' set
  68. REQUIRE(luaL_dostring(state, "value:vn(42)") == 0);
  69. REQUIRE(value.vn == 42);
  70. // 'const volatile'-qualified get
  71. REQUIRE(luaL_dostring(state, "return value:cvn()") == 0);
  72. REQUIRE(luwra::read<int>(state, -1) == value.cvn);
  73. // 'const volatile'-qualified set
  74. REQUIRE(luaL_dostring(state, "value:cvn(42)") == 0);
  75. REQUIRE(value.cvn == 1338);
  76. }
  77. struct C {
  78. int prop;
  79. C(int val):
  80. prop(val)
  81. {}
  82. int foo1(int x) {
  83. return prop += x;
  84. }
  85. int foo2(int x) const {
  86. return prop + x;
  87. }
  88. int foo3(int x) volatile {
  89. return prop -= x;
  90. }
  91. int foo4(int x) const volatile {
  92. return prop - x;
  93. }
  94. };
  95. TEST_CASE("UserTypeMethods") {
  96. luwra::StateWrapper state;
  97. // Registration
  98. luwra::registerUserType<C>(
  99. state,
  100. {
  101. LUWRA_MEMBER(C, foo1),
  102. LUWRA_MEMBER(C, foo2),
  103. LUWRA_MEMBER(C, foo3),
  104. LUWRA_MEMBER(C, foo4)
  105. }
  106. );
  107. // Instantiation
  108. luwra::Value<C&>::push(state, 1337);
  109. lua_setglobal(state, "value");
  110. C& value = luwra::getGlobal<C&>(state, "value");
  111. // Unqualified method
  112. REQUIRE(luaL_dostring(state, "return value:foo1(63)") == 0);
  113. REQUIRE(value.prop == 1400);
  114. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  115. // 'const'-qualified method
  116. REQUIRE(luaL_dostring(state, "return value:foo2(44)") == 0);
  117. REQUIRE(value.prop == 1400);
  118. REQUIRE(luwra::read<int>(state, -1) == 1444);
  119. // 'volatile'-qualified method
  120. REQUIRE(luaL_dostring(state, "return value:foo3(400)") == 0);
  121. REQUIRE(value.prop == 1000);
  122. REQUIRE(luwra::read<int>(state, -1) == value.prop);
  123. // 'const volatile'-qualified method
  124. REQUIRE(luaL_dostring(state, "return value:foo4(334)") == 0);
  125. REQUIRE(value.prop == 1000);
  126. REQUIRE(luwra::read<int>(state, -1) == 666);
  127. }
  128. TEST_CASE("UserTypeGarbageCollectionRef") {
  129. lua_State* state = luaL_newstate();
  130. // Registration
  131. luwra::registerUserType<std::shared_ptr<int>>(state);
  132. // Instantiation
  133. std::shared_ptr<int> shared_var = std::make_shared<int>(1337);
  134. REQUIRE(shared_var.use_count() == 1);
  135. // Copy construction
  136. luwra::push<std::shared_ptr<int>&>(state, shared_var);
  137. REQUIRE(shared_var.use_count() == 2);
  138. // Garbage collection
  139. lua_close(state);
  140. REQUIRE(shared_var.use_count() == 1);
  141. }