Главная | Комментарии | О проекте
Чтение RSS
Суперсайт
Главная Контакты Карта сайта Добавить в избранное
  • Кто OnLine

    Всего на сайте: 5
    Гостей: 5
    Пользователи: - отсутствуют
    Роботы: - отсутствуют

    Опрос пользователей

    Для какого мода Вы пишите плагины?

    • Популярное

    Рекомендуем

    • AMX Mod X
    • up.org.ua

    Наши друзья


  • Автор: Admin Дата: 19-12-2011, 12:35 Просмотров: 5474

    Урок 8. Стилистика кода или как правильно оформлять свой код.

    Прежде чем начать, хочу сказать, что эта статья придумана не мной, я лишь ее прочел и перевел на русский язык, немного подкорректировав, как я ее понимаю. Речь же в ней пойдет о том, как правильно оформлять свой код, где и как оставлять комментарии, как называть переменные и функции, отступы и друге. На самом деле данная статья должна быть одной из первых, что бы с самого начала учиться правильно оформлять свои плагины и не вырабатывать у себя дурные привычки. Я, к сожалению не знал этого и на сегодняшний день у меня целый набор дурных привычек.


    Вводный блок с комментариями

    Лучшее место комментариев к плагину это самое его начало, в комментарий желательно поместить всю необходимую информацию о палгине, такую как:
    • Что он делает
    • Настройки
    • Команды для игроков и администраторов
    • Журнал изменений
    • ...


    Блок комментариев можно и пропустить, если вы не собираетесь выкладывать в паблик свой плагн, но даже для себя его лучше сделать, смотрится как кто солиднее.

    copyleft уведомление является ненужным, но хорошо бы по чаще напоминать людям, что все плагины AMXX – распространяются под лицензий GPL'd.

    Вот пример, не плохого на мой взгляд вводного комментария:
    /***********************************************
    *  Access.ini for players    (example: "nick or ip" "pass" "flags")
    *  Denied.ini for subnets    (example: "ip" "mask" "flags")
    *
    *  if #define SUBNET_REVERSE is comment then
    *  Access.ini list of nicks,who can join from banned subnets
    *  Denied.ini list of banned subnets
    *
    *  if #define SUBNET_REVERSE is uncomment then
    *  Access.ini list of nicks,who can't join from access subnets
    *  Denied.ini list of access subnets,others are banned
    *
    *  ATTENTION!!! HELP for BAN (for that who don't know)
    *  copyleft http://ipcalc.dewil.ru/
    *
    ************************************************
    *
    *  CREATE TABLE bansubnets (
    *  id int(11) NOT NULL auto_increment,
    *  subipaddr VARCHAR(32) NOT NULL,
    *  bitmask VARCHAR(2) NOT NULL,
    *  flags VARCHAR(32) NOT NULL,
    *  comment TEXT NOT NULL,
    *  PRIMARY KEY (id));
    *
    ************************************************/


    Макросы и Препроцессор

    Честно говоря, сам не до конца понимаю все что с этим связано, по этому буквально в двух словах об этом разделе.
    После комментариев логичнее всего сразу же включить в плагин все необходимые вам инклюды
    #include <amxmodx>
    А так же константы:
    #define MAX_ITEMS 10
    Обратите внимание, что константы записывать лучше заглавными буквами, что бы не путать их с переменными.

    Единственное исключение для макро-функциональных определений:
    #define MyNewIsUserAlive(%1) is_user_alive( %1 )
    Это является приемлемым, потому что макрос по существу действует как функция.


    Добавление отступов

    Весь плагин состоит из функций, в некоторых функциях есть условия, в нутрии этих условий циклы и такое вложение может быть многократным, что бы это все было наглядно видно, принято делать отступ для каждой вложенной функции или условия, ниже приведу 2 примера для наглядности:

    Код без отступов:
    public client_connect(id) {
    if (is_user_bot(id) || access(id, ADMIN_RESERVATION) || is_user_hltv(id)) {
    return PLUGIN_HANDLED
    } else {

    if (sql == Empty_Handle) {
    server_print(NotConnectMSG, Tag, error)
    if (file_exists(AccessFile)) {
    new Areaddata[101], Alen, Apos = 0
    if (!file_size(AccessFile, 0)) {
    Denied(id)
    server_print(EmptyPlMSG, Tag)
    } else {
    while(read_file(AccessFile, Apos++, Areaddata, 100, Alen)) {
    if (Areaddata[0] == ';' || !Alen)
    continue

    parse(Areaddata, Ident, 31, Apass, 31, UFlags, 21)
    if (equal(Ident, name) || equal(Ident, ip)) {
    plrAccess(id)
    }
    }
    }
    }
    }
    }
    }

    И код с отступами:
    public client_connect(id) 
    {
        if (is_user_bot(id) || access(id, ADMIN_RESERVATION) || is_user_hltv(id))
        {
            return PLUGIN_HANDLED
        } else
        {

            if (sql == Empty_Handle)
            {
                server_print(NotConnectMSG, Tag, error)
                if (file_exists(AccessFile))
                {
                    new Areaddata[101], Alen, Apos = 0
                    if (!file_size(AccessFile, 0))
                    {
                        Denied(id)
                        server_print(EmptyPlMSG, Tag)
                    } else
                    {
                        while(read_file(AccessFile, Apos++, Areaddata, 100, Alen))
                        {
                            if (Areaddata[0] == ';' || !Alen)
                                continue

                            parse(Areaddata, Ident, 31, Apass, 31, UFlags, 21)
                            if (equal(Ident, name) || equal(Ident, ip))
                            {
                                plrAccess(id)
                            }
                        }
                    }
                }
            }
        }
    }


    Теперь думаю, вы наглядно увидели разницу и преимущество отступов.
    А так же с отступами легче уследить за всеми кавычками, с которыми у новичков очень много проблем.

    Просто возьмите себе за правило, весь код заключенный межу кавычками { code }
    Должен имеет отступ, если в нутрии этого кода появились еще такие же кавычки, то этот код будет уже с двойным отступом и так по мере вложенности.
    А так же, что бы открывающая и закрывающая кавычки были на одном уровне, что облегчит вам поиск незакрытой кавычки и сделает еще более понятным код.


    Название для функций.

    Что бы код был как можно более легко читаемый, все функции должны иметь, понятные названия и при этом красиво написаны.

    Вот пример красивой и понятной функции:
    public EventDeathMsg()

    А могло бы быть так:
    public deathmsg()

    В первом варианте сразу видно, что это за функция, а во втором? Тоже видно, но не так очевидно и не красиво.

    Добавление префикса типа переменной.

    Если плагин меньше 100 строк, то в принципе ни каких особых проблем не будет, а вот если более 1000, сможете ли вы запомнить все переменные? А их тип? Сомневаюсь…
    Для начала выделим глобальные переменные префиксом g
    new gMyVariable

    Или
    new g_MyVariable

    Объявлять глобальные переменные лучше каждую отдельно, это облегчит поиск в случае необходимости.
    new g_MyVariable
    new g_MyOtherVariable

    в место
    new g_MyVariable, g_MyOtherVariable

    Для глобальных переменных я бы рекомендовал второй способ.


    "Венгерская запись" типов переменных (HN).

    Некоторые люди также тегируют свои имена переменных их типом:
    • g или g_ - глобальные переменные
    • p или p_ pointers
    • i - целые числа/ячейки
    • f или fl – дробные числа
    • sz - строки
    • b – bools Булевые переменные
    • h - дескрипторы
    • v - векторы (не стандарт к HN, но все еще полезный)
    • fn – функция

    Вот несколько примеров тегированных переменных:
    // a global cell
    new g_iKills

    // a global float
    new Float:g_flSpeed

    // a bool
    new bool:bFlag

    // a function
    public fnEventResetHUD()

    // a pointer
    new g_pCvar

    В сложных плагинах это поможет вам не запутаться в огромном количестве переменных и массивов.

    Комментарии.

    Комментарии к коду очень важны, даже если вы не следуете ни каким правилам или системе по называнию переменных и функций, но ваши комментарии хорошо описывают каждый блок, то и вам самим и другим пользователям вашего кода, будет доставлять наслаждение работать с вашим плагином.

    Комментарии бывают 2х видов
    Многострочный
    /* 
    this is a nested comment
    this is a nested comment
    this is a nested comment
    */


    И однострочный
    // this is a nested comment 


    Главное запомните что PAWN не поддерживает вложенные комментарии:
    /* 
        this is the first comment
        /* this is a nested comment */
                                                   */

    Обратили внимание на то, что последние закрывающие комментарий символы */ подсвечены зеленым? Это кА КрАЗ из за того что не поддерживаются вложенные комментарии, будьте внимательны!



    Пробелы или пустые строки

    Что бы код был легко читаем, он должен быть разбит на блоки, вы скажете что он и так разбит на функции и условия, но и тут не все так просто, можно еще немного разбить, вот пример:
    MyFunction()
    {
        new id = random_num( 1, 13 )
        user_kill( id )

        set_pcvar_num( p_MyCvar, 9 )
    }

    Как видно в функции MyFunction происходит 2 не зависящих друг от друга дела, но к первому дело еще необходимо создать переменную, так как эти две строчки напрямую взаимосвязаны они и стоят в плотную, а вот следующая функция не связанна с ними ни как и стоит через пустую стоку, что визуально делит код на части.

    В заключении хотел сказать, что у каждого человека есть свой индивидуальный стиль, но если каждый будет следовать общепринятым стилям, то разбираться в чужом коде всем станет легче. Все что выше было изложено, не является, каким либо правилом или законом, это всего лишь рекомендации. Поверьте, они написаны не от балды, а по опыту и вам же будет легче, если вы с самого начала будете писать плагины правильно.
    Это что-то вроде урока чистописания.
    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
    MegaTroll

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Боюсь, мой комментарий запоздал, но статья прекрасна! Мало кто придерживается эстетики в коде smile
    _ck

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Да,интересная статься.. Только очень серьёзная ошибка у тебя - ты перепутал кавычки со скобками! Это два разных символа,исправь! Ну и несколько орфографических ошибок.. Старайся проверять статьи перед публикацией.. За старание тебе спасибо! Многих на пользу пойдёт,мне тем более)

    Информация

    Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Наверх

Реклама