The Breaking Cycles Manually section of the User Manual talks about actors having references to each other and how to avoid potential pitfalls in those scenarios. My question is how do you create a cycle to begin with? I frequently pass handles created by one spawn function into the parameters of another spawn function, but I'm struggling to figure out how to give two actors each other's handles:
#include<chrono>
#include<iostream>
#include <vector>
#include <string>
#include "caf/typed_event_based_actor.hpp"
#include "caf/scoped_actor.hpp"
#include "caf/caf_main.hpp"
#include "CustomMessages.h"
#include "../DuckParty/Displayable.h"
#include "../DuckParty/Duck.h"
#include "../DuckLibrary/Mallard.h"
#include "../DuckLibrary/TerminalDisplayer.h"
using namespace std::chrono;
using namespace std;
using DisplayActor = caf::typed_actor<
caf::result<void>(display_behavior, time_point<system_clock>, string)>;
using DuckActor = caf::typed_actor<
caf::result<void>(do_duck_behavior)>;
class DisplayState {
private:
unique_ptr<Displayable> displayable_;
public:
explicit DisplayState(unique_ptr<Displayable> displayable) : displayable_(move(displayable)) {}
DisplayActor::behavior_type make_behavior() {
return {
[this](display_behavior, time_point<system_clock> quack_time, string behavior) {
displayable_->DisplayBehavior(quack_time, behavior);
}
};
}
};
using DisplayImpl = DisplayActor::stateful_impl<DisplayState>;
class DuckState {
private:
DuckActor::pointer self_;
unique_ptr<Duck> duck_;
int milliseconds_;
DisplayActor display_actor_;
public:
explicit DuckState(DuckActor::pointer self, unique_ptr<Duck> duck, int milliseconds, DisplayActor display_actor) :
self_(self),
duck_(move(duck)),
milliseconds_(milliseconds),
display_actor_(display_actor) {}
DuckActor::behavior_type make_behavior() {
self_->send(self_, do_duck_behavior_v);
return {
[this](do_duck_behavior) {
self_->delayed_send(self_, std::chrono::milliseconds(milliseconds_), do_duck_behavior_v);
time_point<system_clock> quackTime = system_clock::now();
self_->send(display_actor_, display_behavior_v, quackTime, duck_->GetFlyBehavior() + " " + duck_->GetNoiseBehavior());
}
};
}
};
using DuckImpl = DuckActor::stateful_impl<DuckState>;
void caf_main(caf::actor_system& sys) {
unique_ptr<Duck> duck = make_unique<Mallard>("Howard the Duck");
unique_ptr<Displayable> display = make_unique<TerminalDisplayer>();
DisplayActor display_actor = sys.spawn<DisplayImpl>(move(display)); // How to give this actor a strong static reference to duck_actor?
DuckActor duck_actor = sys.spawn<DuckImpl>(move(duck), 500, display_actor);
}
CAF_MAIN(caf::id_block::duck_msg_types)
You can see in my main function, that I can easily give DuckActor a handle to DisplayActor but how do I also give DisplayActor a handle to DuckActor? Do you have any examples or advice regarding how to create a reference cycle? I'm afraid I'm missing something obvious.