usertypes.cpp 3.7 KB

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