2018-12-31 20:04:05 +01:00
|
|
|
//
|
2018-01-02 14:42:31 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
|
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;
|
|
|
|
ActorId(const ActorId &) = default;
|
|
|
|
ActorId &operator=(const ActorId &) = 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 <class ToActorType, class = std::enable_if_t<std::is_base_of<ToActorType, ActorType>::value>>
|
|
|
|
explicit operator ActorId<ToActorType>() const {
|
|
|
|
return ActorId<ToActorType>(ptr_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class AsActorType>
|
|
|
|
ActorId<AsActorType> as() const {
|
|
|
|
return ActorId<AsActorType>(ptr_);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ObjectPool<ActorInfo>::WeakPtr ptr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// threat ActorId as pointer and ActorOwn as
|
|
|
|
// unique_ptr<ActorId>
|
|
|
|
template <class ActorType = Actor>
|
|
|
|
class ActorOwn {
|
|
|
|
public:
|
|
|
|
using ActorT = ActorType;
|
|
|
|
ActorOwn() = default;
|
|
|
|
explicit ActorOwn(ActorId<ActorType>);
|
|
|
|
template <class OtherActorType>
|
|
|
|
explicit ActorOwn(ActorId<OtherActorType> id);
|
|
|
|
template <class OtherActorType>
|
|
|
|
explicit ActorOwn(ActorOwn<OtherActorType> &&);
|
|
|
|
template <class OtherActorType>
|
|
|
|
ActorOwn &operator=(ActorOwn<OtherActorType> &&);
|
|
|
|
ActorOwn(ActorOwn &&);
|
|
|
|
ActorOwn &operator=(ActorOwn &&);
|
|
|
|
ActorOwn(const ActorOwn &) = delete;
|
|
|
|
ActorOwn &operator=(const ActorOwn &) = delete;
|
|
|
|
~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>());
|
|
|
|
void hangup() const;
|
|
|
|
const ActorId<ActorType> *operator->() const;
|
|
|
|
|
|
|
|
using ActorIdConstRef = const ActorId<ActorType> &;
|
|
|
|
// operator ActorIdConstRef();
|
|
|
|
|
|
|
|
private:
|
|
|
|
ActorId<ActorType> id_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class ActorType = Actor>
|
|
|
|
class ActorShared {
|
|
|
|
public:
|
|
|
|
using ActorT = ActorType;
|
|
|
|
ActorShared() = default;
|
|
|
|
template <class OtherActorType>
|
|
|
|
ActorShared(ActorId<OtherActorType>, uint64 token);
|
|
|
|
template <class OtherActorType>
|
|
|
|
ActorShared(ActorShared<OtherActorType> &&);
|
|
|
|
template <class OtherActorType>
|
|
|
|
ActorShared(ActorOwn<OtherActorType> &&);
|
|
|
|
template <class OtherActorType>
|
|
|
|
ActorShared &operator=(ActorShared<OtherActorType> &&);
|
|
|
|
ActorShared(ActorShared &&);
|
|
|
|
ActorShared &operator=(ActorShared &&);
|
|
|
|
ActorShared(const ActorShared &) = delete;
|
|
|
|
ActorShared &operator=(const ActorShared &) = delete;
|
|
|
|
~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>());
|
|
|
|
template <class OtherActorType>
|
|
|
|
void reset(ActorId<OtherActorType> other);
|
|
|
|
const ActorId<ActorType> *operator->() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
ActorId<ActorType> id_;
|
|
|
|
uint64 token_;
|
|
|
|
};
|
|
|
|
|
|
|
|
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
|