Commit 23e33b4f authored by Dominik Charousset's avatar Dominik Charousset

Add examples for request

parent 9b98c168
...@@ -26,9 +26,11 @@ add(custom_types_1 custom_types) ...@@ -26,9 +26,11 @@ add(custom_types_1 custom_types)
add(custom_types_2 custom_types) add(custom_types_2 custom_types)
add(custom_types_3 custom_types) add(custom_types_3 custom_types)
add(dancing_kirby message_passing) add(dancing_kirby message_passing)
add(request message_passing)
add(delegating message_passing) add(delegating message_passing)
add(fixed_stack message_passing) add(fixed_stack message_passing)
add(cell message_passing) add(cell message_passing)
add(divider message_passing)
add(hello_world .) add(hello_world .)
add(aout .) add(aout .)
add(calculator message_passing) add(calculator message_passing)
......
/******************************************************************************\
* A very basic, interactive divider. *
\******************************************************************************/
// This example is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 18-24, 34-47, and 62-72 (MessagePassing.tex)
#include <iostream>
#include "caf/all.hpp"
using std::cout;
using std::endl;
using std::flush;
using namespace caf;
enum class math_error : uint8_t {
division_by_zero = 1
};
error make_error(math_error x) {
return {static_cast<uint8_t>(x), atom("math")};
}
std::string to_string(math_error x) {
switch (x) {
case math_error::division_by_zero:
return "division_by_zero";
default:
return "-unknown-error-";
}
}
using div_atom = atom_constant<atom("add")>;
using divider = typed_actor<replies_to<div_atom, double, double>::with<double>>;
divider::behavior_type divider_impl() {
return {
[](div_atom, double x, double y) -> result<double> {
if (y == 0.0)
return math_error::division_by_zero;
return x / y;
}
};
}
int main() {
auto renderer = [](uint8_t x) {
return to_string(static_cast<math_error>(x));
};
actor_system_config cfg;
cfg.add_error_category(atom("math"), renderer);
actor_system system{cfg};
double x;
double y;
cout << "x: " << flush;
std::cin >> x;
cout << "y: " << flush;
std::cin >> y;
auto div = system.spawn(divider_impl);
scoped_actor self{system};
self->request(div, std::chrono::seconds(10), div_atom::value, x, y).receive(
[&](double z) {
aout(self) << x << " / " << y << " = " << z << endl;
},
[&](const error& err) {
aout(self) << "*** cannot compute " << x << " / " << y << " => "
<< system.render(err) << endl;
}
);
}
/******************************************************************************\
* Illustrates semantics of request().{then|await|receive}. *
\******************************************************************************/
// This example is partially included in the manual, do not modify
// without updating the references in the *.tex files!
// Manual references: lines 20-37, 39-51, 53-58, 62-64 (MessagePassing.tex)
#include <vector>
#include <chrono>
#include <iostream>
#include "caf/all.hpp"
using std::endl;
using std::vector;
using std::chrono::seconds;
using namespace caf;
using cell = typed_actor<reacts_to<put_atom, int>,
replies_to<get_atom>::with<int>>;
struct cell_state {
int value = 0;
};
cell::behavior_type cell_impl(cell::stateful_pointer<cell_state> self, int x0) {
self->state.value = x0;
return {
[=](put_atom, int val) {
self->state.value = val;
},
[=](get_atom) {
return self->state.value;
}
};
}
void waiting_testee(event_based_actor* self, vector<cell> cells) {
for (auto& x : cells)
self->request(x, seconds(1), get_atom::value).await([=](int y) {
aout(self) << "cell #" << x.id() << " -> " << y << endl;
});
}
void multiplexed_testee(event_based_actor* self, vector<cell> cells) {
for (auto& x : cells)
self->request(x, seconds(1), get_atom::value).then([=](int y) {
aout(self) << "cell #" << x.id() << " -> " << y << endl;
});
}
void blocking_testee(blocking_actor* self, vector<cell> cells) {
for (auto& x : cells)
self->request(x, seconds(1), get_atom::value).receive([&](int y) {
aout(self) << "cell #" << x.id() << " -> " << y << endl;
});
}
int main() {
actor_system system;
vector<cell> cells;
for (auto i = 0; i < 5; ++i)
cells.emplace_back(system.spawn(cell_impl, i * i));
scoped_actor self{system};
aout(self) << "waiting_testee" << endl;
self->spawn<monitored>(waiting_testee, cells);
self->receive([](const down_msg&) {});
aout(self) << "multiplexed_testee" << endl;
self->spawn<monitored>(multiplexed_testee, cells);
self->receive([](const down_msg&) {});
aout(self) << "blocking_testee" << endl;
system.spawn(blocking_testee, cells);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment