23-planner.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: MIT
  2. // SPDX-FileCopyrightText: 2022 Ivan Baidakou
  3. #if defined(__ANDROID__)
  4. #undef __ANDROID__
  5. #endif
  6. #include "catch.hpp"
  7. #include "rotor-light/planner.hpp"
  8. #include <limits>
  9. #include <vector>
  10. using namespace rotor_light;
  11. TEST_CASE("1 event planner", "[planner]") {
  12. using AppPlanner = Planner<1>;
  13. auto planner = AppPlanner();
  14. CHECK(!planner.consume(15));
  15. CHECK(planner.next_event() == 0);
  16. static int invoked = 0;
  17. static void *ptr = nullptr;
  18. auto cb = [](void *data) {
  19. ++invoked;
  20. ptr = data;
  21. };
  22. auto event_id = planner.add_event<ctx::thread>(10, cb, &planner);
  23. CHECK(event_id);
  24. CHECK(planner.next_event() == 10);
  25. CHECK(!planner.add_event<ctx::thread>(11, cb, &planner));
  26. CHECK(!planner.consume(9));
  27. SECTION("consume") {
  28. auto consumer = planner.consume(10);
  29. CHECK(consumer);
  30. consumer.call_next();
  31. CHECK(invoked == 1);
  32. CHECK(ptr == &planner);
  33. CHECK(!consumer);
  34. }
  35. SECTION("remove") {
  36. planner.remove_event(event_id);
  37. planner.remove_event(event_id);
  38. }
  39. CHECK(!planner.consume(15));
  40. CHECK(planner.next_event() == 0);
  41. }
  42. TEST_CASE("4 events planner", "[planner]") {
  43. using Vector = std::vector<int>;
  44. using AppPlanner = Planner<4>;
  45. auto planner = AppPlanner();
  46. CHECK(!planner.consume(15));
  47. static Vector order{};
  48. static int invoked = 0;
  49. static void *ptr = nullptr;
  50. static void *ptr2 = nullptr;
  51. static void *ptr3 = nullptr;
  52. static void *ptr4 = nullptr;
  53. auto refresh = []() {
  54. ptr = ptr2 = ptr3 = ptr4 = nullptr;
  55. invoked = 0;
  56. order = {};
  57. };
  58. auto cb1 = [](void *data) {
  59. ++invoked;
  60. ptr = data;
  61. order.emplace_back(1);
  62. };
  63. planner.add_event<ctx::thread>(10, cb1, &planner);
  64. auto cb2 = [](void *data) {
  65. ++invoked;
  66. ptr2 = data;
  67. order.emplace_back(2);
  68. };
  69. planner.add_event<ctx::thread>(8, cb2, &ptr);
  70. auto cb3 = [](void *data) {
  71. ++invoked;
  72. ptr3 = data;
  73. order.emplace_back(3);
  74. };
  75. planner.add_event<ctx::thread>(9, cb3, &ptr2);
  76. auto cb4 = [](void *data) {
  77. ++invoked;
  78. ptr4 = data;
  79. order.emplace_back(4);
  80. };
  81. planner.add_event<ctx::thread>(99, cb4, &ptr3);
  82. SECTION("consume all at once") {
  83. refresh();
  84. auto consumer = planner.consume(100);
  85. while (consumer) {
  86. consumer.call_next();
  87. }
  88. }
  89. SECTION("consume by one") {
  90. refresh();
  91. planner.consume(8).call_next();
  92. planner.consume(9).call_next();
  93. planner.consume(10).call_next();
  94. planner.consume(199).call_next();
  95. }
  96. SECTION("consume 2 and 2") {
  97. refresh();
  98. {
  99. CHECK(planner.next_event() == 8);
  100. auto c = planner.consume(9);
  101. c.call_next();
  102. c.call_next();
  103. CHECK(!c);
  104. }
  105. {
  106. CHECK(planner.next_event() == 10);
  107. auto c = planner.consume(100);
  108. c.call_next();
  109. c.call_next();
  110. CHECK(!c);
  111. }
  112. }
  113. SECTION("consume 1 and 3") {
  114. refresh();
  115. {
  116. auto c = planner.consume(8);
  117. c.call_next();
  118. CHECK(!c);
  119. }
  120. {
  121. auto c = planner.consume(100);
  122. c.call_next();
  123. c.call_next();
  124. c.call_next();
  125. CHECK(!c);
  126. }
  127. }
  128. SECTION("consume 3 and 1") {
  129. refresh();
  130. {
  131. auto c = planner.consume(50);
  132. c.call_next();
  133. c.call_next();
  134. c.call_next();
  135. CHECK(!c);
  136. }
  137. {
  138. auto c = planner.consume(100);
  139. c.call_next();
  140. CHECK(!c);
  141. }
  142. }
  143. CHECK(invoked == 4);
  144. CHECK(!planner.consume(200));
  145. CHECK(ptr == &planner);
  146. CHECK(ptr2 == &ptr);
  147. CHECK(ptr3 == &ptr2);
  148. CHECK(ptr4 == &ptr3);
  149. CHECK(order == Vector{2, 3, 1, 4});
  150. }
  151. TEST_CASE("3 events planner & events removal", "[planner]") {
  152. using AppPlanner = Planner<3>;
  153. auto planner = AppPlanner();
  154. auto some_val = int{5};
  155. auto some_val_2 = int{6};
  156. auto e1 = planner.add_event<ctx::thread>(
  157. 5, [](void *) {}, &planner);
  158. auto e2 = planner.add_event<ctx::thread>(
  159. 5, [](void *) {}, &some_val);
  160. auto e3 = planner.add_event<ctx::thread>(
  161. 6, [](void *) {}, &some_val_2);
  162. SECTION("remove 1-2-3") {
  163. planner.remove_event(e1);
  164. planner.remove_event(e2);
  165. planner.remove_event(e3);
  166. }
  167. SECTION("remove 3-2-1") {
  168. planner.remove_event(e3);
  169. planner.remove_event(e2);
  170. planner.remove_event(e1);
  171. }
  172. SECTION("remove 2-3-1") {
  173. planner.remove_event(e2);
  174. planner.remove_event(e3);
  175. planner.remove_event(e1);
  176. }
  177. SECTION("remove 3-1-2") {
  178. planner.remove_event(e3);
  179. planner.remove_event(e1);
  180. planner.remove_event(e2);
  181. }
  182. CHECK(planner.next_event() == 0);
  183. }
  184. TEST_CASE("event id uniquenesss", "[planner]") {
  185. using AppPlanner = Planner<3>;
  186. auto planner = AppPlanner();
  187. auto callback = [](void *) {};
  188. auto e1 = planner.add_event<ctx::thread>(6, callback, nullptr);
  189. auto e2 = planner.add_event<ctx::thread>(5, callback, nullptr);
  190. auto e3 = std::numeric_limits<EventId>::max();
  191. while (true) {
  192. auto e = planner.add_event<ctx::thread>(15, callback, nullptr);
  193. if (e == e3) {
  194. break;
  195. }
  196. planner.remove_event(e);
  197. }
  198. planner.remove_event(e2);
  199. auto e4 = planner.add_event<ctx::thread>(4, callback, nullptr);
  200. CHECK(e4 == e2 + 1);
  201. planner.remove_event(e1);
  202. planner.remove_event(e4);
  203. planner.remove_event(e3);
  204. CHECK(planner.next_event() == 0);
  205. }