35-broadcasting.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. struct Signal : Message {
  13. static constexpr auto type_id = __LINE__;
  14. using Message::Message;
  15. };
  16. using MessageStorage = traits::MessageStorage<message::ChangeState,
  17. message::ChangeStateAck, Signal>;
  18. using AppQueue = Queue<MessageStorage, 5>;
  19. using AppPlanner = Planner<1>;
  20. struct A : Actor<2> {
  21. using Parent = Actor<2>;
  22. using Parent::Parent;
  23. void initialize() override {
  24. Parent::initialize();
  25. subscribe(&A::on_signal);
  26. }
  27. void on_signal(Signal &) { ++count; }
  28. int count = 0;
  29. };
  30. struct S : Supervisor<4, A, A> {
  31. using Parent = Supervisor<4, A, A>;
  32. using Parent::Parent;
  33. void initialize() override {
  34. Parent::initialize();
  35. subscribe(&S::on_signal);
  36. }
  37. void on_signal(Signal &) { ++count; }
  38. void advance_start() override {
  39. Parent::advance_start();
  40. send_signal();
  41. }
  42. void send_signal() { send<ctx::thread, Signal>(0, broadcast); }
  43. int count = 0;
  44. };
  45. TEST_CASE("broadcasting example", "[sup]") {
  46. AppQueue queue;
  47. AppPlanner planner;
  48. Context context{&queue, &planner, nullptr};
  49. S sup;
  50. sup.bind(context);
  51. auto act1 = sup.get_child<0>();
  52. auto act2 = sup.get_child<1>();
  53. sup.start();
  54. sup.process();
  55. REQUIRE(sup.get_state() == State::operational);
  56. REQUIRE(act1->get_state() == State::operational);
  57. REQUIRE(act2->get_state() == State::operational);
  58. CHECK(sup.count == 1);
  59. CHECK(act1->count == 1);
  60. CHECK(act2->count == 1);
  61. act2->stop();
  62. sup.process();
  63. REQUIRE(act2->get_state() == State::off);
  64. sup.send_signal();
  65. sup.process();
  66. CHECK(sup.count == 2);
  67. CHECK(act1->count == 2);
  68. CHECK(act2->count == 1);
  69. sup.stop();
  70. sup.process();
  71. CHECK(sup.get_state() == State::off);
  72. CHECK(act1->get_state() == State::off);
  73. CHECK(act2->get_state() == State::off);
  74. }