Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 3 1 2 3 ПоследняяПоследняя
Показано с 1 по 10 из 23
  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±

    Отличия Pawn 4.x от Pawn 3.2

    Всем привет.

    Я хотел опубликовать эту статью чуть позже, приурочив её к другому событию, но с выходом плагина nPawn думаю, сейчас самое время.
    В названии указано Pawn 4.x вместо 4.0, поскольку в статье приведены отличия не только версии 4.0, но и экспериментальной ветки, в которой исправлены баги, оставшиеся в 4.0, и добавлено ещё несколько новых фич.
    К сведению, nPawn использует именно экспериментальную ветку. ИМХО, она даже более стабильна, чем "стабильный" релиз 4.0.

    Условные обозначения:
    • (+) Новый функционал.
    • (*) Изменение.
    • (FIX) Багфикс.
    • (4.x) Нет в релизе 4.0, т.к. реализовано позже и пока что находится в экспериментальной ветке.

    Список отличий:
    1. (*) Ключевое слово enum заменено на const.
      Теперь для того, чтобы сделать перечисление из нескольких поименованных констант, нужно использовать const. Также у первой константы обязательно должно быть указано значение.
      Рассмотрим это на примере объявления ID диалогов в SA-MP. Вот как это объявление выглядело бы в Pawn 4.0:
      PHP код:
      const
      {
          
      DIALOG_NONE 0,
          
      DIALOG_REGISTER,
          
      DIALOG_LOGIN,
          
      DIALOG_EMAIL,
          
      DIALOG_EDIT_EMAIL,
      }; 
      Запятая после завершающей константы теперь не является ошибкой. Вы уже могли видеть это в модифицированном компиляторе от Zeex, но этого не было в Pawn 3.2.
      По умолчанию константам задаётся целочисленный тег, но можно указать любой другой тег при объявлении:
      PHP код:
      const Float// По умолчанию константам в списке будет задан тег Float, если не будет указан другой тег.
      {
          
      2.0// const Float:x = 2.0;
          
      3.0// const Float:y = 3.0;
          
      bool:true// const bool:b = true;
          
      4.0// const Float:z = 4.0;
      }; 

    2. (+) Появилась возможность создавать структуры с Си-подобным синтаксисом обращения к их полям.
      Рассмотрим это на примере структуры данных о студенте какого-нибудь ВУЗа:
      PHP код:
      const MAX_STUDENTS 1000;
      new 
      student[MAX_STUDENTS][.ID, .name[16], .surname[32]]; 
      Обращение к полю "ID" будет выглядеть следующим образом:
      PHP код:
      student[0].ID random(-1);
      printf("Student ID: %d\n"student[0].ID); 
      Также можно отдельно описать саму структуру, чтобы иметь возможность использовать её в нескольких переменных.
      Для этого в директиву #define добавлен синтаксис с квадратными скобками, позволяющий объявить макрос из нескольких строк без использования символа переноса строки "\".
      PHP код:
      #define s_Student [
      .ID,
      .
      name[16],
      .
      surname[32]
      ]
      new 
      student[MAX_STUDENTS][s_Student]; 
      Тем не менее, можно объявить структуру и с помощью старого синтаксиса #define:
      PHP код:
      #define s_Student\
      .ID,\
      .
      name[16],\
      .
      surname[32
      или даже так:
      PHP код:
      #define s_Student .ID, .name[16], .surname[32] 
      Во всех перечисленных выше вариантах можно добавить запятую после ".surname[32]", это не будет считаться ошибкой.


    3. (*) Упразднён оператор char, теперь массивы могут объявляться как массивы байт и массивы ячеек.
      PHP код:
      // массив из ячеек
      new cell_array[10];

      // массив из байтов
      // (фигурные скобки нужны, чтобы указать, что это массив байтов)
      new byte_array{10}; 
    4. Для инициализации массивов начальными значениями используется новый синтаксис.
      Какие скобки были использованы при указании размера массива (квадратные/фигурные), в такие и заключаются значения.
      PHP код:
      new byte_array{10} = { 012345678};
      new 
      cell_array[10] = [ 012345678]; 
      Оператор "..." всё ещё можно использовать для инициализации массивов, но теперь, если нужно задать список значений с инкрементом, следует указать, как минимум, два элемента макссива, а не один, как в предыдущих версиях.
      PHP код:
      new some_array[4] = [ 12, ... ]; // В Pawn 3.2 можно было написать "[ 1, ... ]", но в 4.0 это заполнит весь массив единицами. 
      Также доступна прогрессивная инициализация для многомерных массивов:
      PHP код:
      new some_array[4][4] = [ [ ], [ 2, ... ], [ 34, ... ], [ 569, ... ] ]; 
      Этот массив будет инициализирован следующими значениями:
      Код:
      // [ 1 0 0 0 ] - в 1-й строке указано значение лишь для 1-го столбца, остальные заполняются нулями.
      // [ 2 2 2 2 ] - использован оператор "...", но указано только одно значение "2", поэтому вся строка заполнена двойками.
      // [ 3 4 5 6 ] - использован "..." и указаны значения "3" и "4" - по ним компилятор поймёт, что каждый следующий элемент массива должен быть на 1 больше предыдущего.
      // [ 5, 6, 9, 12 ] - следует помнить, что компилятор учитывает только 2 последних значения перед "...", поэтому здесь инкремент равен трём (9 - 6 = 3).

    5. (*) Изменения в синтаксисе строк.
      Начиная с Pawn 4.0, все строки по умолчанию упакованные - теперь не нужно ставить восклицательный знак перед каждой строкой, чтобы она занимала меньше места в памяти.
      PHP код:
      "Это упакованная строка" // 22 символа -> 23 байта -> 8 ячеек (при размере ячейки в 4 байта) 
      Если вы хотите явным образом объявить массив для хранения упакованной строки, то вам понадобится массив байтов:
      PHP код:
      new packed_string{} = "Это упакованная строка"
      Для неупакованных строк доступны сразу 2 варианта синтаксиса:
      PHP код:
      new unpacked_string1[] = ''Это неупакованная строка''// обратите внимание: вместо кавычек используются двойные апострофы.
      new unpacked_string2[] = ``И это тоже неупакованная строка''// альтернативный синтаксис: для открытия строки вместо апострофов используется удвоенный гравис. 
      Об апострофах и грависах можете узнать из википедии: апостроф, гравис.

      При объявлении упакованной строки в неупакованном массиве и наоборот компилятор выдаст варнинг:
      PHP код:
      // на всех этих строках компилятор выдаст предупреждение
      // "warning 229: mixing packed and unpacked array indexing or array assignment"
      new packed_string1[] = "Sample text";
      new 
      packed_string2{} = ''Sample text'';
      new 
      unpacked_string1[] = "Sample text";
      new 
      unpacked_string2{} = ''Sample text''

    6. (*) В Pawn 3.2 строки можно было разделять на отрывки следующим образом:
      PHP код:
      new str[] = "Отрывок1" "Отрывок2" "Отрывок3"
      В версии 4.0 для этого требуется использовать оператор конкатенации "...":
      PHP код:
      new str[] = "Отрывок1" ... "Отрывок2" ... "Отрывок3"
      По аналогии оператор конкатенации теперь нужен и для переноса отрывков на следующую строку:
      PHP код:
      new str[] =
          
      "Отрывок1\n" ...
          
      "Отрывок2\n" ...
          
      "Отрывок3"

    7. (*) Теперь чтобы использовать знак ":" в макросах, он должен находиться внутри круглых "()" или угловых "<>" скобок.
      Например, следующий макрос будет считаться неправильным:
      PHP код:
      #define fpub:%0(%1) forward %0(%1);public %0(%1) // Работает в Pawn 3.2, в 4.0 компилятор выдаёт синтаксическую ошибку. 
      Тем не менее, это ограничение можно обойти:
      PHP код:
      #define fpub%0(%1) forward%0(%1);public%0(%1) 
      Пока что я не знаю точно, было ли так задумано, или это баг.


    8. (*) В Pawn 3.2 можно было вставлять в запись числа знак нижнего подчёркивания, чтобы число было удобнее читать:
      PHP код:
      new 10_000_000
      В Pawn 4.0 для тех же целей следует использовать апостроф, при попытке записи числа через нижнее подчёркивание компилятор выдаст ошибку.
      PHP код:
      new 10'000'000

    9. (+) (4.x) Добавлены директивы #ifdef и #ifndef для большей совместимости с языком C.
      К тому же, они просто удобнее, чем "#if defined".


    10. (+) (4.x) Добавлены директивы #warning и #pragma warning (push|pop|disable).
      Они уже были доступны в форке Zeex, теперь они есть и в 4.x.


    11. (+) (4.x) Для инклудов в дополнение к расширению ".inc" теперь доступно расширение ".i" по аналогии с расширением ".p" в дополнение к ".pawn".
      (Расширение ".pwn" не является стандартным, оно используется только в скриптах для SA-MP.)
      Рассмотрим следующий пример:
      PHP код:
      #include "my_inc"
      main(){} 
      Расширение инклуда "my_inc" не указано, поэтому компилятор попробует открыть файлы со следуюшими расширениями: ".i", ".inc", ".p", ".pawn".
      Поиск файла будет произведён строго в том порядке, который указан выше. Если в папке со скриптом есть файлы "my_inc.i" и "my_inc.inc", то компилятор найдёт первым и откроет файл с расширением ".i", проигнорировав "my_inc.inc".
      Если же у инклуда такое расширение, которого нет в списке, в директиве #include это расширение нужно указывать в явном виде (т.е. не "my_inc", а, например, "my_inc.h").


    12. (+) (4.x) Компилятор сам объединяет одинаковые константные массивы.
      Вы наверняка видели раньше тот трюк с объявлением массивов/строк вручную, чтобы они не дублировались в памяти:
      PHP код:
      static const string[] = "qwertyuiop\n";
      printf(string);
      printf(string); 
      В Pawn 4.0 этот приём устарел, поскольку теперь компилятор сам умеет объединять константные строки и массивы.
      PHP код:
      printf("qwertyuiop\n");
      printf("qwertyuiop\n"); // здесь будет обращение к тому же самому экземпляру строки 

    13. (*) Удалены директивы #emit и #endscript.


    14. (*) (4.x) Также удалены операторы *begin, *end и *then. Паскальщики негодуют.


    15. (+) Проведена ревизия всего набора инструкций AMX. Добавлены упакованные инструкции, в которых код операции и 1-й операнд умещаются в одну ячейку, благодаря чему достигается большая компактность кода и потенциал к более быстрой работе интерпретатора.
      Например, при конфигурации размера ячейки в 4 байта код операции располагается в младших 2 байтах, а операнд - в старших. Разумеется, это работает только если операнд умещается в те старшие 2 байта, иначе компилятор сгенерирует неупакованный вариант инструкции.


    16. (+) Помимо упакованных опкодов в поле flags заголовка AMX добавлен флаг AMX_FLAG_CRYPT, который сигнализирует о том, что скрипт зашифрован.
      По умолчанию предлагается использовать алгоритм шифрования KeeLoq, но можно вручную добавить любой другой алгоритм.


    17. (+) (4.x) Кроме main() в Pawn 4.0 точкой входа в скрипт могут считаться функции entry() и @start(). Впрочем, в скрипте разрешается использовать только одну из них, т.к. точка входа может быть лишь одна.
      Также теперь можно использовать exit() для указания точки выхода. Эти функции могут вызываться при загрузке и выгрузке скрипта соответственно (могут, но не обязаны, всё зависит от того, где используется интерпретатор Pawn и предусмотрен ли там вызов main/@start/entry/exit).


    18. (FIX) (4.x) Исправлен баг в strcmp, из-за которого функция возвращала 0, если одна из сравниваемых строк была пустая.


    19. (FIX) (4.x) Исправлен баг в strins, из-за которого был возможен выход за пределы буфера (функция игнорировала аргумент maxlength).


    20. (FIX) (4.x) Теперь функции printf и strformat правильно выводят число -2147483647 (раньше вместо этого числа выводился только знак "-").


    21. (FIX) (4.x) Исправлен баг, из-за которого оператор tagof нельзя было использовать со скобками в метках конструкции switch.


    22. (FIX) (4.x) Оператор tagof больше не возвращает разные ID для целых чисел и тега "_".


    23. (FIX) (4.x) Исправлена проблема, связанная с неправильным генерированием инструкций из кода, находящегося внутри условно компилируемых секций #if ... #else ... #endif.



    Это весь список отличий, который мне удалось вспомнить. Если вы знаете что-то ещё, что есть в Pawn 4.x, но чего нет в Pawn 3.2, буду рад услышать об этом в комментариях.


    Автор: Daniel_Cortez

    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Последний раз редактировалось Daniel_Cortez; 12.09.2016 в 19:44. Причина: update (2)
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 14 пользователя(ей) сказали cпасибо:
    Battista (25.09.2016) DeimoS (24.08.2016) Desulaid (24.08.2016) enj0y (23.06.2017) Geebrox (12.11.2016) Glant (26.11.2016) L0ndl3m (24.08.2016) Nash_Brigers (24.08.2016) Nurick (12.09.2016) Osetin (24.08.2016) Profyan (24.08.2016) Saibot (24.08.2016) vovandolg (24.08.2016) _lizard (24.08.2016)
  3. #2
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Ещё добавили прогрессивную инициализацию многомерных массивов:
    PHP код:
    new c[3][3] = [ [ ], [ 2, ...], [ 34, ... ] ] 
    Ещё добавили удобную директиву __line.
    Но это есть в Pawn от Zeex. Хотя не нашёл #warning и #pragma warning, видимо это было добавлено Zeex, но штука довольно удобная.

    Ещё можно тэги объявлять с помощью const (но это не обязательно):
    PHP код:
    const tagname constant list } 
    P.S. Мне не очень нравятся такие удвоенные кавычки, да и в качестве разделителя чисел они смотрятся странно.
    Последний раз редактировалось ziggi; 24.08.2016 в 08:10.

  4. #3
    Аватар для vovandolg
    Пользователь

    Статус
    Оффлайн
    Регистрация
    17.11.2015
    Адрес
    Stavropol
    Сообщений
    1,369
    Репутация:
    113 ±
    По 12 пункту хочу уточнить, защиты от DeAMX не будет для этой версий?
    Или придется юзать старую традиционную что при включении мода запускается-_-
    [Anticheat]___Invisible Fly Hack
    [Anticheat]____Weapon/Ammo Hack
    [Function]______ResetPlayerWeaponSlot
    [Function]_______FIX_SetPlayerAmmo
    [ServerMod]______TDM | Zombie Apokalypse

  5. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Ещё добавили прогрессивную инициализацию многомерных массивов:
    PHP код:
    new c[3][3] = [ [ ], [ 2, ...], [ 34, ... ] ] 
    Да, спасибо, что напомнил. Я ещё забыл написать, что для инициализации с инкрементом значений необходимо указать, как минимум, 2 элемента массива, а не 1, как раньше.
    Добавил это всё в 4-й пункт, твой пример пришлось немного изменить.


    Цитата Сообщение от ziggi Посмотреть сообщение
    Ещё добавили удобную директиву __line.
    Но это есть в Pawn от Zeex.
    Даже не знаю, стоит ли об этом вообще упоминать - всё равно те немногие, кому нужна эта константа, отнюдь не первый день пишут код и уже давно пользуются компилятором от Zeex.


    Цитата Сообщение от ziggi Посмотреть сообщение
    Хотя не нашёл #warning и #pragma warning, видимо это было добавлено Zeex, но штука довольно удобная.
    Да, действительно. Можно попросить разработчика Pawn (Thiadmer Riemersma) добавить эти директивы (он уже добавил #ifdef и #ifndef, так что не думаю, что это будет сильно сложно для него).
    Но только не от моего имени. Впрочем, если нужно, могу помочь с составлением текста (хоть и не могу сказать, что так уж хорошо знаю инглиш).
    Я бы и сам рад спросить его, но не хочу, чтобы это выглядело, как будто я перегружаю его работой - он и без того ей завален в последнее время, из-за чего поздно отвечает на багрепорты (которых я, наверное, уже насоздавал предостаточно, и ещё несколько собираюсь сделать).


    Цитата Сообщение от ziggi Посмотреть сообщение
    Ещё можно тэги объявлять с помощью const (но это не обязательно):
    PHP код:
    const tagname constant list } 
    Это не теги, а список констант с тегом, отличным от целочисленного. Я добавил ещё один пример в 1-й пункт.


    Цитата Сообщение от ziggi Посмотреть сообщение
    P.S. Мне не очень нравятся такие удвоенные кавычки, да и в качестве разделителя чисел они смотрятся странно.
    Удвоенный апостроф нужен только для того, чтобы объявлять неупакованные строки, а строки в обычных кавычках теперь являются упакованными. Похоже, что это было сделано с расчётом на то, что неупакованные строки почти нигде не нужны и синтаксис для них не сильно критичен.
    А по поводу чисел - да, хороший вопрос, я и сам ума не приложу, зачем он так сделал. Можно в том же feature request попросить его вернуть возможность разделять цифры нижними подчёркиваниями.


    Цитата Сообщение от vovandolg Посмотреть сообщение
    По 12 пункту хочу уточнить, защиты от DeAMX не будет для этой версий?
    Или придется юзать старую традиционную что при включении мода запускается-_-
    Для нового набора инструкций ещё нет никакого DeAMX. А если даже и сделают, то в 4.0 предусмотрена возможность для шифрования скриптов. Я добавил более подробную информацию в 1-й пост 15-м пунктом.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  6. #5
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Да, действительно. Можно попросить разработчика Pawn (Thiadmer Riemersma) добавить эти директивы (он уже добавил #ifdef и #ifndef, так что не думаю, что это будет сильно сложно для него).
    Но только не от моего имени. Впрочем, если нужно, могу помочь с составлением текста (хоть и не могу сказать, что так уж хорошо знаю инглиш).
    Я бы и сам рад спросить его, но не хочу, чтобы это выглядело, как будто я перегружаю его работой - он и без того ей завален в последнее время, из-за чего поздно отвечает на багрепорты (которых я, наверное, уже насоздавал предостаточно, и ещё несколько собираюсь сделать).
    Сделано.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Удвоенный апостроф нужен только для того, чтобы объявлять неупакованные строки, а строки в обычных кавычках теперь являются упакованными. Похоже, что это было сделано с расчётом на то, что неупакованные строки почти нигде не нужны и синтаксис для них не сильно критичен.
    Этого я не учёл. И правда, трудно придумать случай, где может потребоваться не упакованная строка (разве что для расширенного набора символов, но не уверен, что это поддерживается).

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    А по поводу чисел - да, хороший вопрос, я и сам ума не приложу, зачем он так сделал. Можно в том же feature request попросить его вернуть возможность разделять цифры нижними подчёркиваниями.
    Позже создам, если никто не захочет опередить.

  7. #6
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    ALS не работает? У меня компилятор зацикливается.
    Код:
    .\default.pwn(49) : warning 208: function "Prefix2_OnGameModeInit" is used before definition, a forward declaration is recommended
    .\default.pwn(36) : warning 208: function "Prefix2_OnGameModeInit" is used before definition, a forward declaration is recommended
    .\default.pwn(24) : warning 208: function "Prefix_OnGameModeInit" is used before definition, a forward declaration is recommended

  8. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    ALS не работает? У меня компилятор зацикливается.
    Код:
    .\default.pwn(49) : warning 208: function "Prefix2_OnGameModeInit" is used before definition, a forward declaration is recommended
    .\default.pwn(36) : warning 208: function "Prefix2_OnGameModeInit" is used before definition, a forward declaration is recommended
    .\default.pwn(24) : warning 208: function "Prefix_OnGameModeInit" is used before definition, a forward declaration is recommended
    Да, действительно.
    Как будто потери настраиваемого инкремента в enum и замены на const было мало... -_-

    Что интересно, перехват функций работает в Pawn 4.0, зацикливание проявляется только в последней разрабатываемой версии.
    И я так понимаю, началось это всё после коммита 6de1822.

    Мне сообщить об этом баге или ты сам?


    UPD: Буквально 20 минут назад были добавлены директивы #error и #pragma warning. Ура, товарищи!
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #8
    Аватар для TheMallard
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2015
    Адрес
    San Fierro
    Сообщений
    217
    Репутация:
    39 ±
    Написал о возврате поведения препроцессора (ALS): https://github.com/compuphase/pawn/issues/28

  10. #9
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    UPD: Буквально 20 минут назад были добавлены директивы #error и #pragma warning. Ура, товарищи!
    Да и теги пофиксили, красота)

    Цитата Сообщение от TheMallard Посмотреть сообщение
    Написал о возврате поведения препроцессора (ALS): https://github.com/compuphase/pawn/issues/28
    Отлично, надеюсь пофиксят.

  11. #10
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от TheMallard Посмотреть сообщение
    Написал о возврате поведения препроцессора (ALS): https://github.com/compuphase/pawn/issues/28
    В следующий раз прилагайте к отчёту примеры кода и сообщений компилятора, дабы разработчику Pawn было проще разобраться - у него и так почти не остаётся свободного времени из-за работы.

    P.S.: Добавил #warning и #pragma warning в 1-й пост 10-м пунктом.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

 

 
Страница 1 из 3 1 2 3 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •