Header files for TDLib 1.7

This commit is contained in:
Sebastian Wolf 2020-12-06 22:03:08 +01:00
parent f6d72d8ef1
commit aafe7c1308
5 changed files with 5120 additions and 2518 deletions

View file

@ -22,10 +22,10 @@ namespace td {
* The TDLib instance is created for the lifetime of the Client object.
* Requests to TDLib can be sent using the Client::send method from any thread.
* New updates and responses to requests can be received using the Client::receive method from any thread,
* this function shouldn't be called simultaneously from two different threads. Also note that all updates and
* this function must not be called simultaneously from two different threads. Also note that all updates and
* responses to requests should be applied in the same order as they were received, to ensure consistency.
* Given this information, it's advisable to call this function from a dedicated thread.
* Some service TDLib requests can be executed synchronously from any thread by using the Client::execute method.
* Some service TDLib requests can be executed synchronously from any thread using the Client::execute method.
*
* General pattern of usage:
* \code
@ -84,7 +84,7 @@ class Client final {
*/
struct Response {
/**
* TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
* TDLib request identifier, which corresponds to the response, or 0 for incoming updates from TDLib.
*/
std::uint64_t id;
@ -131,4 +131,138 @@ class Client final {
std::unique_ptr<Impl> impl_;
};
/**
* The future native C++ interface for interaction with TDLib.
*
* A TDLib client instance can be created through the method ClientManager::create_client_id.
* Requests can be sent using the method ClientManager::send from any thread.
* New updates and responses to requests can be received using the method ClientManager::receive from any thread after
* the first request has been sent to the client instance. ClientManager::receive must not be called simultaneously from
* two different threads. Also note that all updates and responses to requests should be applied in the same order as
* they were received, to ensure consistency.
* Some TDLib requests can be executed synchronously from any thread using the method ClientManager::execute.
*
* General pattern of usage:
* \code
* td::ClientManager manager;
* auto client_id = manager.create_client_id();
* // somehow share the manager and the client_id with other threads,
* // which will be able to send requests via manager.send(client_id, ...)
*
* // send some dummy requests to the new instance to activate it
* manager.send(client_id, ...);
*
* const double WAIT_TIMEOUT = 10.0; // seconds
* while (true) {
* auto response = manager.receive(WAIT_TIMEOUT);
* if (response.object == nullptr) {
* continue;
* }
*
* if (response.request_id == 0) {
* // process response.object as an incoming update of the type td_api::Update for the client response.client_id
* } else {
* // process response.object as an answer to a request response.request_id for the client response.client_id
* }
* }
* \endcode
*/
class ClientManager final {
public:
/**
* Creates a new TDLib client manager.
*/
ClientManager();
/**
* Opaque TDLib client instance identifier.
*/
using ClientId = std::int32_t;
/**
* Request identifier.
* Responses to TDLib requests will have the same request id as the corresponding request.
* Updates from TDLib will have the request_id == 0, incoming requests are thus not allowed to have request_id == 0.
*/
using RequestId = std::uint64_t;
/**
* Returns an opaque identifier of a new TDLib instance.
* The TDLib instance will not send updates until the first request is sent to it.
* \return Opaque identifier of a new TDLib instance.
*/
ClientId create_client_id();
/**
* Sends request to TDLib. May be called from any thread.
* \param[in] client_id TDLib client instance identifier.
* \param[in] request_id Request identifier. Must be non-zero.
* \param[in] request Request to TDLib.
*/
void send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request);
/**
* A response to a request, or an incoming update from TDLib.
*/
struct Response {
/**
* TDLib client instance identifier, for which the response was received.
*/
ClientId client_id;
/**
* Request identifier, to which the response corresponds, or 0 for incoming updates from TDLib.
*/
RequestId request_id;
/**
* TDLib API object representing a response to a TDLib request or an incoming update.
*/
td_api::object_ptr<td_api::Object> object;
};
/**
* Receives incoming updates and responses to requests from TDLib. May be called from any thread, but must not be
* called simultaneously from two different threads.
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
* \return An incoming update or response to a request. The object returned in the response may be a nullptr
* if the timeout expires.
*/
Response receive(double timeout);
/**
* Synchronously executes a TDLib request.
* A request can be executed synchronously, only if it is documented with "Can be called synchronously".
* \param[in] request Request to the TDLib.
* \return The request response.
*/
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> &&request);
/**
* Destroys the client manager and all TDLib client instances managed by it.
*/
~ClientManager();
/**
* Move constructor.
*/
ClientManager(ClientManager &&other);
/**
* Move assignment operator.
*/
ClientManager &operator=(ClientManager &&other);
/**
* Returns a pointer to a singleton ClientManager instance.
* \return A unique singleton ClientManager instance.
*/
static ClientManager *get_manager_singleton();
private:
friend class Client;
class Impl;
std::unique_ptr<Impl> impl_;
};
} // namespace td

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -13,19 +13,19 @@
* and is able to work with JSON.
*
* The JSON serialization of TDLib API objects is straightforward: all API objects are represented as JSON objects with
* the same keys as the API object field names. The object type name is stored in the special field '@type' which is
* the same keys as the API object field names. The object type name is stored in the special field "@type" which is
* optional in places where type is uniquely determined by the context.
* Fields of Bool type are stored as Boolean, fields of int32, int53, and double types are stored as Number, fields of
* int64 and string types are stored as String, fields of bytes type are base64 encoded and then stored as String,
* fields of vector type are stored as Array.
* fields of array type are stored as Array.
* The main TDLib interface is asynchronous. To match requests with a corresponding response a field "@extra" can
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
*
* A TDLib client instance should be created through td_json_client_create.
* A TDLib client instance can be created through td_json_client_create.
* Requests then can be sent using td_json_client_send from any thread.
* New updates and request responses can be received through td_json_client_receive from any thread. This function
* shouldn't be called simultaneously from two different threads. Also note that all updates and request responses
* should be applied in the order they were received to ensure consistency.
* must not be called simultaneously from two different threads. Also note that all updates and request responses
* must be applied in the order they were received to ensure consistency.
* Given this information, it's advisable to call this function from a dedicated thread.
* Some service TDLib requests can be executed synchronously from any thread by using td_json_client_execute.
* The TDLib client instance can be destroyed via td_json_client_destroy.
@ -68,7 +68,7 @@ TDJSON_EXPORT void td_json_client_send(void *client, const char *request);
/**
* Receives incoming updates and request responses from the TDLib client. May be called from any thread, but
* shouldn't be called simultaneously from two different threads.
* must not be called simultaneously from two different threads.
* Returned pointer will be deallocated by TDLib during next call to td_json_client_receive or td_json_client_execute
* in the same thread, so it can't be used after that.
* \param[in] client The client.
@ -84,16 +84,78 @@ TDJSON_EXPORT const char *td_json_client_receive(void *client, double timeout);
* in the same thread, so it can't be used after that.
* \param[in] client The client. Currently ignored for all requests, so NULL can be passed.
* \param[in] request JSON-serialized null-terminated request to TDLib.
* \return JSON-serialized null-terminated request response. May be NULL if the request can't be parsed.
* \return JSON-serialized null-terminated request response.
*/
TDJSON_EXPORT const char *td_json_client_execute(void *client, const char *request);
/**
* Destroys the TDLib client instance. After this is called the client instance shouldn't be used anymore.
* Destroys the TDLib client instance. After this is called the client instance must not be used anymore.
* \param[in] client The client.
*/
TDJSON_EXPORT void td_json_client_destroy(void *client);
/*
* New TDLib JSON interface.
*
* The main TDLib interface is asynchronous. To match requests with a corresponding response, the field "@extra" can
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
* Each returned object will have an "@client_id" field, containing the identifier of the client for which
* a response or an update was received.
*
* A TDLib client instance can be created through td_create_client_id.
* Requests can be sent using td_send and the received client identifier.
* New updates and responses to requests can be received through td_receive from any thread after the first request
* has been sent to the client instance. This function must not be called simultaneously from two different threads.
* Also note that all updates and responses to requests must be applied in the order they were received for consistency.
* Some TDLib requests can be executed synchronously from any thread using td_execute.
* TDLib client instances are destroyed automatically after they are closed.
*
* General pattern of usage:
* \code
* int client_id = td_create_client_id();
* // share the client_id with other threads, which will be able to send requests via td_send
*
* const double WAIT_TIMEOUT = 10.0; // seconds
* while (true) {
* const char *result = td_receive(WAIT_TIMEOUT);
* if (result) {
* // parse the result as a JSON object and process it as an incoming update or the answer to a previously sent request
* }
* }
* \endcode
*/
/**
* Returns an opaque identifier of a new TDLib instance.
* The TDLib instance will not send updates until the first request is sent to it.
* \return Opaque identifier of a new TDLib instance.
*/
TDJSON_EXPORT int td_create_client_id();
/**
* Sends request to the TDLib client. May be called from any thread.
* \param[in] client_id TDLib client identifier.
* \param[in] request JSON-serialized null-terminated request to TDLib.
*/
TDJSON_EXPORT void td_send(int client_id, const char *request);
/**
* Receives incoming updates and request responses. Must not be called simultaneously from two different threads.
* The returned pointer can be used until the next call to td_receive or td_execute, after which it will be deallocated by TDLib.
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
* \return JSON-serialized null-terminated incoming update or request response. May be NULL if the timeout expires.
*/
TDJSON_EXPORT const char *td_receive(double timeout);
/**
* Synchronously executes a TDLib request.
* A request can be executed synchronously, only if it is documented with "Can be called synchronously".
* The returned pointer can be used until the next call to td_receive or td_execute, after which it will be deallocated by TDLib.
* \param[in] request JSON-serialized null-terminated request to TDLib.
* \return JSON-serialized null-terminated request response.
*/
TDJSON_EXPORT const char *td_execute(const char *request);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -13,7 +13,6 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
@ -88,9 +87,7 @@ class TlObject {
virtual ~TlObject() = default;
};
/**
* A smart wrapper to store a pointer to a TL-object.
*/
/// @cond UNDOCUMENTED
namespace tl {
template <class T>
@ -116,15 +113,16 @@ class unique_ptr {
}
explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) {
}
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
template <class S, class = typename std::enable_if<std::is_base_of<T, S>::value>::type>
unique_ptr(unique_ptr<S> &&other) noexcept : ptr_(static_cast<S *>(other.release())) {
}
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
template <class S, class = typename std::enable_if<std::is_base_of<T, S>::value>::type>
unique_ptr &operator=(unique_ptr<S> &&other) noexcept {
reset(static_cast<T *>(other.release()));
return *this;
}
void reset(T *new_ptr = nullptr) noexcept {
static_assert(sizeof(T) > 0, "Can't destroy unique_ptr with incomplete type");
delete ptr_;
ptr_ = new_ptr;
}
@ -177,6 +175,11 @@ bool operator!=(const unique_ptr<T> &p, std::nullptr_t) {
}
} // namespace tl
/// @endcond
/**
* A smart wrapper to store a pointer to a TL-object.
*/
template <class Type>
using tl_object_ptr = tl::unique_ptr<Type>;
@ -186,8 +189,8 @@ using tl_object_ptr = tl::unique_ptr<Type>;
* \code
* auto get_authorization_state_request = td::make_tl_object<td::td_api::getAuthorizationState>();
* auto message_text = td::make_tl_object<td::td_api::formattedText>("Hello, world!!!",
* std::vector<td::tl_object_ptr<td::td_api::textEntity>>());
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, nullptr, nullptr,
* td::td_api::array<td::tl_object_ptr<td::td_api::textEntity>>());
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, 0, nullptr, nullptr,
* td::make_tl_object<td::td_api::inputMessageText>(std::move(message_text), false, true));
* \endcode
*