ГлавнаяБлогКарты Warcraft 3Гайды для первой ДотыГайды для Доты 2 [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 4
  • 1
  • 2
  • 3
  • 4
  • »
Локальные переменные
Дата: Воскресенье, 08.07.2012, 07:04 | Сообщение # 1
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
Итак, после ознакомления с азами Jass копнём чуть поглубже и разберём два вида переменных.
В Jass существует 2 вида переменных - локальные и глобальные. Разберём плюсы и минусы каждого из них.

Локальные:
+ Сохраняют своё значение после ожиданий.
+ Создаются уникально при каждом запуске триггера (не перезаписываются после второго запуска триггера).
+ Легко регулируемы.
+ MUI.

- Действуют только в пределах функции, где их задали.

Глобальные:
+ Действуют во всех триггерах карты.

+ MPI (Хоть и массивным способом)

- Есть риск потерять значение после ожидания (Если триггер запустится во время ожидания, переменная перезапишется).
- Каждый раз нужно писать приставку udg_
- Немного неудобны по сравнению с локальными.

Лучше по возможности отказываться от глобальных переменных и использовать только локальные (Исключение - хеш-таблицы), т.к. они дают гарантию того, что значение сохранится.
Как объявить локальную переменную? Очень просто:

[bgcolor=#FFFFFF]local <тип> <название>[/bgcolor]

Пример:
[bgcolor=#FFFFFF]local integeri[/bgcolor]


Это будет целочисленная под названием i. Вводя название, мы обращаемся к целочисленной переменной.
Кое-когда объявляют переменные и тут же задают им значение:

[bgcolor=#FFFFFF]local <тип> <название> = <значение>[/bgcolor]

Пример:
[bgcolor=#FFFFFF]local integer i =
0[/bgcolor]

Тогда наша целочисленная будет равна 0.
Можно задать её значение не сразу, а по ходу кода. Делают это так:

[bgcolor=#FFFFFF]set <название> = <значение>[/bgcolor]

Пример:
[bgcolor=#FFFFFF]set i =
0[/bgcolor]

Подобным образом задают глобальные переменные, но добавляют приставку udg_
[bgcolor=#FFFFFF]set udg_<название> = <значение>[/bgcolor]

Пример:
[bgcolor=#FFFFFF]set udg_Integer =
0[/bgcolor]

Глобальные переменные создаются в Редакторе переменных, локальные же - только в функциях непосредственно.
Переменные бывают утечные (те, которые наследуются от типа handle), их надо обнулять:

[bgcolor=#FFFFFF]set <название> = null[/bgcolor]

Неутечные типы переменных: boolean, integer, real. Запомните их. Из не нужно обнулять

handle - самый интересный тип, дескриптор/ссылка, отвечает за положение объекта в памяти. Занимает 4 байта, что позволяет сравнивать его с integer. Имеет более 9000 дочерних типов (конкретно 74, если я ничего не забыл), однако я отмечу только несколько: boolexpr, widget, trigger, timer, group, texttag. Наиболее сложный из них - widget - собирательный тип всех объектов, имеющих здоровье. Иначе говоря дочерними типами widget являются unit, destructable и item.

Оптимизация.

И так, наверно уже все наслышаны, что бездумное использование языка Jass (и через GUI тем более), приводит к так называемым "утечкам" памяти. Речь идёт не о вытекании памяти из вашего компьютера, так что можно не бояться. В общем смысле под "утечкой" подразумевают отсутствие своевременного освобождения памяти тем, или иным объектом. Доступной памяти становится меньше, следовательно, у ещё свободных ячеек начинает скапливаться очередь. В очереди принято ждать, верно? Это ожидание причина лагов, которые можно получить уже через небольшой промежуток времени. При достаточном угле изгиба рук можно добиться даже полного вылета из игры (но нужно действительно постараться).

Что же делать?! Первым делом не стоит паниковать, если ваш код выполняется только 1-2 раза за 2 часа, то ничего страшного не произойдет, даже если он (код) страшен как атомная война. Но если промежуток между вызовами вашего триггера плавно приближается к 0.0, то уже через n секунд вы сможете на здоровье любоваться прекрасными лагами даже с 4 ГБ оперативки.

Также перед оптимизацией очень важно остановится и подумать (вообще хорошая черта программиста). Увидев не обнуленные переменные типа handle (timer, unit...) не стоит сразу изрыгать потоки ненависти, вспомним что вообще такое переменная. А ведь по сути это просто ссылка на ячейку памяти с определённым объектом, будь-то integer или unit. Вы можете лёгким движение руки (пальцев) установить значение переменной на null. Вот только это никак не повлияет на сам объект. Он удаляется только специальными функциями (их 100500, не буду их перечислять). Тогда зачем вообще нужно обнуления?!

Хитрость в том, что, даже получив, приказ удалится, объект не будет этого делать пока есть ссылки (переменные) на него. Непонятно? Тогда вот пример: допустим, есть unit rabbit, он утратил свою полезность, и мы хотим жестоко удалить его с помощью функции call RemoveUnit(rabbit). Кролик послушно исчезнет с нашего экрана. Однако исчезнет ли он из памяти? Сделаем так, пусть в бесконечном цикле будет вызываться некая функция. Суть функции - создать новую переменную, создать нового кролика и сразу удалить, переменную конечно не обнулим. Цикл у нас без пауз, работает очень быстро, через несколько минут наблюдаем приличные лаги. А ведь мы удаляли всех кроликов! И экран чистый, никого не видно. Добавляем обнуление после функции и внезапно всё работает безотказно! Вывод? Функции удаления объектов удалят его и без обнуления переменной, если ссылка уже отсутствует


Статья "Оптимизация" изменена мною, главный автор - Ajaccio


Тот кто владеет информацией, тот владеет миром.

Сообщение отредактировал ^GREAT^MAN^ - Воскресенье, 08.07.2012, 22:21
 
Дата: Воскресенье, 08.07.2012, 11:46 | Сообщение # 2
Генералиссимус
Модераторы
Сообщений: 12997
Награды: 22
Репутация: 141
^GREAT^MAN^, Ну вот, другое дело, разложил по полочкам)
Вот только:
Quote (^GREAT^MAN^)
MPI

Что это?
Quote (^GREAT^MAN^)
Переменные бывают утечные

Что значит утечные? Напиши подробнее... что там куда утекает)
Quote (^GREAT^MAN^)
которые наследуются от типа handle

Что за наследство такое?
Quote (^GREAT^MAN^)
их надо обнулять:

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


это Ксопик!


Сообщение отредактировал XOPYC - Воскресенье, 08.07.2012, 11:46
 
Дата: Воскресенье, 08.07.2012, 12:52 | Сообщение # 3
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
Quote (XOPYC)
Что значит утечные? Напиши подробнее... что там куда утекает)

Утечка - это такой гад, который висит у тебя в компе и засоряет копм. Очищается утечка тогда когда ты выйдешь с игры допустим
Quote (XOPYC)
Что это?

Что то болшее похоже на муи


Тот кто владеет информацией, тот владеет миром.
 
Дата: Воскресенье, 08.07.2012, 13:41 | Сообщение # 4
Генералиссимус
Модераторы
Сообщений: 12997
Награды: 22
Репутация: 141
Ты развёрнуто отвечать можешь? Я тебя прошу описать это не для себя, а для человека, который это первый раз читает...
Напиши типа утечка это переменные, которые более не используются, но занимают место в памяти, а обнуляем мы их как раз для того, что бы они это место не занимали. Всё просто и понятно. Не используй названия, которые понимают только те, кто уже хоть как то разобрался в джасе, т.к. новичок их не поймёт.


это Ксопик!
 
Дата: Воскресенье, 08.07.2012, 22:22 | Сообщение # 5
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
XOPYC, НУ вот добавил дальше)) Читай)

Тот кто владеет информацией, тот владеет миром.
 
Дата: Воскресенье, 08.07.2012, 22:30 | Сообщение # 6
Генералиссимус
Модераторы
Сообщений: 12997
Награды: 22
Репутация: 141
Тогда вопрос такой, каким образом появляется эта утечка? Ну я понимаю если переменная-массив, т.е. мы закинули в неё одного кролика, кролика удалили, а в переменной он остался, но потом создали нового кролика, который записался вторым в нашу переменную-массив, тогда без вопросов, скоро эта переменная может вырасти до нереальных размеров. Но а что если переменная у нас обычная?? По идеи она просто должна перезаписываться, а следовательно утечки быть не должно или я что-то не понимаю?

это Ксопик!
 
Дата: Воскресенье, 08.07.2012, 23:48 | Сообщение # 7
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
XOPYC, ну почти так, но близзарды немного тупнули. Дело в том, что Глобальная переменная(находится в Редакторе переменных), не создается 3 или 100 раз как локалка, по этому:
У нас есть глобальная переменная типа "боевая еденица".
Создаем юнита и прикрепляем к переменной, то что была создана "Последняя боевая еденица". И тут проблема. Если же ты не успеешь все вовремя удалить и обнулить, то тот старый юнит выйдет из переменной, а новый запишется в переменную. Это и есть утечка, так как старый юнит не был не удален и не был обнулен. А с локалками немного проще. Можно создать кучу таких переменных с одинаковым названием и каждый вовремя удалиться если есть в конце действия обнуления и удаления, а вобще... Говорят то что они после всех действий сами обнуляются, но стоит перестраховаться и сделать все вручную, хотя я написал 1 статье, что integer, real, boolean обнуляется автоматически при завершении действия. Так то


Тот кто владеет информацией, тот владеет миром.
 
Дата: Воскресенье, 08.07.2012, 23:49 | Сообщение # 8
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
XOPYC, А что с ним??

Тот кто владеет информацией, тот владеет миром.
 
Дата: Воскресенье, 08.07.2012, 23:51 | Сообщение # 9
Генералиссимус
Модераторы
Сообщений: 12997
Награды: 22
Репутация: 141
Ну в целом я всегда пользовался локальными, а на карте порой одна такая переменная задействовалась не одну тысячу раз в достаточно короткий промежуток времени и лагов даже в эти моменты не наблюдалось, потому я всегда очень скептически относился к этим утечкам, вот и насилую тебе мозг))
Quote (^GREAT^MAN^)
XOPYC, А что с ним??

Да он чёт флудить вздумал))) Миха Миха, спалился)))


это Ксопик!


Сообщение отредактировал XOPYC - Воскресенье, 08.07.2012, 23:52
 
Дата: Воскресенье, 08.07.2012, 23:52 | Сообщение # 10
Генералиссимус
Проверенные
Сообщений: 2259
Награды: 9
Репутация: 70
XOPYC, Это еще цветочки. Я когда своему учителю насиловал мозг... =/

а в каком месте он нагадил? ))


Тот кто владеет информацией, тот владеет миром.

Сообщение отредактировал ^GREAT^MAN^ - Воскресенье, 08.07.2012, 23:53
 
  • Страница 1 из 4
  • 1
  • 2
  • 3
  • 4
  • »
Поиск: