36-queue-full.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 Sample : Message {
  12. static constexpr auto type_id = __LINE__;
  13. using Message::Message;
  14. };
  15. struct LogMessage : Message {
  16. static constexpr auto type_id = __LINE__;
  17. LogMessage(ActorId to, const char *msg_) : Message(to), msg{msg_} {}
  18. const char *msg;
  19. };
  20. using MessageStorage =
  21. traits::MessageStorage<message::ChangeState, message::ChangeStateAck,
  22. Sample, LogMessage>;
  23. using AppPlanner = Planner<1>;
  24. static int overfill = 0;
  25. namespace rotor_light {
  26. void on_queue_full() { ++overfill; }
  27. } // namespace rotor_light
  28. TEST_CASE("simple ping-pong example", "[actor]") {
  29. using AppQueue = Queue<MessageStorage, 5>;
  30. using AppSupervisor = Supervisor<3>;
  31. AppQueue queue;
  32. AppPlanner planner;
  33. Context context{&queue, &planner, nullptr};
  34. AppSupervisor sup;
  35. sup.bind(context);
  36. sup.start();
  37. sup.process();
  38. CHECK(overfill == 0);
  39. for (int i = 0; i < 5; ++i) {
  40. bool ok = sup.send<ctx::thread, Sample>(0, sup.get_id());
  41. CHECK(ok);
  42. }
  43. CHECK(overfill == 0);
  44. bool ok = sup.send<ctx::thread, Sample>(0, sup.get_id());
  45. CHECK(!ok);
  46. CHECK(overfill == 0);
  47. sup.stop();
  48. CHECK(overfill == 1);
  49. sup.process();
  50. sup.stop();
  51. sup.process();
  52. CHECK(sup.get_state() == State::off);
  53. }
  54. TEST_CASE("transmit log message") {
  55. struct A : Actor<2> {
  56. using Parent = Actor<2>;
  57. using Parent::Parent;
  58. void initialize() override {
  59. subscribe(&A::on_message);
  60. Parent::initialize();
  61. }
  62. void on_message(LogMessage &msg) { msgs[idx++] = msg.msg; }
  63. const char *msgs[2];
  64. int idx = 0;
  65. };
  66. using AppQueue = Queue<MessageStorage, 5, 2>;
  67. using AppSupervisor = Supervisor<3, A>;
  68. AppQueue queue;
  69. AppPlanner planner;
  70. Context context{&queue, &planner, nullptr};
  71. AppSupervisor sup;
  72. sup.bind(context);
  73. sup.start();
  74. sup.process();
  75. auto a = sup.get_child<0>();
  76. CHECK(!a->transmit<ctx::thread, LogMessage>(1, a->get_id(), "first"));
  77. CHECK(!a->transmit<ctx::thread, LogMessage>(1, a->get_id(), "second"));
  78. CHECK(a->transmit<ctx::thread, LogMessage>(1, a->get_id(), "third"));
  79. sup.process();
  80. CHECK(a->idx == 2);
  81. CHECK(a->msgs[0] == std::string_view("second"));
  82. CHECK(a->msgs[1] == std::string_view("third"));
  83. sup.stop();
  84. sup.process();
  85. CHECK(sup.get_state() == State::off);
  86. }