// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/utils/ObjectPool.h" #include "td/utils/Slice.h" #include namespace td { class Actor; class ActorInfo; template class ActorId { public: using ActorT = ActorType; explicit ActorId(ObjectPool::WeakPtr ptr) : ptr_(ptr) { } ActorId() = default; ActorId(const ActorId &other) = default; ActorId &operator=(const ActorId &other) = default; ActorId(ActorId &&other) : ptr_(other.ptr_) { other.ptr_.clear(); } ActorId &operator=(ActorId &&other) { if (&other == this) { return *this; } ptr_ = other.ptr_; other.clear(); return *this; } ~ActorId() = default; bool empty() const { return ptr_.empty(); } void clear() { ptr_.clear(); } bool is_alive() const { return ptr_.is_alive_unsafe(); } ActorInfo *get_actor_info() const; ActorType *get_actor_unsafe() const; // returns pointer to actor if it is on current thread. nullptr otherwise ActorType *try_get_actor() const; Slice get_name() const; template ::value>> explicit operator ActorId() const { return ActorId(ptr_); } template ActorId as() const { return ActorId(ptr_); } private: ObjectPool::WeakPtr ptr_; }; // threat ActorId as pointer and ActorOwn as // unique_ptr template class ActorOwn { public: using ActorT = ActorType; ActorOwn() = default; explicit ActorOwn(ActorId id); template explicit ActorOwn(ActorId id); template explicit ActorOwn(ActorOwn &&other); template ActorOwn &operator=(ActorOwn &&other); ActorOwn(ActorOwn &&other); ActorOwn &operator=(ActorOwn &&other); ActorOwn(const ActorOwn &other) = delete; ActorOwn &operator=(const ActorOwn &other) = delete; ~ActorOwn(); bool empty() const; bool is_alive() const { return id_.is_alive(); } ActorId get() const; ActorId release(); void reset(ActorId other = ActorId()); void hangup() const; const ActorId *operator->() const; using ActorIdConstRef = const ActorId &; // operator ActorIdConstRef(); private: ActorId id_; }; template class ActorShared { public: using ActorT = ActorType; ActorShared() = default; template ActorShared(ActorId id, uint64 token); template ActorShared(ActorShared &&other); template ActorShared(ActorOwn &&other); template ActorShared &operator=(ActorShared &&other); ActorShared(ActorShared &&other); ActorShared &operator=(ActorShared &&other); ActorShared(const ActorShared &other) = delete; ActorShared &operator=(const ActorShared &other) = delete; ~ActorShared(); uint64 token() const; bool empty() const; bool is_alive() const { return id_.is_alive(); } ActorId get() const; ActorId release(); void reset(ActorId other = ActorId()); template void reset(ActorId other); const ActorId *operator->() const; private: ActorId id_; uint64 token_ = 0; }; class ActorRef { public: ActorRef() = default; template ActorRef(const ActorId &actor_id); template ActorRef(ActorId &&actor_id); template ActorRef(const ActorShared &actor_id); template ActorRef(ActorShared &&actor_id); template ActorRef(const ActorOwn &actor_id); template ActorRef(ActorOwn &&actor_id); ActorId<> get() const { return actor_id_; } uint64 token() const { return token_; } private: ActorId<> actor_id_; uint64 token_ = 0; }; } // namespace td