scheduler.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <functional>
  2. #include <memory>
  3. #include <utility>
  4. #include <gtest/gtest.h>
  5. #include <entt/process/process.hpp>
  6. #include <entt/process/scheduler.hpp>
  7. struct foo_process: entt::process<foo_process, entt::scheduler::delta_type> {
  8. foo_process(std::function<void()> upd, std::function<void()> abort)
  9. : on_update{std::move(upd)}, on_aborted{std::move(abort)} {}
  10. void update(delta_type, void *) {
  11. on_update();
  12. }
  13. void aborted() {
  14. on_aborted();
  15. }
  16. std::function<void()> on_update;
  17. std::function<void()> on_aborted;
  18. };
  19. struct succeeded_process: entt::process<succeeded_process, entt::scheduler::delta_type> {
  20. void update(delta_type, void *data) {
  21. ++static_cast<std::pair<int, int> *>(data)->first;
  22. succeed();
  23. }
  24. };
  25. struct failed_process: entt::process<failed_process, entt::scheduler::delta_type> {
  26. void update(delta_type, void *data) {
  27. ++static_cast<std::pair<int, int> *>(data)->second;
  28. fail();
  29. }
  30. };
  31. TEST(Scheduler, Functionalities) {
  32. entt::scheduler scheduler{};
  33. entt::scheduler other{std::move(scheduler)};
  34. scheduler = std::move(other);
  35. bool updated = false;
  36. bool aborted = false;
  37. ASSERT_EQ(scheduler.size(), 0u);
  38. ASSERT_TRUE(scheduler.empty());
  39. scheduler.attach<foo_process>(
  40. [&updated]() { updated = true; },
  41. [&aborted]() { aborted = true; });
  42. ASSERT_NE(scheduler.size(), 0u);
  43. ASSERT_FALSE(scheduler.empty());
  44. scheduler.update(0);
  45. scheduler.abort(true);
  46. ASSERT_TRUE(updated);
  47. ASSERT_TRUE(aborted);
  48. ASSERT_NE(scheduler.size(), 0u);
  49. ASSERT_FALSE(scheduler.empty());
  50. scheduler.clear();
  51. ASSERT_EQ(scheduler.size(), 0u);
  52. ASSERT_TRUE(scheduler.empty());
  53. }
  54. TEST(Scheduler, Swap) {
  55. entt::scheduler scheduler{};
  56. entt::scheduler other{};
  57. int counter{};
  58. scheduler.attach([&counter](auto &&...) { ++counter; });
  59. ASSERT_EQ(scheduler.size(), 1u);
  60. ASSERT_EQ(other.size(), 0u);
  61. ASSERT_EQ(counter, 0);
  62. scheduler.update({});
  63. ASSERT_EQ(counter, 1);
  64. scheduler.swap(other);
  65. scheduler.update({});
  66. ASSERT_EQ(scheduler.size(), 0u);
  67. ASSERT_EQ(other.size(), 1u);
  68. ASSERT_EQ(counter, 1);
  69. other.update({});
  70. ASSERT_EQ(counter, 2);
  71. }
  72. TEST(Scheduler, Then) {
  73. entt::scheduler scheduler{};
  74. std::pair<int, int> counter{};
  75. scheduler
  76. // failing process with successor
  77. .attach<succeeded_process>()
  78. .then<succeeded_process>()
  79. .then<failed_process>()
  80. .then<succeeded_process>()
  81. // failing process without successor
  82. .attach<succeeded_process>()
  83. .then<succeeded_process>()
  84. .then<failed_process>()
  85. // non-failing process
  86. .attach<succeeded_process>()
  87. .then<succeeded_process>();
  88. while(!scheduler.empty()) {
  89. scheduler.update(0, &counter);
  90. }
  91. ASSERT_EQ(counter.first, 6u);
  92. ASSERT_EQ(counter.second, 2u);
  93. }
  94. TEST(Scheduler, Functor) {
  95. entt::scheduler scheduler{};
  96. bool first_functor = false;
  97. bool second_functor = false;
  98. auto attach = [&first_functor](auto, void *, auto resolve, auto) {
  99. ASSERT_FALSE(first_functor);
  100. first_functor = true;
  101. resolve();
  102. };
  103. auto then = [&second_functor](auto, void *, auto, auto reject) {
  104. ASSERT_FALSE(second_functor);
  105. second_functor = true;
  106. reject();
  107. };
  108. scheduler.attach(std::move(attach)).then(std::move(then)).then([](auto...) { FAIL(); });
  109. while(!scheduler.empty()) {
  110. scheduler.update(0);
  111. }
  112. ASSERT_TRUE(first_functor);
  113. ASSERT_TRUE(second_functor);
  114. ASSERT_TRUE(scheduler.empty());
  115. }
  116. TEST(Scheduler, SpawningProcess) {
  117. entt::scheduler scheduler{};
  118. std::pair<int, int> counter{};
  119. scheduler.attach([&scheduler](auto, void *, auto resolve, auto) {
  120. scheduler.attach<succeeded_process>().then<failed_process>();
  121. resolve();
  122. });
  123. while(!scheduler.empty()) {
  124. scheduler.update(0, &counter);
  125. }
  126. ASSERT_EQ(counter.first, 1u);
  127. ASSERT_EQ(counter.second, 1u);
  128. }
  129. TEST(Scheduler, CustomAllocator) {
  130. const std::allocator<void> allocator{};
  131. entt::scheduler scheduler{allocator};
  132. ASSERT_EQ(scheduler.get_allocator(), allocator);
  133. ASSERT_FALSE(scheduler.get_allocator() != allocator);
  134. scheduler.attach([](auto &&...) {});
  135. const decltype(scheduler) other{std::move(scheduler), allocator};
  136. ASSERT_EQ(other.size(), 1u);
  137. }