В разделе 5.7, при рассмотрении проблемы синхронизации потоков, были представлены функции cue
и sync
То, что там не было разъяснено, это система Time State, которая обеспечивает эту функциональность. Так случилось, что функцияset
на самом деле является вариацией cue
и устроена поверх той же базовой функциональности, которая заключается в сообщении информации системе Time State. Кроме того, функция sync
также спроектирована таким образом, чтобы бесперебойно работать с Time State - любую информацию, которую мы планируем хранить в Time State, мы можем синхронизировать с ее помощью. Другими словами - * мы применяем функциюsync
к событиям, которые еще только предстоит сообщить системе Time State *.
Давайте кратко рассмотрим, как использовать sync
для ожидания новых событий, которым предстоит быть добавленными в Time State:
in_thread do
sync :foo
sample :ambi_lunar_land
end
sleep 2
set :foo, 1
В этом примере мы сначала создаем поток, который ожидает в дальнейшем добавления события : foo
в Time State. После этого, мы “спим” 2 такта, а затем посредством функции set
устанавливаем для : foo
значение 1
. Это определяет функцию sync
, которая в следующей строке воспроизводит сэмпл: ambi_lunar_land
.
Обратите внимание, что sync
всегда ожидает * будущих событий * и блокирует текущий поток в ожидании нового события. Кроме того, он унаследует логическое время потока, который запустил его через set
или cue
, поэтому его также можно использовать для синхронизации времени.
В приведенном выше примере мы установили для : foo
значение 1
, с которым ничего не сделали. На самом деле мы можем получить это значение из sync
, вызывающего поток:
in_thread do
amp = sync :foo
sample :ambi_lunar_land, amp: amp
end
sleep 2
set :foo, 0.5
Обратите внимание, что значения, которые передаются через set
и cue
, должны быть потокобезопасными - то есть кольца, числа, символы или замороженные строки не должны изменяться. Sonic Pi выдаст ошибку, если значение, которое вы пытаетесь сохранить в Time State, недопустимо.