33-timers.cpp 2.4 KB

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