013-observer.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //
  2. // Copyright (c) 2019-2021 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  3. //
  4. // Distributed under the MIT Software License
  5. //
  6. #include "rotor.hpp"
  7. #include "supervisor_test.h"
  8. #include "access.h"
  9. namespace r = rotor;
  10. namespace rt = r::test;
  11. struct foo_t {};
  12. struct simpleton_actor_t : public r::actor_base_t {
  13. using r::actor_base_t::actor_base_t;
  14. void configure(r::plugin::plugin_base_t &plugin) noexcept override {
  15. plugin.with_casted<r::plugin::starter_plugin_t>([](auto &p) { p.subscribe_actor(&simpleton_actor_t::on_foo); });
  16. }
  17. void on_start() noexcept override {
  18. r::actor_base_t::on_start();
  19. INFO("simpleton_actor_t::on_start()");
  20. send<foo_t>(address);
  21. }
  22. void on_foo(r::message_t<foo_t> &) noexcept {
  23. INFO("simpleton_actor_t::on_foo()");
  24. ++foo_count;
  25. }
  26. std::uint32_t foo_count = 0;
  27. };
  28. struct observer_config_t : r::actor_config_t {
  29. r::address_ptr_t observable;
  30. using r::actor_config_t::actor_config_t;
  31. };
  32. template <typename Actor> struct observer_config_builder_t : r::actor_config_builder_t<Actor> {
  33. using builder_t = typename Actor::template config_builder_t<Actor>;
  34. using parent_t = r::actor_config_builder_t<Actor>;
  35. using parent_t::parent_t;
  36. builder_t &&observable(const r::address_ptr_t &addr) {
  37. parent_t::config.observable = addr;
  38. return std::move(*static_cast<builder_t *>(this));
  39. }
  40. bool validate() noexcept override { return parent_t::config.observable && parent_t::validate(); }
  41. };
  42. struct foo_observer_t : public r::actor_base_t {
  43. using config_t = observer_config_t;
  44. template <typename Actor> using config_builder_t = observer_config_builder_t<Actor>;
  45. explicit foo_observer_t(config_t &cfg) : r::actor_base_t(cfg), simpleton_addr{cfg.observable} {}
  46. void configure(r::plugin::plugin_base_t &plugin) noexcept override {
  47. plugin.with_casted<r::plugin::starter_plugin_t>(
  48. [this](auto &p) { p.subscribe_actor(&foo_observer_t::on_foo, simpleton_addr); });
  49. }
  50. void on_foo(r::message_t<foo_t> &) noexcept {
  51. ++foo_count;
  52. INFO("foo_observer_t::on_foo");
  53. }
  54. r::address_ptr_t simpleton_addr;
  55. std::uint32_t foo_count = 0;
  56. };
  57. TEST_CASE("observer", "[actor]") {
  58. r::system_context_t system_context;
  59. auto sup = system_context.create_supervisor<rt::supervisor_test_t>().timeout(rt::default_timeout).finish();
  60. auto simpleton = sup->create_actor<simpleton_actor_t>().timeout(rt::default_timeout).finish();
  61. auto &simpleton_addr = simpleton->get_address();
  62. auto observer =
  63. sup->create_actor<foo_observer_t>().observable(simpleton_addr).timeout(rt::default_timeout).finish();
  64. sup->do_process();
  65. REQUIRE(simpleton->foo_count == 1);
  66. REQUIRE(observer->foo_count == 1);
  67. sup->do_shutdown();
  68. sup->do_process();
  69. REQUIRE(sup->get_state() == r::state_t::SHUT_DOWN);
  70. REQUIRE(sup->get_leader_queue().size() == 0);
  71. REQUIRE(sup->get_points().size() == 0);
  72. REQUIRE(rt::empty(sup->get_subscription()));
  73. }