/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2019 Telegram Systems LLP */ #pragma once #include "td/actor/common.h" #include "td/actor/ActorId.h" namespace td { namespace actor { template class ActorShared { public: using ActorT = ActorType; ActorShared() = default; template ActorShared(ActorId id, uint64 token) : id_(std::move(id)), token_(token) { CHECK(token_ != 0); } template ActorShared(ActorShared &&other) : id_(other.release()), token_(other.token()) { } template ActorShared(ActorOwn &&other) : id_(other.release()), token_(other.token()) { } template ActorShared &operator=(ActorShared &&other) { reset(other.release(), other.token()); } ActorShared(ActorShared &&other) : id_(other.release()), token_(other.token()) { } ActorShared &operator=(ActorShared &&other) { reset(other.release(), other.token()); return *this; } ActorShared(const ActorShared &) = delete; ActorShared &operator=(const ActorShared &) = delete; ~ActorShared() { reset(); } uint64 token() const { return token_; } bool empty() const { return id_.empty(); } bool is_alive() const { return id_.is_alive(); } ActorId get() const { return id_; } ActorId release() { return std::move(id_); } ActorType &get_actor_unsafe() const { return (*this)->get_actor_unsafe(); } void reset(ActorId other = ActorId(), uint64 link_token = core::EmptyLinkToken) { static_assert(sizeof(ActorType) > 0, "Can't use ActorShared with incomplete type"); hangup(); id_ = other; token_ = link_token; } const ActorId *operator->() const { return &id_; } detail::ActorRef as_actor_ref() const { CHECK(!empty()); return detail::ActorRef(*id_.actor_info_ptr(), token_); } private: ActorId id_; uint64 token_; void hangup() const { if (empty()) { return; } detail::send_message(as_actor_ref(), detail::ActorMessageCreator::hangup_shared()); } }; template ActorShared actor_dynamic_cast(ActorShared from) { return ActorShared(td::actor::actor_dynamic_cast(from.release()), from.token()); } // common interface namespace core { // for ADL template ActorShared actor_shared(SelfT *self, uint64 id = static_cast(-1)) { return ActorShared(actor_id(self), id); } inline ActorShared<> actor_shared() { return actor_shared(&core::ActorExecuteContext::get()->actor()); } } // namespace core using core::actor_shared; } // namespace actor } // namespace td