1#pragma once
2
3#include <mbgl/actor/mailbox.hpp>
4#include <mbgl/actor/message.hpp>
5
6#include <memory>
7
8namespace mbgl {
9
10/*
11 An `ActorRef<O>` is a *non*-owning, weak reference to an actor of type `O`. You can send it
12 messages just like an `Actor<O>`. It's a value object: safe to copy and pass between actors
13 via messages.
14
15 An `ActorRef<O>` does not extend the lifetime of the corresponding `Actor<O>`. That's determined
16 entirely by whichever object owns the `Actor<O>` -- the actor's "supervisor".
17
18 It's safe for a `Ref` to outlive its `Actor` -- the reference is "weak", and does not extend
19 the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
20 a no-op. (In the future, a dead-letters queue or log may be implemented.)
21*/
22
23template <class Object>
24class ActorRef {
25public:
26 ActorRef(Object& object_, std::weak_ptr<Mailbox> weakMailbox_)
27 : object(&object_),
28 weakMailbox(std::move(weakMailbox_)) {
29 }
30
31 template <typename Fn, class... Args>
32 void invoke(Fn fn, Args&&... args) {
33 if (auto mailbox = weakMailbox.lock()) {
34 mailbox->push(actor::makeMessage(*object, fn, std::forward<Args>(args)...));
35 }
36 }
37
38 template <typename Fn, class... Args>
39 auto ask(Fn fn, Args&&... args) {
40 // Result type is deduced from the function's return type
41 using ResultType = typename std::result_of<decltype(fn)(Object, Args...)>::type;
42
43 std::promise<ResultType> promise;
44 auto future = promise.get_future();
45
46 if (auto mailbox = weakMailbox.lock()) {
47 mailbox->push(
48 actor::makeMessage(
49 std::move(promise), *object, fn, std::forward<Args>(args)...
50 )
51 );
52 } else {
53 promise.set_exception(std::make_exception_ptr(ex: std::runtime_error("Actor has gone away")));
54 }
55
56 return future;
57 }
58
59private:
60 Object* object;
61 std::weak_ptr<Mailbox> weakMailbox;
62};
63
64} // namespace mbgl
65

source code of qtlocation/src/3rdparty/mapbox-gl-native/include/mbgl/actor/actor_ref.hpp