33-timers.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "rotor-light/queue.hpp"
  9. #include "rotor-light/supervisor.hpp"
  10. using namespace rotor_light;
  11. using MessageStorage =
  12. traits::MessageStorage<message::ChangeState, message::ChangeStateAck>;
  13. using AppQueue = Queue<MessageStorage, 5>;
  14. using AppPlanner = Planner<3>;
  15. TimePoint now = 1;
  16. TimePoint get_current_time() { return ++now; }
  17. TEST_CASE("trigger some timers, no refresher", "[timers]") {
  18. static int triggered{0};
  19. struct A : Actor<1> {
  20. using Parent = Actor<1>;
  21. using Parent::Parent;
  22. virtual void advance_init() {
  23. add_event<ctx::thread>(
  24. now, [](void *data) { reinterpret_cast<A *>(data)->on_timer(); },
  25. this);
  26. add_event<ctx::thread>(
  27. 50, [](void *) { ++triggered; }, this);
  28. }
  29. void on_timer() { Parent::advance_init(); }
  30. };
  31. struct S : Supervisor<3, A> {
  32. using Parent = Supervisor<3, A>;
  33. using Parent::Parent;
  34. };
  35. AppQueue queue;
  36. AppPlanner planner;
  37. Context context{&queue, &planner, &get_current_time};
  38. S sup;
  39. sup.bind(context);
  40. auto act = sup.get_child<0>();
  41. sup.start();
  42. sup.process();
  43. CHECK(sup.get_state() == State::operational);
  44. CHECK(act->get_state() == State::operational);
  45. CHECK(triggered == 0);
  46. CHECK(planner.next_event());
  47. sup.stop(true);
  48. sup.process();
  49. }
  50. TEST_CASE("trigger some timers, with time refresher", "[timers]") {
  51. struct A : Actor<1> {
  52. using Parent = Actor<1>;
  53. using Parent::Parent;
  54. virtual void advance_init() {
  55. add_event<ctx::thread>(
  56. now + 100,
  57. [](void *data) { reinterpret_cast<A *>(data)->on_timer(); }, this);
  58. }
  59. void on_timer() { Parent::advance_init(); }
  60. };
  61. struct S : Supervisor<3, A> {
  62. using Parent = Supervisor<3, A>;
  63. using Parent::Parent;
  64. void on_refhesh_timer(message::RefreshTime &message) override {
  65. if (state < State::operational) {
  66. Parent::on_refhesh_timer(message);
  67. }
  68. }
  69. };
  70. AppQueue queue;
  71. AppPlanner planner;
  72. Context context{&queue, &planner, &get_current_time};
  73. S sup;
  74. sup.bind(context);
  75. auto act = sup.get_child<0>();
  76. sup.start(true);
  77. sup.process();
  78. CHECK(sup.get_state() == State::operational);
  79. CHECK(act->get_state() == State::operational);
  80. CHECK(!planner.next_event());
  81. sup.stop(true);
  82. sup.process();
  83. }