Typed Message View¶
For the most part, users can write CAF applications without knowing about
message
. When sending messages between actors, CAF automatically wraps the
content for the message into this type-erased container and then matches each
incoming message against the message handlers.
However, there are use cases for message
outside of the dispatching logic in
CAF. For example, actors can store messages that they currently don’t want to
(or cannot) process in some cache for processing them later. Or an application
could read messages from custom data sources and then deploy on their run-time
type.
For such use cases, CAF includes typed message views. On construction, a view
performs the necessary type checking. On a match, users can then query
individual elements from the view via get<Index>(x)
, much like the interface
offered by std::tuple
.
Internally, messages use copy-on-write (see Copy-on-Write Types). Hence,
there are two flavors of typed message views: const
views that represent
read-only access and views with mutable access. The latter forces the message to
perform a deep copy of its data if there is more to one reference to the data.
To cut a long story short, we recommend sticking to the const
version
whenever possible.
For both view types, the simplest way of using them is to construct a view
object and then check whether it is valid. The const
version is called
const_typed_message_view
:
auto msg1 = caf::make_message("hello", "world");
auto msg2 = msg1;
if (auto v = caf::const_typed_message_view<std::string, std::string>{msg1})
sys.println("v: {}, {}", caf::get<0>(v), caf::get<1>(v));
// Both messages still point to the same data.
assert(msg1.cptr() == msg2.cptr());
The mutable version is simply called typed_message_view
, but otherwise has a
similar interface:
auto msg1 = caf::make_message("hello", "world");
auto msg2 = msg1;
if (auto v = caf::typed_message_view<std::string, std::string>{msg1}) {
caf::get<0>(v) = "bye";
sys.println("v: {}, {}", caf::get<0>(v), caf::get<1>(v));
}
// The messages no longer point to the same data.
assert(msg1.cptr() != msg2.cptr());