000155. Использование SCM-функций (опкод 0AB1)
Использование SCM-функций (опкод 0AB1)|Что же такое SCM-функция? На деле это выглядит так, словно мы вызываем опкод, который создали сами и, он выполняет определённые действия. С одной стороны, он похож на стандартный gosub, но принцип работы у SCM-функции другой - все переменные сохраняют свои значения, несмотря на то, что в функции используются те же переменные ( имеются ввиду локальные переменные )|BoPoH|BoPoH||||Основное назначение SCM-функций - укорачивание кода скрипта и улучшение его читабельности, если в нём используются одни и те же конструкции во многих местах. За вызов SCM-функции отвечает опкод 0AB1. Этот опкод добавляется библиотекой CLEO, поэтому если у вас её нет - опкод работать не будет. Давайте рассмотрим подробнее его параметры.
Здесь: @function - это метка, указывающая на код нашей SCM-функции 1 - это количество параметров, которые мы передаём в функцию ( не более 32 ). Эти параметры используются функцией для выполнения определённых задач, связанных с этими параметрами. К примеру, если функция будет помещать актёра в определённую точку, то в неё мы будем передавать хендл актёра. 10 ( и т.п. ) - это те параметры, которые будут передаваться в функцию ( не более 32 ). Их количество должно совпадать со вторым параметром. Т.е. если вы вторым параметром указали число 3, значит после него вы должны указать 3 параметра, которые передадутся в функцию.
Например:
Оставшиеся параметры ( переменные ) будут получать возвращаемые функцией данные. SCM-функция может возвращать одно и более значений при помощи опкода 0AB2. Если функция не возвращает параметров, то никаких переменных в конце опкода писать не нужно. Попробуем разобрать пример, приведённый ниже:
По нажатию клавиши 0`, перед игроком заспаунится элегия и ей присвоятся иммунитеты. Рассмотрим вызов функции опкодом 0AB1. Здесь у нас 5 параметров, которые передаются в функцию, и одно возвращаемое значение - хендл созданной машины.
Сама SCM-функция находится за пределами основного цикла скрипта. Исполнение скрипта не должно дойти до неё иным способом, кроме как через опкод 0AB1. Проще говоря, SCM-функции лучше всего оставлять в конце скрипта, а не в середине и уж тем более, не в начале.
Исходя из того, что компилятор спокойно воспринимает изменения описаний опкодов, мы можем спокойно изменить внешний вид опкода 0AB1 под свои нужды. К примеру, так:
Таким образом, вызов фукции становится более читабельным. Описание к каждой функции можно придумывать своё.
Лично я перед меткой функции оставляю комментарий с примером вызова функции, чтобы не забывать, какие параметры передаются в функцию и какие возвращаются.
Теперь разберём саму функцию. Параметры, которые передаются опкодом 0AB1 в функцию, записываются последовательно в локальные переменные функции, начиная с 0@. В нашем случае, в 0@ запишется хендл актёра, в 1@, 2@ и 3@ - смещение от актёра, а в 4@ - модель машины.
Заканчивается работа функции опкодом 0AB2.
Первый параметр в этом опкоде - количество параметров, которые возвращаются из функции и запишутся в соответствующие переменные, указанные в опкоде 0AB1. Если функция не должна возвращать параметров, то указываем 0. Если функция возвращает один или несколько параметров - указываем соответствующее значение и далее вписываем необходимые значения или переменные, значения которых должны быть возвращены.
SCM-функции могут быть вложенными, как и gosub-ы - можно использовать SCM-функции внутри других SCM-функций.
У каждой функции есть свой независимый набор локальных переменных - можно вызывать их, не боясь, что вы потеряете данные из локальных переменных основного потока.
У SCM-функций есть один неприятный недостаток - они сильно замедляют работу скрипта. Если использование десятка-другого функций за один цикл игры никак не отразится на производительности игры, то сотня функций за один цикл игры может заметно снизить фпс. Таким образом, не рекомендуется использовать SCM-функции в циклах с большим количеством итераций.
У SCM-функций есть одна особенность - если передавать в неё строковые переменные ( 13@v, например ), то в соответствующую локальную переменную функции запишется указатель на строковую переменную ( т.е. на переменную 13@ в данном примере). Для тех, кто не разбирается в работе с памятью, могу объяснить проще - строковые параметры в обычном виде в функцию передать нельзя. Если вы хотите передать строку, то нужно передавать её в виде 4 последовательных переменных, начиная с той, в которую записана строка. Например:
А в функции уже можно использовать её как строковую переменную:
Я думаю, на этом закончим урок. Я постарался раскрыть все известные мне детали, хотя мог что-нибудь и упустить. Если есть вопросы или вы хотели бы видеть урок по теме, которая вас интересует - пишите в комментариях.|1983|315|0||ispolzovanie_scm_funkcij_opkod_0ab1|1504597275
Last updated