2018-12-31 20:04:05 +01:00
|
|
|
//
|
2024-01-01 01:07:21 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// 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 <type_traits>
|
|
|
|
|
|
|
|
namespace td {
|
2018-07-03 21:29:04 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
class Actor;
|
2018-07-03 21:29:04 +02:00
|
|
|
class ActorInfo;
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ActorType = Actor>
|
|
|
|
class ActorId {
|
|
|
|
public:
|
|
|
|
using ActorT = ActorType;
|
|
|
|
explicit ActorId(ObjectPool<ActorInfo>::WeakPtr ptr) : ptr_(ptr) {
|
|
|
|
}
|
|
|
|
ActorId() = default;
|
2023-05-05 12:51:19 +02:00
|
|
|
ActorId(const ActorId &) = default;
|
|
|
|
ActorId &operator=(const ActorId &) = default;
|
2021-10-18 13:36:15 +02:00
|
|
|
ActorId(ActorId &&other) noexcept : ptr_(other.ptr_) {
|
2022-10-01 10:29:09 +02:00
|
|
|
other.clear();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2021-10-18 13:36:15 +02:00
|
|
|
ActorId &operator=(ActorId &&other) noexcept {
|
2018-12-31 20:04:05 +01:00
|
|
|
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;
|
2022-10-01 22:48:03 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
ActorType *get_actor_unsafe() const;
|
|
|
|
|
|
|
|
Slice get_name() const;
|
|
|
|
|
|
|
|
template <class ToActorType, class = std::enable_if_t<std::is_base_of<ToActorType, ActorType>::value>>
|
|
|
|
explicit operator ActorId<ToActorType>() const {
|
|
|
|
return ActorId<ToActorType>(ptr_);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ObjectPool<ActorInfo>::WeakPtr ptr_;
|
|
|
|
};
|
|
|
|
|
2022-10-01 22:48:03 +02:00
|
|
|
// treat ActorId as pointer and ActorOwn as unique_ptr<ActorId>
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ActorType = Actor>
|
|
|
|
class ActorOwn {
|
|
|
|
public:
|
|
|
|
using ActorT = ActorType;
|
|
|
|
ActorOwn() = default;
|
2018-10-26 16:11:20 +02:00
|
|
|
explicit ActorOwn(ActorId<ActorType> id);
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class OtherActorType>
|
|
|
|
explicit ActorOwn(ActorId<OtherActorType> id);
|
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
explicit ActorOwn(ActorOwn<OtherActorType> &&other);
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
ActorOwn &operator=(ActorOwn<OtherActorType> &&other);
|
2021-10-18 13:36:15 +02:00
|
|
|
ActorOwn(ActorOwn &&other) noexcept;
|
|
|
|
ActorOwn &operator=(ActorOwn &&other) noexcept;
|
2023-05-05 12:51:19 +02:00
|
|
|
ActorOwn(const ActorOwn &) = delete;
|
|
|
|
ActorOwn &operator=(const ActorOwn &) = delete;
|
2018-12-31 20:04:05 +01:00
|
|
|
~ActorOwn();
|
|
|
|
|
|
|
|
bool empty() const;
|
|
|
|
bool is_alive() const {
|
|
|
|
return id_.is_alive();
|
|
|
|
}
|
|
|
|
ActorId<ActorType> get() const;
|
|
|
|
ActorId<ActorType> release();
|
|
|
|
void reset(ActorId<ActorType> other = ActorId<ActorType>());
|
2022-10-01 10:29:09 +02:00
|
|
|
ActorType *get_actor_unsafe() const;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
ActorId<ActorType> id_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class ActorType = Actor>
|
|
|
|
class ActorShared {
|
|
|
|
public:
|
|
|
|
using ActorT = ActorType;
|
|
|
|
ActorShared() = default;
|
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
ActorShared(ActorId<OtherActorType> id, uint64 token);
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
ActorShared(ActorShared<OtherActorType> &&other);
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
ActorShared(ActorOwn<OtherActorType> &&other);
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class OtherActorType>
|
2018-10-26 16:11:20 +02:00
|
|
|
ActorShared &operator=(ActorShared<OtherActorType> &&other);
|
2021-10-18 13:36:15 +02:00
|
|
|
ActorShared(ActorShared &&other) noexcept;
|
|
|
|
ActorShared &operator=(ActorShared &&other) noexcept;
|
2023-05-05 12:51:19 +02:00
|
|
|
ActorShared(const ActorShared &) = delete;
|
|
|
|
ActorShared &operator=(const ActorShared &) = delete;
|
2018-12-31 20:04:05 +01:00
|
|
|
~ActorShared();
|
|
|
|
|
|
|
|
uint64 token() const;
|
|
|
|
bool empty() const;
|
|
|
|
bool is_alive() const {
|
|
|
|
return id_.is_alive();
|
|
|
|
}
|
|
|
|
ActorId<ActorType> get() const;
|
|
|
|
ActorId<ActorType> release();
|
|
|
|
void reset(ActorId<ActorType> other = ActorId<ActorType>());
|
|
|
|
|
|
|
|
private:
|
|
|
|
ActorId<ActorType> id_;
|
2018-10-26 16:11:20 +02:00
|
|
|
uint64 token_ = 0;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class ActorRef {
|
|
|
|
public:
|
|
|
|
ActorRef() = default;
|
|
|
|
template <class T>
|
|
|
|
ActorRef(const ActorId<T> &actor_id);
|
|
|
|
template <class T>
|
2018-09-26 14:48:10 +02:00
|
|
|
ActorRef(ActorId<T> &&actor_id);
|
|
|
|
template <class T>
|
2018-12-31 20:04:05 +01:00
|
|
|
ActorRef(const ActorShared<T> &actor_id);
|
|
|
|
template <class T>
|
|
|
|
ActorRef(ActorShared<T> &&actor_id);
|
|
|
|
template <class T>
|
|
|
|
ActorRef(const ActorOwn<T> &actor_id);
|
|
|
|
template <class T>
|
|
|
|
ActorRef(ActorOwn<T> &&actor_id);
|
|
|
|
ActorId<> get() const {
|
|
|
|
return actor_id_;
|
|
|
|
}
|
|
|
|
uint64 token() const {
|
|
|
|
return token_;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ActorId<> actor_id_;
|
|
|
|
uint64 token_ = 0;
|
|
|
|
};
|
2018-07-03 21:29:04 +02:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
} // namespace td
|