Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 5 из 5
  1. #1
    Аватар для DCL
    Пользователь

    Статус
    Оффлайн
    Регистрация
    16.08.2015
    Сообщений
    0
    Репутация:
    0 ±

    Создание чистого и читаемого кода

    Автор: CalvinC
    Ссылка на оригинальную тему: http://forum.sa-mp.com/showthread.php?t=563078
    Перевод: translate.ru, DCL


    ***

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

    Описание:
    Прочитав эту тему, вы научитесь писать более чистый и оптимизированный код, а так же возьмете себе что - нибудь на заметку.

    Часть 1 - табуляция
    Вы вероятно знаете, что такое табуляция и как ей пользоваться. Но я решил включить это в тему, т.к. так или иначе люди иногда допускают ошибки при компилировании (warning 217), или вообще отключают их. Даже если игнорировать все предупреждения, ваш код будет неудобно читать. Вот один из примеров:

    PHP код:
    CMD:toggle(playeridparams[])
    {
    if(
    sscanf(params"s[14]"params))
    {
    SendClientMessage(playerid, -1"/toggle [option]");
    SendClientMessage(playerid, -1"Options: PM");
    }
    if(!
    strcmp(params"pm"true))
    {
    switch(
    pm[playerid])
    {
    case 
    0:
    {
    pm[playerid] = 1;
    SendClientMessage(playerid, -1"You have toggled PM's off.");
    }
    case 
    1:
    {
    pm[playerid] = 0;
    SendClientMessage(playerid, -1"You have toggled PM's on.");
    }
    }
    }
    return 
    1;

    Множество людей, использующих это обычно ставят фигурные скобки в ряд ({, }), тем самым иногда нельзя понять - какую из скобок вы закрыли, а какую нет. Но если же использовать табуляцию, вы сможете видеть, закрываются скобки или нет.

    PHP код:
    CMD:toggle(playeridparams[])
    {
        if(
    sscanf(params"s[14]"params))
        {
            
    SendClientMessage(playerid, -1"/toggle [option]");
            
    SendClientMessage(playerid, -1"Options: PM");
        }
        if(!
    strcmp(params"pm"true))
        {
            switch(
    pm[playerid])
            {
                case 
    0:
                {
                    
    pm[playerid] = 1;
                    
    SendClientMessage(playerid, -1"You have toggled PM's off.");
                }
                case 
    1:
                {
                    
    pm[playerid] = 0;
                    
    SendClientMessage(playerid, -1"You have toggled PM's on.");
                }
            }
        }
        return 
    1;

    После каждой открытой скобки вы должны нажать 4 раза клавишу пробел (или 1 раз клавишу TAB).
    После каждой закрытой скобки вы должны сделать 4 пробела назад.

    От меня: мне кажется, тут проще будет сделать табуляцию через notepad++, вот тема, которая наглядно показывает весь процесс: http://***********.ru/showthread.php?t=249112
    Если вам необходимо передвинуть много кода в одну из сторон, выделите его, чтобы передвинуть вперед - нажмите TAB, назад - SHIFT

    Часть 2 - использование скобок (1/2)
    Вы конечно можете использовать табуляцию для расстановки скобок и они даже могут быть расставлены правильно, но может быть, они вам не нужны совсем?

    PHP код:
    CMD:pm(playeridparams[])
    {
        new 
    targetidmessage[128];
        if(
    sscanf(params"us"targetidmessage))
        {
            
    SendClientMessage(playerid, -1"/pm [playerid] [message]");
            return 
    1;
        }
        if(
    pm[playerid] == 0)
        {
            
    SendClientMessage(playerid, -1"Your PM's are turned off.");
        }
        else if(
    pm[targetid] == 1)
        {
            
    SendClientMessage(playerid, -1"Your PM's are turned on.");
        }
        else
        {
            
    SendClientMessage(targetid, -1"PM Received.");
            
    SendClientMessage(playerid, -1"PM Sent");
        }
        return 
    1;

    Как Вы видите, это будет работать, но нет никакой необходимости во всех тех скобках.
    Поэтому давайте попытаемся убрать этот код немного.
    Давайте смотреть на первую часть кода:

    PHP код:
    if(sscanf(params"us"targetidmessage))
    {
        
    SendClientMessage(playerid, -1"/pm [playerid] [message]");
        return 
    1;

    Мы возвращаем 1, когда можем просто вернуть SendClientMessage - одно и то же, но плюс к оптимизации.

    PHP код:
    if(sscanf(params"us"targetidmessage))
    {
        return 
    SendClientMessage(playerid, -1"/pm [playerid] [message]");

    Код выше будет работать точно так же, как и в случае с возвращением 1. Но мы можем обойтись вообще без скобок, потому что нам не обязательно даже возвращать SendClientMessage.

    PHP код:
    if(sscanf(params"us"targetidmessage)) return SendClientMessage(playerid, -1"/pm [playerid] [message]"); 
    Как вы видите, мы из 5 строк сделали 1. И это осталось так же работоспособным. Такое же действие мы можем сделать и с остальной командой, поскольку мы заключаем 1 - 2 функции в скобки.

    PHP код:
    CMD:pm(playeridparams[])
    {
        new 
    targetidmessage[128];
        if(
    sscanf(params"us"targetidmessage)) return SendClientMessage(playerid, -1"/pm [playerid] [message]");
        if(
    pm[playerid] == 0SendClientMessage(playerid, -1"Your PM's are turned off.");
        else if(
    pm[targetid] == 1SendClientMessage(playerid, -1"Your PM's are turned on.");
        else
        {
            
    SendClientMessage(targetid, -1"PM Received.");
            
    SendClientMessage(playerid, -1"PM Sent");
        }
        return 
    1;

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

    PHP код:
    else
    {
        
    SendClientMessage(targetid, -1"PM Received.");
        
    SendClientMessage(playerid, -1"PM Sent");

    Мы можем сделать так:

    PHP код:
    else SendClientMessage(targetid, -1"PM Received."); SendClientMessage(playerid, -1"PM Sent"); 
    Это не будет работать, поскольку компилятор увидит его следующим образом:

    PHP код:
    else SendClientMessage(targetid, -1"PM Received.");
    SendClientMessage(playerid, -1"PM Sent"); 
    Поэтому в игре, если выполнится условие, то вам напишет "PM Received", а "PM Sent" останется независимым и не будет принадлежать к условию.

    От меня: можно поставить запятую и как раз таки вместить 2 функции в 1 строчку, при этом условие будет выполнятся.

    PHP код:
    else SendClientMessage(targetid, -1"PM Received."), SendClientMessage(playerid, -1"PM Sent"); 
    Часть 3 - использование скобок (2/2)
    Скобки могут использоваться по разному. Один из способов представляет собой что-то вроде этого:

    PHP код:
    CMD:pm(playeridparams[])
    {
        new 
    targetidmessage[128];
        if(
    sscanf(params"us"targetidmessage)) return SendClientMessage(playerid, -1"/pm [playerid] [message]");
        if(
    pm[playerid] == 0SendClientMessage(playerid, -1"Your PM's are turned off.");
        else if(
    pm[targetid] == 1SendClientMessage(playerid, -1"Your PM's are turned on.");
        else
        {
            
    SendClientMessage(targetid, -1"PM Received.");
            
    SendClientMessage(playerid, -1"PM Sent");
        }
        return 
    1;

    До этого мы уже разбирали с вами использование скобок и табуляцию, но вы можете сделать по другому:

    PHP код:
    CMD:pm(playeridparams[]) {
        new 
    targetidmessage[128];
        if(
    sscanf(params"us"targetidmessage)) return SendClientMessage(playerid, -1"/pm [playerid] [message]");
        if(
    pm[playerid] == 0SendClientMessage(playerid, -1"Your PM's are turned off.");
        else if(
    pm[targetid] == 1SendClientMessage(playerid, -1"Your PM's are turned on.");
        else {
            
    SendClientMessage(targetid, -1"PM Received.");
            
    SendClientMessage(playerid, -1"PM Sent"); }
        return 
    1; } 
    Как вы видите, этот способ делает код визуально меньше, но при этом он усложняет чтение кода и вы можете пропустить незакрытые скобки.

    Часть 3 - сравнения "==, >, !, &&, ||"
    Кратко об этом:

    (что-то) == (что-то еще) - Что-то равняется чему-то еще

    (что-то) > (что-то еще) - Что-то больше, чем что-то еще

    (что-то) < (что-то еще) - Что-то меньше, чем что-то еще

    (что-то) && (что-то еще) - Что-то и что-то еще

    (что-то) || (что-то еще) - Что-то или что-то еще

    "!" это специальный знак, может использоваться как "больше", но обычно его используют как "не"

    (что-то) != (что-то еще) - Что-то не равняется чему-то еще

    Использование: !(переменная/функция)

    Некоторые люди создают длинные коды, вместо того, чтобы сделать маленький код. Особенно использование "!" в функции strcmp может значительно сократить ее.

    Без "!":

    PHP код:
    if(strcmp(params"pm"true) == 0
    С "!":

    PHP код:
    if(!strcmp(params"pm"true)) 
    Часть 4 - пользовательские функции
    Есть функции, которые a_samp дает вам по умолчанию, например GivePlayerMoney. Но вы так же можете создавать и свои функции, что существенно сокращает код, особенно если вы используете один и тот же код в нескольких местах.
    Вот пример своей функции:

    PHP код:
    SetPlayerMoney(playeridamount)
    {
        
    ResetPlayerMoney(playerid);
        return 
    GivePlayerMoney(playeridamount);

    Теперь если мы хотим установить деньги игрока, мы просто используем эту функцию:

    PHP код:
    SetPlayerMoney(playerid100); 
    Это, конечно, не может быть самым совершенным примером, но я вас натолкнул на идею.

    Часть 5 - define
    Использование define позволит вам сделать код более красивым и читаемым. Define определяет что - то к чему то еще (по принципу макросов).
    На примере define можно сделать, допустим, цвет сообщений, например, вместо этого:

    PHP код:
    CMD:redmessage(playeridparams[]) return SendClientMessage(playerid0xFF0000AA"This message is red"); 
    Как вы видите, тут мы снова не используем скобки, но суть не в этом.
    Если вы используете много одного и того же цвета в сообщениях, то вам необходимо больше запоминать цвет, вы можете просто его "задефайнить"

    PHP код:
    #define COLOR_RED 0xFF0000AA // Добавьте вверх своего мода

    CMD:redmessage(playeridparams[]) return SendClientMessage(playeridCOLOR_RED"This message is red"); 
    Таким образом, если вам нужно будет изменить цвет во всех сообщениях, просто измените его в define.
    Это - все, что я имею на данный момент, я знаю много людей, которые хотят писать чистый и оптимизированный код, я надеюсь что данный урок поможет вам. Я обновлю это учебное руководство, если я найду какие-либо ошибки или другие улучшения.

  2. #2
    Аватар для wAx
    ¯\_(ツ)_/¯

    Статус
    Оффлайн
    Регистрация
    13.12.2013
    Сообщений
    377
    Репутация:
    146 ±
    есть подобная тема, после прочтения которой, в твоей я не увидел ничего нового...

  3. #3
    Аватар для Desulaid
    лесоруб продакшен

    Статус
    Оффлайн
    Регистрация
    15.03.2015
    Адрес
    Slobodskoy
    Сообщений
    667
    Репутация:
    236 ±
    Не знаю как вам, но мне вариант

    PHP код:
    CMD:redmessage(playeridparams[]) return SendClientMessage(playeridCOLOR_RED"This message is red"); 
    видится не очень читаемым :( Лучше делать с блоками

    PHP код:
    CMD:redmessage(playeridparams[]) 
    {
        return 
    SendClientMessage(playeridCOLOR_RED"This message is red");  


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

    Статус
    Оффлайн
    Регистрация
    06.11.2015
    Сообщений
    40
    Репутация:
    10 ±
    если честно автор(оригинальный), втирает какую-то дичь:) из всех стилей слепил стиль CalvinC'a, уж если писать так уж в одном стиле. Лично я предпочитаю стиль Олмана.

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

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

 

 

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

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

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

Ваши права

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