42-ping_pong.cpp 2.0 KB

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