⚠️ Обращайте внимание на даты.
Этот блог больше не ведётся с 17 января 2023, и на тот момент с написания этой страницы (20.08.2013) прошло 9 лет.
Заголовок у несведущего читателя сразу вызовет вопросы о том, что такое “синхронные действия”. И если читатель знаком с программированием, то (скорее всего) вовсю этими действиями пользуется. Что такое “синхронные действия” проще объяснить, рассказав об асинхронных.
Начну с примера. Вы слышали о такой штуке, как JavaScript? Скорее всего, слышали. Представьте - когда загружается страница, с ней может загружаться огромное количество разнообразных файлов, а также выполняться тонна различных программ (скриптов). Предположим, что из-за этого страница загружается вполне ощутимое для пользователя время, но нормальное.
А теперь предположим, что вам надо посреди страницы рассчитать и разместить что-то тяжёлое и кушающее драгоценное время. Предположим, это картинка в большом разрешении. Её можно вшить прямо в текст страницы (хоть так и мало кто в наше время делает - это лишь пример). Какого эффекта мы добьёмся? На медленном соединении (которое не сможет загрузить картинку мгновенно) загрузка дойдёт до картинки и успешно повесит загрузку следующих элементов, пока картинка не загрузится. А всё почему? Потому что картинка в одном потоке с остальным материалом, и её загрузка происходит синхронно со страницей.
Второй пример. Технически посложнее, зато встречается намного чаще. Пусть у нас есть программа, которая в бесконечном цикле спрашивает систему, какие события произошли. И реагирует на них соответствующе. К примеру, нам может прийти сообщение “пользователь нажал
кнопку
“. Кнопка нажалась, выяснилось, что кнопка запускает какое-то очень долгое действие. Что выходит? Что программа выполняет это долгое действие, совершенно забыв о каких-либо других событиях. Пользователь нажал закрыть
? Пофиг!
Что делать?
Ответ простой - вынести это очень долгое действие из общего потока программы. Так, чтобы оно выполнялось отдельно, не мешая общему течению. А это “общее течение” тем временем может проверять, не завершилось ли действие.
Такой приём применяют даже в тех случаях, когда действие может занять длительное время, хоть это далеко не всегда так. Это обычно выгодно - мы чаще имеем дело с многоядерными системами, и грузить всего одно ядро - это использовать лишь жалкую часть его мощи.
Раз уж я тут столько рассказываю о GameMaker Studio: там реализация этого приёма достаточно проста. Изолировать там можно всего несколько процессов: загрузку ресурсов и обращения к сети - они могут никак не взаимодействовать с игрой в процессе работы.
Когда вы совершаете одно из этих действий, GMS его запускает и продолжает работу. Но каждый шаг он проверяет, не закончилось ли оно. И если да - он запускает по всей игре событие “у нас асинхронка кончилась!”, причём соответствующего вида. По виду - определяется, какие данные получены в ходе выполненного задания. Это может быть статус (получилось или нет), сообщение (к интернету не подключены?) и сам результат (индекс ресурса или текст).
Эти данные хранятся в структуре данных map, о назначении, разновидностях и устройстве которой я расскажу в другой раз. Азы, которые вам нужно знать - map можно использовать, как словарь. Причём слова, в нём присутствующие, описаны в справке, а “определения словарных слов” - это нужные вам данные. Слова - ключи (key), а их “определения” - это значения (value). Применяя эти термины - в справке вы найдёте список ключей, соответствующих каждому событию.
Уж извините, но справку я раскапывать в этот раз не буду. GMS развивается настолько активно, что эти данные могут устареть, а я об этом и не узнаю - пост утонет.