Merge remote-tracking branch 'td/master'

This commit is contained in:
Andrea Cavalli 2021-12-28 19:12:09 +01:00
commit 53d4e14c7d
33 changed files with 206 additions and 228 deletions

View File

@ -60,6 +60,8 @@ function(td_set_up_compiler)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(TD_LINKER_FLAGS "-Wl,-z,ignore")
elseif (EMSCRIPTEN)
set(TD_LINKER_FLAGS "-Wl,--gc-sections")
else()
set(TD_LINKER_FLAGS "-Wl,--gc-sections -Wl,--exclude-libs,ALL")
endif()

View File

@ -6,7 +6,7 @@ if (POLICY CMP0065)
cmake_policy(SET CMP0065 NEW)
endif()
project(TDLib VERSION 1.7.11 LANGUAGES CXX C)
project(TDLib VERSION 1.7.12 LANGUAGES CXX C)
if (NOT DEFINED CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH "")

View File

@ -130,7 +130,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic)
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
```
find_package(Td 1.7.11 REQUIRED)
find_package(Td 1.7.12 REQUIRED)
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
```
See [example/cpp/CMakeLists.txt](https://github.com/tdlight-team/tdlight/tree/master/example/cpp/CMakeLists.txt).

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
project(TdExample VERSION 1.0 LANGUAGES CXX)
find_package(Td 1.7.11 REQUIRED)
find_package(Td 1.7.12 REQUIRED)
add_executable(tdjson_example tdjson_example.cpp)
target_link_libraries(tdjson_example PRIVATE Td::TdJson)

View File

@ -598,4 +598,4 @@ public final class Example {
}
}
}
}
}

View File

@ -40,6 +40,7 @@ _td_set_log_message_callback.restype = None
_td_set_log_message_callback.argtypes = [c_int, log_message_callback_type]
# initialize TDLib log with desired parameters
@log_message_callback_type
def on_log_message_callback(verbosity_level, message):
if verbosity_level == 0:
sys.exit('TDLib fatal error: %r' % message)
@ -51,8 +52,7 @@ def td_execute(query):
result = json.loads(result.decode('utf-8'))
return result
c_on_log_message_callback = log_message_callback_type(on_log_message_callback)
_td_set_log_message_callback(2, c_on_log_message_callback)
_td_set_log_message_callback(2, on_log_message_callback)
# setting TDLib log verbosity level to 1 (errors)
print(str(td_execute({'@type': 'setLogVerbosityLevel', 'new_verbosity_level': 1, '@extra': 1.01234})).encode('utf-8'))
@ -73,7 +73,7 @@ def td_receive():
return result
# another test for TDLib execute method
print(str(td_execute({'@type': 'getTextEntities', 'text': '@telegram /test_command https://telegram.org telegram.me', '@extra': ['5', 7.0, 'ä']})).encode('utf-8'))
print(str(td_execute({'@type': 'getTextEntities', 'text': '@telegram /test_command https://telegram.org telegram.me', '@extra': ['5', 7.0, 'a']})).encode('utf-8'))
# start the client by sending request to it
td_send({'@type': 'getAuthorizationState', '@extra': 1.01234})

View File

@ -26,4 +26,4 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: ComVisible(false)]

View File

@ -1,6 +1,6 @@
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
<Metadata>
<Identity Id="Telegram.Td.UWP" Version="1.7.11" Language="en-US" Publisher="Telegram LLC" />
<Identity Id="Telegram.Td.UWP" Version="1.7.12" Language="en-US" Publisher="Telegram LLC" />
<DisplayName>TDLib for Universal Windows Platform</DisplayName>
<Description>TDLib is a library for building Telegram clients</Description>
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>

View File

@ -7,7 +7,7 @@ You need a Unix shell with `sed`, `tar` and `wget` utilities to run the provided
## Building tdweb NPM package
* Install the 2.0.6 [emsdk](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html), which is known to work. Do not use the system-provided `emscripten` package, because it contains a too old emsdk version.
* Install all `TDLib` build dependencies described in [Building](https://github.com/tdlib/td#building).
* Install all `TDLib` build dependencies described in [Building](https://github.com/tdlib/td#building) and `sed`, `tar` and `wget` utilities.
* Run `source ./emsdk_env.sh` from `emsdk` directory to set up the correct build environment.
* On `macOS`, install the `coreutils` [Homebrew](https://brew.sh) package and replace `realpath` in scripts with `grealpath`:
```

View File

@ -135,7 +135,7 @@ temporaryPasswordState has_password:Bool valid_for:int32 = TemporaryPasswordStat
//@description Represents a local file
//@path Local path to the locally available file part; may be empty
//@can_be_downloaded True, if it is possible to try to download or generate the file
//@can_be_downloaded True, if it is possible to download or generate the file
//@can_be_deleted True, if the file can be deleted
//@is_downloading_active True, if the file is currently being downloaded (or a local copy is being generated by some other means)
//@is_downloading_completed True, if the local copy is fully available
@ -734,9 +734,9 @@ messageSenders total_count:int32 senders:vector<MessageSender> = MessageSenders;
//@description The message was originally sent by a known user @sender_user_id Identifier of the user that originally sent the message
messageForwardOriginUser sender_user_id:int53 = MessageForwardOrigin;
//@description The message was originally sent by an anonymous chat administrator on behalf of the chat
//@description The message was originally sent on behalf of a chat
//@sender_chat_id Identifier of the chat that originally sent the message
//@author_signature Original message author signature
//@author_signature For messages originally sent by an anonymous chat administrator, original message author signature
messageForwardOriginChat sender_chat_id:int53 author_signature:string = MessageForwardOrigin;
//@description The message was originally sent by a user, which is hidden by their privacy settings @sender_name Name of the sender
@ -844,11 +844,11 @@ messageCalendar total_count:int32 days:vector<messageCalendarDay> = MessageCalen
//@description Describes a sponsored message
//@id Unique sponsored message identifier
//@message_id Message identifier; unique for the chat to which the sponsored message belongs among both ordinary and sponsored messages
//@sponsor_chat_id Chat identifier
//@link An internal link to be opened when the sponsored message is clicked; may be null. If null, the sponsor chat needs to be opened instead
//@content Content of the message. Currently, can be only of the type messageText
sponsoredMessage id:int32 sponsor_chat_id:int53 link:InternalLinkType content:MessageContent = SponsoredMessage;
sponsoredMessage message_id:int53 sponsor_chat_id:int53 link:InternalLinkType content:MessageContent = SponsoredMessage;
//@class NotificationSettingsScope @description Describes the types of chats to which notification settings are relevant
@ -2042,7 +2042,7 @@ inputMessagePoll question:string options:vector<string> is_anonymous:Bool type:P
//@description A forwarded message @from_chat_id Identifier for the chat this forwarded message came from @message_id Identifier of the message to forward
//@in_game_share True, if a game message is being shared from a launched game; applies only to game messages
//@copy_options Options to be used to copy content of the message without reference to the original sender; pass null to try to forward the message as usual
//@copy_options Options to be used to copy content of the message without reference to the original sender; pass null to forward the message as usual
inputMessageForwarded from_chat_id:int53 message_id:int53 in_game_share:Bool copy_options:messageCopyOptions = InputMessageContent;
@ -4295,7 +4295,7 @@ getChatHistory chat_id:int53 from_message_id:int53 offset:int32 limit:int32 only
getMessageThreadHistory chat_id:int53 message_id:int53 from_message_id:int53 offset:int32 limit:int32 = Messages;
//@description Deletes all messages in the chat. Use chat.can_be_deleted_only_for_self and chat.can_be_deleted_for_all_users fields to find whether and how the method can be applied to the chat
//@chat_id Chat identifier @remove_from_chat_list Pass true if the chat needs to be removed from the chat list @revoke Pass true to try to delete chat history for all users
//@chat_id Chat identifier @remove_from_chat_list Pass true if the chat needs to be removed from the chat list @revoke Pass true to delete chat history for all users
deleteChatHistory chat_id:int53 remove_from_chat_list:Bool revoke:Bool = Ok;
//@description Deletes a chat along with all messages in the corresponding chat for all chat members; requires owner privileges. For group chats this will release the username and remove all members. Chats with more than 1000 members can't be deleted using this method @chat_id Chat identifier
@ -4381,9 +4381,6 @@ getMessagePublicForwards chat_id:int53 message_id:int53 offset:string limit:int3
//@description Returns sponsored message to be shown in a chat; for channel chats only. Returns a 404 error if there is no sponsored message in the chat @chat_id Identifier of the chat
getChatSponsoredMessage chat_id:int53 = SponsoredMessage;
//@description Informs TDLib that a sponsored message was viewed by the user @chat_id Identifier of the chat with the sponsored message @sponsored_message_id The identifier of the sponsored message being viewed
viewSponsoredMessage chat_id:int53 sponsored_message_id:int32 = Ok;
//@description Removes an active notification from notification list. Needs to be called only if the notification is removed by the current user @notification_group_id Identifier of notification group to which the notification belongs @notification_id Identifier of removed notification
removeNotification notification_group_id:int32 notification_id:int32 = Ok;
@ -4473,14 +4470,14 @@ sendChatScreenshotTakenNotification chat_id:int53 = Ok;
//@input_message_content The content of the message to be added
addLocalMessage chat_id:int53 sender_id:MessageSender reply_to_message_id:int53 disable_notification:Bool input_message_content:InputMessageContent = Message;
//@description Deletes messages @chat_id Chat identifier @message_ids Identifiers of the messages to be deleted @revoke Pass true to try to delete messages for all chat members. Always true for supergroups, channels and secret chats
//@description Deletes messages @chat_id Chat identifier @message_ids Identifiers of the messages to be deleted @revoke Pass true to delete messages for all chat members. Always true for supergroups, channels and secret chats
deleteMessages chat_id:int53 message_ids:vector<int53> revoke:Bool = Ok;
//@description Deletes all messages sent by the specified message sender in a chat. Supported only for supergroups; requires can_delete_messages administrator privileges @chat_id Chat identifier @sender_id Identifier of the sender of messages to delete
deleteChatMessagesBySender chat_id:int53 sender_id:MessageSender = Ok;
//@description Deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted
//@chat_id Chat identifier @min_date The minimum date of the messages to delete @max_date The maximum date of the messages to delete @revoke Pass true to try to delete chat messages for all users; private chats only
//@chat_id Chat identifier @min_date The minimum date of the messages to delete @max_date The maximum date of the messages to delete @revoke Pass true to delete chat messages for all users; private chats only
deleteChatMessagesByDate chat_id:int53 min_date:int32 max_date:int32 revoke:Bool = Ok;
@ -4690,7 +4687,7 @@ openChat chat_id:int53 = Ok;
//@description Informs TDLib that the chat is closed by the user. Many useful activities depend on the chat being opened or closed @chat_id Chat identifier
closeChat chat_id:int53 = Ok;
//@description Informs TDLib that messages are being viewed by the user. Many useful activities depend on whether the messages are currently being viewed or not (e.g., marking messages as read, incrementing a view counter, updating a view counter, removing deleted messages in supergroups and channels)
//@description Informs TDLib that messages are being viewed by the user. Sponsored messages must be marked as viewed only when the entire text of the message is shown on the screen (excluding the button). Many useful activities depend on whether the messages are currently being viewed or not (e.g., marking messages as read, incrementing a view counter, updating a view counter, removing deleted messages in supergroups and channels)
//@chat_id Chat identifier
//@message_thread_id If not 0, a message thread identifier in which the messages are being viewed
//@message_ids The identifiers of the messages being viewed

View File

@ -431,7 +431,7 @@ class MultiImplPool {
auto max_client_threads = clamp(thread::hardware_concurrency(), 8u, 20u) * 5 / 4;
#if TD_OPENBSD
max_client_threads = td::min(max_client_threads, 7u);
max_client_threads = td::min(max_client_threads, 4u);
#endif
impls_.resize(max_client_threads);
CHECK(impls_.size() * (1 + MultiImpl::ADDITIONAL_THREAD_COUNT + 1 /* IOCP */) < 128);

View File

@ -70,4 +70,4 @@ inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedFile &file) {
<< tag("dc_id", file.dc_id_) << tag("key_fingerprint", file.key_fingerprint_) << "]";
}
} // namespace td
} // namespace td

View File

@ -266,7 +266,8 @@ class LinkManager::InternalLinkProxy final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
CHECK(type_ != nullptr);
auto proxy_type = [type = type_.get()]() -> td_api::object_ptr<td_api::ProxyType> {
auto type = type_.get();
auto proxy_type = [type]() -> td_api::object_ptr<td_api::ProxyType> {
switch (type->get_id()) {
case td_api::proxyTypeSocks5::ID: {
auto type_socks = static_cast<const td_api::proxyTypeSocks5 *>(type);

View File

@ -3152,91 +3152,91 @@ Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contac
bool allow_all) {
vector<MessageEntity> entities;
entities.reserve(input_entities.size());
for (auto &entity : input_entities) {
if (entity == nullptr || entity->type_ == nullptr) {
for (auto &input_entity : input_entities) {
if (input_entity == nullptr || input_entity->type_ == nullptr) {
continue;
}
switch (entity->type_->get_id()) {
auto offset = input_entity->offset_;
auto length = input_entity->length_;
switch (input_entity->type_->get_id()) {
case td_api::textEntityTypeMention::ID:
entities.emplace_back(MessageEntity::Type::Mention, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Mention, offset, length);
break;
case td_api::textEntityTypeHashtag::ID:
entities.emplace_back(MessageEntity::Type::Hashtag, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Hashtag, offset, length);
break;
case td_api::textEntityTypeBotCommand::ID:
entities.emplace_back(MessageEntity::Type::BotCommand, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::BotCommand, offset, length);
break;
case td_api::textEntityTypeUrl::ID:
entities.emplace_back(MessageEntity::Type::Url, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Url, offset, length);
break;
case td_api::textEntityTypeEmailAddress::ID:
entities.emplace_back(MessageEntity::Type::EmailAddress, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::EmailAddress, offset, length);
break;
case td_api::textEntityTypeCashtag::ID:
entities.emplace_back(MessageEntity::Type::Cashtag, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Cashtag, offset, length);
break;
case td_api::textEntityTypePhoneNumber::ID:
entities.emplace_back(MessageEntity::Type::PhoneNumber, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::PhoneNumber, offset, length);
break;
case td_api::textEntityTypeBankCardNumber::ID:
entities.emplace_back(MessageEntity::Type::BankCardNumber, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::BankCardNumber, offset, length);
break;
case td_api::textEntityTypeBold::ID:
entities.emplace_back(MessageEntity::Type::Bold, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Bold, offset, length);
break;
case td_api::textEntityTypeItalic::ID:
entities.emplace_back(MessageEntity::Type::Italic, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Italic, offset, length);
break;
case td_api::textEntityTypeUnderline::ID:
entities.emplace_back(MessageEntity::Type::Underline, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Underline, offset, length);
break;
case td_api::textEntityTypeStrikethrough::ID:
entities.emplace_back(MessageEntity::Type::Strikethrough, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Strikethrough, offset, length);
break;
case td_api::textEntityTypeCode::ID:
entities.emplace_back(MessageEntity::Type::Code, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Code, offset, length);
break;
case td_api::textEntityTypePre::ID:
entities.emplace_back(MessageEntity::Type::Pre, entity->offset_, entity->length_);
entities.emplace_back(MessageEntity::Type::Pre, offset, length);
break;
case td_api::textEntityTypePreCode::ID: {
auto entity_pre_code = static_cast<td_api::textEntityTypePreCode *>(entity->type_.get());
if (!clean_input_string(entity_pre_code->language_)) {
auto entity = static_cast<td_api::textEntityTypePreCode *>(input_entity->type_.get());
if (!clean_input_string(entity->language_)) {
return Status::Error(400, "MessageEntityPreCode.language must be encoded in UTF-8");
}
entities.emplace_back(MessageEntity::Type::PreCode, entity->offset_, entity->length_,
entity_pre_code->language_);
entities.emplace_back(MessageEntity::Type::PreCode, offset, length, entity->language_);
break;
}
case td_api::textEntityTypeTextUrl::ID: {
auto entity_text_url = static_cast<td_api::textEntityTypeTextUrl *>(entity->type_.get());
if (!clean_input_string(entity_text_url->url_)) {
auto entity = static_cast<td_api::textEntityTypeTextUrl *>(input_entity->type_.get());
if (!clean_input_string(entity->url_)) {
return Status::Error(400, "MessageEntityTextUrl.url must be encoded in UTF-8");
}
auto r_url = LinkManager::check_link(entity_text_url->url_);
auto r_url = LinkManager::check_link(entity->url_);
if (r_url.is_error()) {
return Status::Error(400, PSTRING() << "Wrong message entity: " << r_url.error().message());
return Status::Error(400, PSTRING() << "Wrong message input_entity: " << r_url.error().message());
}
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
entities.emplace_back(MessageEntity::Type::TextUrl, offset, length, r_url.move_as_ok());
break;
}
case td_api::textEntityTypeMentionName::ID: {
auto entity_mention_name = static_cast<td_api::textEntityTypeMentionName *>(entity->type_.get());
UserId user_id(entity_mention_name->user_id_);
auto entity = static_cast<td_api::textEntityTypeMentionName *>(input_entity->type_.get());
UserId user_id(entity->user_id_);
if (contacts_manager != nullptr && !contacts_manager->have_input_user(user_id)) {
return Status::Error(400, "Have no access to the user");
}
entities.emplace_back(entity->offset_, entity->length_, user_id);
entities.emplace_back(offset, length, user_id);
break;
}
case td_api::textEntityTypeMediaTimestamp::ID: {
auto entity_media_timestamp = static_cast<td_api::textEntityTypeMediaTimestamp *>(entity->type_.get());
if (entity_media_timestamp->media_timestamp_ < 0) {
auto entity = static_cast<td_api::textEntityTypeMediaTimestamp *>(input_entity->type_.get());
if (entity->media_timestamp_ < 0) {
return Status::Error(400, "Invalid media timestamp specified");
}
entities.emplace_back(MessageEntity::Type::MediaTimestamp, entity->offset_, entity->length_,
entity_media_timestamp->media_timestamp_);
entities.emplace_back(MessageEntity::Type::MediaTimestamp, offset, length, entity->media_timestamp_);
break;
}
default:
@ -3255,107 +3255,104 @@ vector<MessageEntity> get_message_entities(const ContactsManager *contacts_manag
const char *source) {
vector<MessageEntity> entities;
entities.reserve(server_entities.size());
for (auto &entity : server_entities) {
switch (entity->get_id()) {
for (auto &server_entity : server_entities) {
switch (server_entity->get_id()) {
case telegram_api::messageEntityUnknown::ID:
break;
case telegram_api::messageEntityMention::ID: {
auto entity_mention = static_cast<const telegram_api::messageEntityMention *>(entity.get());
entities.emplace_back(MessageEntity::Type::Mention, entity_mention->offset_, entity_mention->length_);
auto entity = static_cast<const telegram_api::messageEntityMention *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Mention, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityHashtag::ID: {
auto entity_hashtag = static_cast<const telegram_api::messageEntityHashtag *>(entity.get());
entities.emplace_back(MessageEntity::Type::Hashtag, entity_hashtag->offset_, entity_hashtag->length_);
auto entity = static_cast<const telegram_api::messageEntityHashtag *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Hashtag, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityCashtag::ID: {
auto entity_cashtag = static_cast<const telegram_api::messageEntityCashtag *>(entity.get());
entities.emplace_back(MessageEntity::Type::Cashtag, entity_cashtag->offset_, entity_cashtag->length_);
auto entity = static_cast<const telegram_api::messageEntityCashtag *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Cashtag, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityPhone::ID: {
auto entity_phone = static_cast<const telegram_api::messageEntityPhone *>(entity.get());
entities.emplace_back(MessageEntity::Type::PhoneNumber, entity_phone->offset_, entity_phone->length_);
auto entity = static_cast<const telegram_api::messageEntityPhone *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::PhoneNumber, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityBotCommand::ID: {
auto entity_bot_command = static_cast<const telegram_api::messageEntityBotCommand *>(entity.get());
entities.emplace_back(MessageEntity::Type::BotCommand, entity_bot_command->offset_,
entity_bot_command->length_);
auto entity = static_cast<const telegram_api::messageEntityBotCommand *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::BotCommand, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityBankCard::ID: {
auto entity_bank_card = static_cast<const telegram_api::messageEntityBankCard *>(entity.get());
entities.emplace_back(MessageEntity::Type::BankCardNumber, entity_bank_card->offset_,
entity_bank_card->length_);
auto entity = static_cast<const telegram_api::messageEntityBankCard *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::BankCardNumber, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityUrl::ID: {
auto entity_url = static_cast<const telegram_api::messageEntityUrl *>(entity.get());
entities.emplace_back(MessageEntity::Type::Url, entity_url->offset_, entity_url->length_);
auto entity = static_cast<const telegram_api::messageEntityUrl *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Url, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityEmail::ID: {
auto entity_email = static_cast<const telegram_api::messageEntityEmail *>(entity.get());
entities.emplace_back(MessageEntity::Type::EmailAddress, entity_email->offset_, entity_email->length_);
auto entity = static_cast<const telegram_api::messageEntityEmail *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::EmailAddress, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityBold::ID: {
auto entity_bold = static_cast<const telegram_api::messageEntityBold *>(entity.get());
entities.emplace_back(MessageEntity::Type::Bold, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const telegram_api::messageEntityBold *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Bold, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityItalic::ID: {
auto entity_italic = static_cast<const telegram_api::messageEntityItalic *>(entity.get());
entities.emplace_back(MessageEntity::Type::Italic, entity_italic->offset_, entity_italic->length_);
auto entity = static_cast<const telegram_api::messageEntityItalic *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Italic, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityUnderline::ID: {
auto entity_bold = static_cast<const telegram_api::messageEntityUnderline *>(entity.get());
entities.emplace_back(MessageEntity::Type::Underline, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const telegram_api::messageEntityUnderline *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Underline, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityStrike::ID: {
auto entity_bold = static_cast<const telegram_api::messageEntityStrike *>(entity.get());
entities.emplace_back(MessageEntity::Type::Strikethrough, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const telegram_api::messageEntityStrike *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Strikethrough, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityBlockquote::ID: {
auto entity_bold = static_cast<const telegram_api::messageEntityBlockquote *>(entity.get());
entities.emplace_back(MessageEntity::Type::BlockQuote, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const telegram_api::messageEntityBlockquote *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::BlockQuote, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityCode::ID: {
auto entity_code = static_cast<const telegram_api::messageEntityCode *>(entity.get());
entities.emplace_back(MessageEntity::Type::Code, entity_code->offset_, entity_code->length_);
auto entity = static_cast<const telegram_api::messageEntityCode *>(server_entity.get());
entities.emplace_back(MessageEntity::Type::Code, entity->offset_, entity->length_);
break;
}
case telegram_api::messageEntityPre::ID: {
auto entity_pre = static_cast<telegram_api::messageEntityPre *>(entity.get());
if (entity_pre->language_.empty()) {
entities.emplace_back(MessageEntity::Type::Pre, entity_pre->offset_, entity_pre->length_);
auto entity = static_cast<telegram_api::messageEntityPre *>(server_entity.get());
if (entity->language_.empty()) {
entities.emplace_back(MessageEntity::Type::Pre, entity->offset_, entity->length_);
} else {
entities.emplace_back(MessageEntity::Type::PreCode, entity_pre->offset_, entity_pre->length_,
std::move(entity_pre->language_));
entities.emplace_back(MessageEntity::Type::PreCode, entity->offset_, entity->length_,
std::move(entity->language_));
}
break;
}
case telegram_api::messageEntityTextUrl::ID: {
auto entity_text_url = static_cast<const telegram_api::messageEntityTextUrl *>(entity.get());
auto r_url = LinkManager::check_link(entity_text_url->url_);
auto entity = static_cast<const telegram_api::messageEntityTextUrl *>(server_entity.get());
auto r_url = LinkManager::check_link(entity->url_);
if (r_url.is_error()) {
LOG(ERROR) << "Wrong URL entity: \"" << entity_text_url->url_ << "\": " << r_url.error().message() << " from "
LOG(ERROR) << "Wrong URL entity: \"" << entity->url_ << "\": " << r_url.error().message() << " from "
<< source;
continue;
}
entities.emplace_back(MessageEntity::Type::TextUrl, entity_text_url->offset_, entity_text_url->length_,
r_url.move_as_ok());
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
break;
}
case telegram_api::messageEntityMentionName::ID: {
auto entity_mention_name = static_cast<const telegram_api::messageEntityMentionName *>(entity.get());
UserId user_id(entity_mention_name->user_id_);
auto entity = static_cast<const telegram_api::messageEntityMentionName *>(server_entity.get());
UserId user_id(entity->user_id_);
if (!user_id.is_valid()) {
LOG(ERROR) << "Receive invalid " << user_id << " in MentionName from " << source;
continue;
@ -3368,7 +3365,7 @@ vector<MessageEntity> get_message_entities(const ContactsManager *contacts_manag
LOG(ERROR) << "Receive inaccessible " << user_id << " in MentionName from " << source;
continue;
}
entities.emplace_back(entity_mention_name->offset_, entity_mention_name->length_, user_id);
entities.emplace_back(entity->offset_, entity->length_, user_id);
break;
}
default:
@ -3381,8 +3378,8 @@ vector<MessageEntity> get_message_entities(const ContactsManager *contacts_manag
vector<MessageEntity> get_message_entities(vector<tl_object_ptr<secret_api::MessageEntity>> &&secret_entities) {
vector<MessageEntity> entities;
entities.reserve(secret_entities.size());
for (auto &entity : secret_entities) {
switch (entity->get_id()) {
for (auto &secret_entity : secret_entities) {
switch (secret_entity->get_id()) {
case secret_api::messageEntityUnknown::ID:
break;
case secret_api::messageEntityMention::ID:
@ -3404,74 +3401,73 @@ vector<MessageEntity> get_message_entities(vector<tl_object_ptr<secret_api::Mess
// skip, will find it ourselves
break;
case secret_api::messageEntityUrl::ID: {
auto entity_url = static_cast<const secret_api::messageEntityUrl *>(entity.get());
auto entity = static_cast<const secret_api::messageEntityUrl *>(secret_entity.get());
// TODO skip URL when find_urls will be better
entities.emplace_back(MessageEntity::Type::Url, entity_url->offset_, entity_url->length_);
entities.emplace_back(MessageEntity::Type::Url, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityEmail::ID: {
auto entity_email = static_cast<const secret_api::messageEntityEmail *>(entity.get());
auto entity = static_cast<const secret_api::messageEntityEmail *>(secret_entity.get());
// TODO skip emails when find_urls will be better
entities.emplace_back(MessageEntity::Type::EmailAddress, entity_email->offset_, entity_email->length_);
entities.emplace_back(MessageEntity::Type::EmailAddress, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityBold::ID: {
auto entity_bold = static_cast<const secret_api::messageEntityBold *>(entity.get());
entities.emplace_back(MessageEntity::Type::Bold, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const secret_api::messageEntityBold *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::Bold, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityItalic::ID: {
auto entity_italic = static_cast<const secret_api::messageEntityItalic *>(entity.get());
entities.emplace_back(MessageEntity::Type::Italic, entity_italic->offset_, entity_italic->length_);
auto entity = static_cast<const secret_api::messageEntityItalic *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::Italic, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityUnderline::ID: {
auto entity_bold = static_cast<const secret_api::messageEntityUnderline *>(entity.get());
entities.emplace_back(MessageEntity::Type::Underline, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const secret_api::messageEntityUnderline *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::Underline, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityStrike::ID: {
auto entity_bold = static_cast<const secret_api::messageEntityStrike *>(entity.get());
entities.emplace_back(MessageEntity::Type::Strikethrough, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const secret_api::messageEntityStrike *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::Strikethrough, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityBlockquote::ID: {
auto entity_bold = static_cast<const secret_api::messageEntityBlockquote *>(entity.get());
entities.emplace_back(MessageEntity::Type::BlockQuote, entity_bold->offset_, entity_bold->length_);
auto entity = static_cast<const secret_api::messageEntityBlockquote *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::BlockQuote, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityCode::ID: {
auto entity_code = static_cast<const secret_api::messageEntityCode *>(entity.get());
entities.emplace_back(MessageEntity::Type::Code, entity_code->offset_, entity_code->length_);
auto entity = static_cast<const secret_api::messageEntityCode *>(secret_entity.get());
entities.emplace_back(MessageEntity::Type::Code, entity->offset_, entity->length_);
break;
}
case secret_api::messageEntityPre::ID: {
auto entity_pre = static_cast<secret_api::messageEntityPre *>(entity.get());
if (!clean_input_string(entity_pre->language_)) {
LOG(WARNING) << "Wrong language in entity: \"" << entity_pre->language_ << '"';
entity_pre->language_.clear();
auto entity = static_cast<secret_api::messageEntityPre *>(secret_entity.get());
if (!clean_input_string(entity->language_)) {
LOG(WARNING) << "Wrong language in entity: \"" << entity->language_ << '"';
entity->language_.clear();
}
if (entity_pre->language_.empty()) {
entities.emplace_back(MessageEntity::Type::Pre, entity_pre->offset_, entity_pre->length_);
if (entity->language_.empty()) {
entities.emplace_back(MessageEntity::Type::Pre, entity->offset_, entity->length_);
} else {
entities.emplace_back(MessageEntity::Type::PreCode, entity_pre->offset_, entity_pre->length_,
std::move(entity_pre->language_));
entities.emplace_back(MessageEntity::Type::PreCode, entity->offset_, entity->length_,
std::move(entity->language_));
}
break;
}
case secret_api::messageEntityTextUrl::ID: {
auto entity_text_url = static_cast<secret_api::messageEntityTextUrl *>(entity.get());
if (!clean_input_string(entity_text_url->url_)) {
LOG(WARNING) << "Wrong URL entity: \"" << entity_text_url->url_ << '"';
auto entity = static_cast<secret_api::messageEntityTextUrl *>(secret_entity.get());
if (!clean_input_string(entity->url_)) {
LOG(WARNING) << "Wrong URL entity: \"" << entity->url_ << '"';
continue;
}
auto r_url = LinkManager::check_link(entity_text_url->url_);
auto r_url = LinkManager::check_link(entity->url_);
if (r_url.is_error()) {
LOG(WARNING) << "Wrong URL entity: \"" << entity_text_url->url_ << "\": " << r_url.error().message();
LOG(WARNING) << "Wrong URL entity: \"" << entity->url_ << "\": " << r_url.error().message();
continue;
}
entities.emplace_back(MessageEntity::Type::TextUrl, entity_text_url->offset_, entity_text_url->length_,
r_url.move_as_ok());
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
break;
}
case secret_api::messageEntityMentionName::ID:

View File

@ -43,6 +43,14 @@ bool MessageId::is_valid_scheduled() const {
return type == SCHEDULED_MASK || type == (SCHEDULED_MASK | TYPE_YET_UNSENT) || type == (SCHEDULED_MASK | TYPE_LOCAL);
}
bool MessageId::is_valid_sponsored() const {
if (id <= max().get() || id > (static_cast<int64>(1) << 51)) {
return false;
}
int32 type = (id & TYPE_MASK);
return type == TYPE_LOCAL;
}
MessageType MessageId::get_type() const {
if (id <= 0 || id > (static_cast<int64>(1) << 51)) {
return MessageType::None;

View File

@ -41,6 +41,10 @@ class MessageId {
// |-------30-------|----18---|1|--2-|
// |send_date-2**30 |server_id|1|type|
// sponsored message ID layout
// |-------31--------|---17---|1|-2|
// |11111111111111111|local_id|0|10|
ServerMessageId get_server_message_id_force() const;
ScheduledServerMessageId get_scheduled_server_message_id_force() const {
@ -73,6 +77,8 @@ class MessageId {
bool is_valid_scheduled() const;
bool is_valid_sponsored() const;
int64 get() const {
return id;
}

View File

@ -28,4 +28,4 @@ struct MessageLinkInfo {
bool for_comment = false;
};
} // namespace td
} // namespace td

View File

@ -237,4 +237,4 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageReplyInfo
}
}
} // namespace td
} // namespace td

View File

@ -65,4 +65,4 @@ struct MessageReplyInfo {
StringBuilder &operator<<(StringBuilder &string_builder, const MessageReplyInfo &reply_info);
} // namespace td
} // namespace td

View File

@ -100,4 +100,4 @@ void MessageReplyInfo::parse(ParserT &parser) {
}
}
} // namespace td
} // namespace td

View File

@ -19,4 +19,4 @@ struct MessageThreadInfo {
int32 unread_message_count = 0;
};
} // namespace td
} // namespace td

View File

@ -50,6 +50,7 @@
#include "td/telegram/ReplyMarkup.hpp"
#include "td/telegram/SecretChatsManager.h"
#include "td/telegram/SequenceDispatcher.h"
#include "td/telegram/SponsoredMessageManager.h"
#include "td/telegram/Td.h"
#include "td/telegram/TdDb.h"
#include "td/telegram/TdParameters.h"
@ -19912,6 +19913,12 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
}
for (auto message_id : message_ids) {
if (!message_id.is_valid() && !message_id.is_valid_scheduled()) {
if (message_id.is_valid_sponsored()) {
if (d->is_opened) {
td_->sponsored_message_manager_->view_sponsored_message(dialog_id, message_id);
}
continue;
}
return Status::Error(400, "Invalid message identifier");
}
}

View File

@ -55,4 +55,4 @@ Result<NewPasswordState> get_new_password_state(tl_object_ptr<telegram_api::Pass
return state;
}
} // namespace td
} // namespace td

View File

@ -24,4 +24,4 @@ struct NewPasswordState {
Result<NewPasswordState> get_new_password_state(tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo,
tl_object_ptr<telegram_api::SecurePasswordKdfAlgo> new_secure_algo);
} // namespace td
} // namespace td

View File

@ -64,18 +64,14 @@ class GetSponsoredMessagesQuery final : public Td::ResultHandler {
};
class ViewSponsoredMessageQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
ChannelId channel_id_;
public:
explicit ViewSponsoredMessageQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(ChannelId channel_id, const string &message_id) {
channel_id_ = channel_id;
auto input_channel = td_->contacts_manager_->get_input_channel(channel_id);
if (input_channel == nullptr) {
return promise_.set_error(Status::Error(400, "Chat info not found"));
return;
}
send_query(G()->net_query_creator().create(
telegram_api::channels_viewSponsoredMessage(std::move(input_channel), BufferSlice(message_id))));
@ -86,25 +82,22 @@ class ViewSponsoredMessageQuery final : public Td::ResultHandler {
if (result_ptr.is_error()) {
return on_error(result_ptr.move_as_error());
}
promise_.set_value(Unit());
}
void on_error(Status status) final {
td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ViewSponsoredMessageQuery");
promise_.set_error(std::move(status));
}
};
struct SponsoredMessageManager::SponsoredMessage {
int32 local_id = 0;
int64 local_id = 0;
DialogId sponsor_dialog_id;
ServerMessageId server_message_id;
string start_param;
unique_ptr<MessageContent> content;
SponsoredMessage() = default;
SponsoredMessage(int32 local_id, DialogId sponsor_dialog_id, ServerMessageId server_message_id, string start_param,
SponsoredMessage(int64 local_id, DialogId sponsor_dialog_id, ServerMessageId server_message_id, string start_param,
unique_ptr<MessageContent> content)
: local_id(local_id)
, sponsor_dialog_id(sponsor_dialog_id)
@ -117,7 +110,7 @@ struct SponsoredMessageManager::SponsoredMessage {
struct SponsoredMessageManager::DialogSponsoredMessages {
vector<Promise<td_api::object_ptr<td_api::sponsoredMessage>>> promises;
vector<SponsoredMessage> messages;
std::unordered_map<int32, string> message_random_ids;
std::unordered_map<int64, string> message_random_ids;
};
SponsoredMessageManager::SponsoredMessageManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
@ -274,8 +267,16 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages(
}
CHECK(disable_web_page_preview);
CHECK(current_sponsored_message_id_ < std::numeric_limits<int32>::max());
auto local_id = ++current_sponsored_message_id_;
current_sponsored_message_id_ = current_sponsored_message_id_.get_next_message_id(MessageType::Local);
if (!current_sponsored_message_id_.is_valid_sponsored()) {
LOG(ERROR) << "Sponsored message ID overflowed";
current_sponsored_message_id_ = MessageId::max().get_next_message_id(MessageType::Local);
CHECK(current_sponsored_message_id_.is_valid_sponsored());
}
auto local_id = current_sponsored_message_id_.get();
CHECK(!current_sponsored_message_id_.is_valid());
CHECK(!current_sponsored_message_id_.is_scheduled());
CHECK(messages->message_random_ids.count(local_id) == 0);
messages->message_random_ids[local_id] = sponsored_message->random_id_.as_slice().str();
messages->messages.emplace_back(local_id, sponsor_dialog_id, server_message_id,
std::move(sponsored_message->start_param_), std::move(content));
@ -287,27 +288,19 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages(
delete_cached_sponsored_messages_timeout_.set_timeout_in(dialog_id.get(), 300.0);
}
void SponsoredMessageManager::view_sponsored_message(DialogId dialog_id, int32 sponsored_message_id,
Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id, "view_sponsored_message")) {
return promise.set_error(Status::Error(400, "Chat not found"));
}
if (!td_->messages_manager_->is_dialog_opened(dialog_id)) {
return promise.set_value(Unit());
}
void SponsoredMessageManager::view_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id) {
auto it = dialog_sponsored_messages_.find(dialog_id);
if (it == dialog_sponsored_messages_.end()) {
return promise.set_value(Unit());
return;
}
auto random_id_it = it->second->message_random_ids.find(sponsored_message_id);
auto random_id_it = it->second->message_random_ids.find(sponsored_message_id.get());
if (random_id_it == it->second->message_random_ids.end()) {
return promise.set_value(Unit());
return;
}
auto random_id = std::move(random_id_it->second);
it->second->message_random_ids.erase(random_id_it);
td_->create_handler<ViewSponsoredMessageQuery>(std::move(promise))->send(dialog_id.get_channel_id(), random_id);
td_->create_handler<ViewSponsoredMessageQuery>()->send(dialog_id.get_channel_id(), random_id);
}
} // namespace td

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
@ -35,7 +36,7 @@ class SponsoredMessageManager final : public Actor {
void get_dialog_sponsored_message(DialogId dialog_id,
Promise<td_api::object_ptr<td_api::sponsoredMessage>> &&promise);
void view_sponsored_message(DialogId dialog_id, int32 sponsored_message_id, Promise<Unit> &&promise);
void view_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id);
private:
struct SponsoredMessage;
@ -59,7 +60,7 @@ class SponsoredMessageManager final : public Actor {
std::unordered_map<DialogId, unique_ptr<DialogSponsoredMessages>, DialogIdHash> dialog_sponsored_messages_;
int32 current_sponsored_message_id_ = 0;
MessageId current_sponsored_message_id_ = MessageId::max();
MultiTimeout delete_cached_sponsored_messages_timeout_{"DeleteCachedSponsoredMessagesTimeout"};

View File

@ -6519,7 +6519,7 @@ void StickersManager::on_update_recent_stickers_limit(int32 recent_stickers_limi
for (int is_attached = 0; is_attached < 2; is_attached++) {
if (static_cast<int32>(recent_sticker_ids_[is_attached].size()) > recent_stickers_limit) {
recent_sticker_ids_[is_attached].resize(recent_stickers_limit);
send_update_recent_stickers(is_attached);
send_update_recent_stickers(is_attached != 0);
}
}
} else {

View File

@ -4737,13 +4737,6 @@ void Td::on_request(uint64 id, const td_api::getChatSponsoredMessage &request) {
sponsored_message_manager_->get_dialog_sponsored_message(DialogId(request.chat_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::viewSponsoredMessage &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
sponsored_message_manager_->view_sponsored_message(DialogId(request.chat_id_), request.sponsored_message_id_,
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getMessageThread &request) {
CHECK_IS_USER();
CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_);

View File

@ -105,7 +105,7 @@ class Td final : public Actor {
Td &operator=(Td &&) = delete;
~Td() final;
static constexpr const char *TDLIB_VERSION = "1.7.11";
static constexpr const char *TDLIB_VERSION = "1.7.12";
struct Options {
std::shared_ptr<NetQueryStats> net_query_stats;
@ -536,8 +536,6 @@ class Td final : public Actor {
void on_request(uint64 id, const td_api::getChatSponsoredMessage &request);
void on_request(uint64 id, const td_api::viewSponsoredMessage &request);
void on_request(uint64 id, const td_api::getMessageLink &request);
void on_request(uint64 id, const td_api::getMessageEmbeddingCode &request);

View File

@ -2674,12 +2674,6 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::getMessages>(as_chat_id(chat_id), as_message_ids(message_ids)));
} else if (op == "gsm") {
send_request(td_api::make_object<td_api::getChatSponsoredMessage>(as_chat_id(args)));
} else if (op == "vsm") {
string chat_id;
string sponsored_message_id;
get_args(args, chat_id, sponsored_message_id);
send_request(td_api::make_object<td_api::viewSponsoredMessage>(as_chat_id(chat_id),
to_integer<int32>(sponsored_message_id)));
} else if (op == "gmlink") {
string chat_id;
string message_id;

View File

@ -184,38 +184,20 @@ class SafePromise;
template <class T = Unit>
class Promise;
constexpr inline std::false_type is_promise_interface(...) {
return {};
}
template <class T>
struct is_promise_interface : std::false_type {};
template <class U>
struct is_promise_interface<PromiseInterface<U>> : std::true_type {};
template <class U>
struct is_promise_interface<Promise<U>> : std::true_type {};
template <class T>
constexpr std::true_type is_promise_interface(const PromiseInterface<T> &promise) {
return {};
}
struct is_promise_interface_ptr : std::false_type {};
template <class T>
constexpr std::true_type is_promise_interface(const Promise<T> &promise) {
return {};
}
template <class F>
constexpr bool is_promise_interface() {
return decltype(is_promise_interface(std::declval<F>()))::value;
}
constexpr inline std::false_type is_promise_interface_ptr(...) {
return {};
}
template <class T>
constexpr std::true_type is_promise_interface_ptr(const unique_ptr<T> &promise) {
return {};
}
template <class F>
constexpr bool is_promise_interface_ptr() {
return decltype(is_promise_interface_ptr(std::declval<F>()))::value;
}
template <class U>
struct is_promise_interface_ptr<unique_ptr<U>> : std::true_type {};
template <class T = void, class F = void, std::enable_if_t<std::is_same<T, void>::value, bool> has_t = false>
auto lambda_promise(F &&f) {
@ -227,22 +209,26 @@ auto lambda_promise(F &&f) {
return detail::LambdaPromise<T, std::decay_t<F>>(std::forward<F>(f));
}
template <class T, class F, std::enable_if_t<is_promise_interface<F>(), bool> from_promise_interface = true>
template <class T, class F,
std::enable_if_t<is_promise_interface<std::decay_t<F>>::value, bool> from_promise_interface = true>
auto &&promise_interface(F &&f) {
return std::forward<F>(f);
}
template <class T, class F, std::enable_if_t<!is_promise_interface<F>(), bool> from_promise_interface = false>
template <class T, class F,
std::enable_if_t<!is_promise_interface<std::decay_t<F>>::value, bool> from_promise_interface = false>
auto promise_interface(F &&f) {
return lambda_promise<T>(std::forward<F>(f));
}
template <class T, class F, std::enable_if_t<is_promise_interface_ptr<F>(), bool> from_promise_interface = true>
template <class T, class F,
std::enable_if_t<is_promise_interface_ptr<std::decay_t<F>>::value, bool> from_promise_interface = true>
auto promise_interface_ptr(F &&f) {
return std::forward<F>(f);
}
template <class T, class F, std::enable_if_t<!is_promise_interface_ptr<F>(), bool> from_promise_interface = false>
template <class T, class F,
std::enable_if_t<!is_promise_interface_ptr<std::decay_t<F>>::value, bool> from_promise_interface = false>
auto promise_interface_ptr(F &&f) {
return td::make_unique<std::decay_t<decltype(promise_interface<T>(std::forward<F>(f)))>>(
promise_interface<T>(std::forward<F>(f)));

View File

@ -301,11 +301,7 @@ class OpenClose final : public td::Actor {
TEST(Actors, open_close) {
td::ConcurrentScheduler scheduler;
scheduler.init(2);
int cnt = 1000000;
#if TD_WINDOWS || TD_ANDROID
// TODO(perf) optimize
cnt = 100;
#endif
int cnt = 10000; // TODO(perf) optimize
scheduler.create_actor_unsafe<OpenClose>(1, "A", cnt).release();
scheduler.create_actor_unsafe<OpenClose>(2, "B", cnt).release();
scheduler.start();

View File

@ -22,4 +22,4 @@ char disable_linker_warning_about_empty_file_platform_cpp TD_UNUSED;
#warning "Probably unsupported compiler. Feel free to try to compile"
#endif
#endif
#endif