42-ping_pong.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. struct Ping : Message {
  12. static constexpr auto type_id = __LINE__;
  13. using Message::Message;
  14. MessageTypeId get_type_id() const override { return type_id; }
  15. };
  16. struct Pong : Message {
  17. static constexpr auto type_id = __LINE__;
  18. using Message::Message;
  19. MessageTypeId get_type_id() const override { return type_id; }
  20. };
  21. using MessageStorage =
  22. traits::MessageStorage<message::ChangeState, message::ChangeStateAck, Ping,
  23. Pong>;
  24. struct Pinger : Actor<2> {
  25. using Parent = Actor<2>;
  26. void initialize() override {
  27. subscribe(&Pinger::on_pong);
  28. Parent::initialize();
  29. }
  30. void on_pong(Pong &) {
  31. ok = true;
  32. supervisor->stop();
  33. }
  34. void advance_start() override {
  35. Parent::advance_start();
  36. send<Ping>(0, ponger_id);
  37. }
  38. bool ok = false;
  39. ActorId ponger_id;
  40. };
  41. struct Ponger : Actor<2> {
  42. using Parent = Actor<2>;
  43. void initialize() override {
  44. subscribe(&Ponger::on_ping);
  45. Parent::initialize();
  46. }
  47. void on_ping(Ping &) {
  48. send<Pong>(0, pinger_id);
  49. ok = true;
  50. }
  51. void advance_start() override { Parent::advance_start(); }
  52. bool ok = false;
  53. ActorId pinger_id;
  54. };
  55. using AppQueue = Queue<MessageStorage, 5>;
  56. using AppSupervisor = Supervisor<3, Pinger, Ponger>;
  57. using AppPlanner = Planner<1>;
  58. TEST_CASE("simple ping-pong example", "[actor]") {
  59. AppQueue queue;
  60. AppPlanner planner;
  61. Context context{&queue, &planner, nullptr};
  62. AppSupervisor sup;
  63. sup.bind(context);
  64. auto pinger = sup.get_child<0>();
  65. auto ponger = sup.get_child<1>();
  66. pinger->ponger_id = ponger->get_id();
  67. ponger->pinger_id = pinger->get_id();
  68. sup.start();
  69. sup.process();
  70. CHECK(pinger->ok);
  71. CHECK(ponger->ok);
  72. CHECK(sup.get_state() == State::off);
  73. CHECK(pinger->get_state() == State::off);
  74. CHECK(ponger->get_state() == State::off);
  75. }