1#pragma once
2
3#include <mbgl/actor/aspiring_actor.hpp>
4#include <mbgl/actor/mailbox.hpp>
5#include <mbgl/actor/message.hpp>
6#include <mbgl/actor/actor_ref.hpp>
7
8#include <memory>
9#include <future>
10#include <type_traits>
11#include <cassert>
12
13namespace mbgl {
14
15/*
16 An `EstablishedActor<O>` is one half of the pair of types that comprise an actor (see `Actor<O>`),
17 the other half being `AspiringActor<O>`. It is responsible for managing the lifetime of the
18 target object `O` and the open/closed state of the parent's `mailbox`.
19
20 The `O` object's lifetime is contained by that of its owning `EstablishedActor<O>`: the
21 `EstablishedActor` constructor executes the `O` constructor via "placement new", constructing
22 it at the address provided by the parent `AspiringActor`, and the `~EstablishedActor` destructor
23 similarly executes the `~O` destructor (after closing the mailbox). `EstablishedActor` should
24 therefore live entirely on the thread intended to own `O`.
25*/
26
27template <class Object>
28class EstablishedActor {
29public:
30 // Construct the Object from a parameter pack `args` (i.e. `Object(args...)`)
31 template <typename U = Object, class... Args, typename std::enable_if<
32 std::is_constructible<U, Args...>::value ||
33 std::is_constructible<U, ActorRef<U>, Args...>::value
34 >::type * = nullptr>
35 EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, Args&& ... args)
36 : parent(parent_) {
37 emplaceObject(std::forward<Args>(args)...);
38 parent.mailbox->open(scheduler);
39 }
40
41 // Construct the `Object` from a tuple containing the constructor arguments (i.e.
42 // `Object(std::get<0>(args), std::get<1>(args), ...)`)
43 template <class ArgsTuple, std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value>
44 EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args)
45 : parent(parent_) {
46 emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
47 parent.mailbox->open(scheduler);
48 }
49
50 EstablishedActor(const EstablishedActor&) = delete;
51
52 ~EstablishedActor() {
53 parent.mailbox->close();
54 parent.object().~Object();
55 }
56
57private:
58 // Enabled for Objects with a constructor taking ActorRef<Object> as the first parameter
59 template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
60 void emplaceObject(Args&&... args_) {
61 new (&parent.objectStorage) Object(parent.self(), std::forward<Args>(args_)...);
62 }
63
64 // Enabled for plain Objects
65 template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, Args...>::value>::type * = nullptr>
66 void emplaceObject(Args&&... args_) {
67 new (&parent.objectStorage) Object(std::forward<Args>(args_)...);
68 }
69
70 // Used to expand a tuple holding the constructor arguments
71 template <class ArgsTuple, std::size_t... I>
72 void emplaceObject(ArgsTuple&& args, std::index_sequence<I...>) {
73 emplaceObject(std::move(std::get<I>(std::forward<ArgsTuple>(args)))...);
74 (void) args; // mark args as used: if it's empty tuple, it's not actually used above.
75 }
76
77 AspiringActor<Object>& parent;
78};
79
80} // namespace mbgl
81

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