#pragma once #include #include #include #include #include #include #include namespace mbgl { template class EstablishedActor; template class Actor; /* An `AspiringActor` is one half of the pair of types that comprise an actor (see `Actor`), the other half being `EstablishedActor`. It is responsible for: - ownership of the actor's `Mailbox` - allocating the memory for (but *not* constructing) the target object `O` Using these two pieces--the mailbox and a stable address for `O`--an `AspiringActor` can accept messages for the target object, or provide `ActorRef`s that do so, before the object has actually been constructed by the corresponding `EstablishedActor`. (Such messages are queued in the mailbox until after the object is constructed.) This allows for an `AspiringActor` to be created and safely used by a thread other than the one on which the target object will (eventually) live. */ template class AspiringActor { public: AspiringActor() : mailbox(std::make_shared()) { // mailbox starts closed because the `Object` hasn't yet been constructed assert(!mailbox->isOpen()); } AspiringActor(const AspiringActor&) = delete; ActorRef> self() { return ActorRef>(object(), mailbox); } private: std::shared_ptr mailbox; std::aligned_storage_t objectStorage; Object& object() { return *reinterpret_cast(&objectStorage); } friend class EstablishedActor; friend class Actor; }; } // namespace mbgl