Сейчас 06:13:23 Воскресенье, 14 августа, 2022 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » Раздел картостроителя » [СТАТЬЯ]Теория скриптописания на языке Jass. (Большущая!)
[СТАТЬЯ]Теория скриптописания на языке Jass.
AjaccioДата: Пятница, 04 Февраля 2011, 16:59:04 | Сообщение # 1
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Теория скриптописания на языке Jass.


Оглавление:


  • [goto=intro]Вступление[/goto]
  • [goto=types]Типы переменных[/goto]
  • [goto=arrays]Массивы[/goto]
  • [goto=optimization]Оптимизация[/goto]
  • [goto=misc]Повседневные хитрости[/goto]


[#=intro]
Вступление.


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

[#=types]
Типы переменных.


Начнём с того, что всего зарезервировано 6 типов переменных, остальные же являются потомками или иначе дочерними типами. Любой родительский тип может «содержать» в себе любого из своих потомков, хотя для хранения данных рекомендуется все же использовать специально выделенный под это дело тип. Непонятно? Тогда давайте рассмотрим каждый из этих 6 видов переменных подробней, возможно ситуация прояснится.

integer, real, boolean, string
– самые примитивные из типов, отвечают за обозначение целочисленных, дробных, логических и строковых переменных соответственно. Совсем не имеют потомков, однако это не очень огорчает. Примеры: integer x = 1; real y = 1.0; Подробно рассматривать тип real я не буду, он используется только для расчётов. А вот integer для нас более интересен, ведь многие игровые объекты являются целочисленным типом, хотя они представлены в несколько иной форме. Форме? Да, числа 'A000', 0x31 или 34 все являются целыми числами, просто они записаны в 256-ой, 16-ой и 10-ой системе счисления соответственно. Поэтому мы можем использовать с любой из этих форм любые операции, будь то сложение, вычитание или запись в переменную. Всё вроде? Ах да, integer может принимать значения от -2147483648 до 2147483647, что соответствует 4 байтам.



boolean z = true; string c = “word”; Ничего необычного, boolean - переменная логического типа, читайте, принимает значение "да" и "нет" (true или false). Несложно догадаться, что string - строка, любой набор символов в скобках "...". Важно отметить, что "" != null, то есть пустая строка тоже строка, а не пустое значение.



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

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

[code=jass]local widget u = CreateUnit(...)[/code]
или вообще

[code=jass]local handle u = CreateUnit(...)[/code]

При этом ни одна из этих записей не вызовет ошибки и корректно сработает. Почему? Просто handle считается родителем widget, а widget родителем unit.

Остальные типы работают по такой же системе. Их смысл понятен из их названия, исключая разве что boolexpr. Что это? Просто ссылка/указатель на другую функцию, которую вы собираетесь использовать как фильтр (если конечно собираетесь). Допустимо писать так: local boolexpr b = Condition(function MyFunc), где MyFunc обязательно возвращает boolean. Например:

[code=jass]local boolexpr f = Condition(function MyFunc)
call GroupEnumUnitsInRange(group, x, y, r, f)[/code]

Здесь мы просто собираем юнитов в группу, но согласно условию MyFunc. Иначе говоря, Warcraft перебирает всех юнитов на расстоянии r от точки (x; y), для каждого запускает функцию f и, если она вернёт true, то группа увеличивается на одного юнита. Также можно писать так:

[code=jass]call GroupEnumUnitsInRange(group, x, y, r, Condition(function MyFunc))[/code]

Правда потом не получится удалить это условие, что не есть хорошо.

Многие из этих типов нуждаются в удалении и обнулении, об этом будет сказано дальше.
Ах да, в 1.24 ввели новый тип agent который находится где-то посередине между handle и всем остальным.



code - ссылка в чистом виде, самый необычный тип и этим все сказано. Очевидно, служит для хранения некоторого кода, абсолютно любой функции, например local code c = function MyFunc. Разумеется MyFunc должна существовать и быть выше точки вызова, иначе при сохранении вылетит ошибка. Не правда ли тип code очень похож на boolexpr? Оба хранят в себе функции, правда boolexpr требует, чтобы хранимая функция возвращала boolean. Тем не менее он (code) является старшим/базовым типом и с типом handle (=> и с boolexpr) не связан. Добавьте к этому невозможность создание массива code, компилятор просто не даст это сделать. Возможно code был выделен из handle хитрыми разработчиками, чтобы мы не могли так или иначе использовать хэш и организовать массив...



Вы не можете удалять code, это даже несколько абсурдно, удалить некоторую функцию/код по ходу игры. Однако её можно обнулить... хотя после нескольких тестов я начинаю сомневаться в необходимости таких действий. Похоже code это просто замаскированное целое число, отвечающее за номер такой-то функции.

[#=arrays]
Массивы.


Строго говоря, массив - набор однотипных переменных, расположенных в памяти непосредственно друг за другом, доступ к которым осуществляется по индексу. Иначе это можно представить как некоторое количество банок с неким содержимым, причём все банки пронумерованы. Нумерация массива всегда начинается с 0, максимальный элемент - 8191. Получается мы имеет 8192 банки в которые можно положить любой из доступный Warcraft 3 типов, кроме code.



Напрямую можно задать только одномерный массив, остальное вам придется делать самим через параллельные массивы и некоторую integer переменную. Выделение памяти идёт динамично, однако сразу по 1000 (примерно же) элементов.

[#=optimization]
Оптимизация.


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

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

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

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

[code=jass]local unit rabbit
loop
exitwhen (i > 100000)
set rabbit = CreateUnit(...)
call RemoveUnit(rabbit)
set rabbit = null // <-------------------------------  А вот это можно не писать! Ссылка всё-равно исчезнет.
set i = i + 1
endloop
set rabbit = null // <-------------------------------  Но тогда напишите здесь, последняя переменная останется.
[/code]

Я думаю (надеюсь) никто, никогда и не писал эту строку... но здесь я даю только теорию, показываю почему это так.



Особую головную боль при оптимизации доставляют динамические триггеры... Конечно, существует не очень (совсем не) сложная функция DestroyTrigger(t), однако на практике оказывается мало удалить сам триггер, как и кролик он просто исчезнет (перестанет работать), однако даже после обнуления переменных никуда не денется. В чём причина? В начинке. Точнее в условиях и действиях, ведь они являются объектами и при этом ссылками на триггер. Хотите удалить триггер? Удалите все его действия и условия с помощью функций TriggerClearAction(...) и TriggerClearCondition(...).



Вообще старайтесь избегать динамических триггеров, если их и создавать, то пусть навсегда.
Удаление других объектов не должно быть затруднительным и специально я останавливаться на них не буду.



[#=misc]
Повседневные хитрости.


1) Функция call GroupEnumUnitsInRange(...) и ей подобные сами очищают группу перед началом своей работы. Поэтому можно не использовать call GroupClear(...), если вы используете одну глобальную группу, а не плодите локальные.

2) Вы знаете, как расположены юниты в группе? Оказывается, это определятся их игровым номером, иначе говоря, первым становится тот юнит, функция GetHandleId(...) для которого вернёт меньшее значение и так далее по возрастанию. Обычно на практике это означает, что FirstOfGroup(...) вернет самого "старшего" юнита.

3) Невозможно мгновенно повернуть юнита... максимальная скорость обеспечивается функцией call SetUnitFacingTimed() с параметром времени на 0.01. Это соответствует скорости поворота 3.0 в настройках этого юнита.

4) Игра не будет инициализировать ваши переменные за вас, старайтесь избегать вот таких конструкций:

[code=jass]local integer i
set i = i + 1[/code]

Получается, что вы прибавляете "пустоту" к 1... как результат, данный поток немедленно завершится, ни одно действие после set i = i + 1 не выполнится никогда, по крайней мере, пока i остается неопределённым. Однако ошибка не вылезет!

5) Использование return в любой форме немедленно заканчивает выполнения функции. Даже если ваша функция ничего не возвращает, вы можете так и написать - return, это всё равно завершит работу данного участка кода.

6) Если вам нужно создать эффект, а удалять его лень, можете использовать запись вида:

[code=jass]call DestroyEffect(AddSpecialEffectTarget(...))[/code]

Однако в этом случае проиграется только анимации birth и death, вам придется сохранять эффект и удалять потом, как положено, если вы хотите насладиться анимацией stand.

7) В чём отличие SetUnitX/SetUnitY и SetUnitPosition(...)? На самом деле SetUnitPosition(...) дополнительно проверяет точку на проходимость, как результат работает немного медленней, что сильно заметно при обработке большого числа юнитов. Также использование SetUnitX/SetUnitY может привести к вылету без отчета, если перемещаемый юнит выйдет за границы карты.

8) Записи if (IsUnitEnemy(...) == true) then... и if IsUnitEnemy(...) then... имеют одинаковый смысл, однако хорошим тоном считается использовать второй вариант. Будьте внимательны при использовании IsUnitType(...)!

9) Что быстрее глобалки или хэш? Теоретически глобалки, но только по причине необходимости вызова, зачастую даже двух, функции для нормальной работы с хэш-таблицей: call SaveInteger(HASH, GetHandleId(...), 0, 5), в то время как для операций над глобалками вызывать никаких функций не надо. Вызов функции требует время большее, чем загрузка переменной из памяти... но на практике заметить (и похоже даже измерить средствами Warcraft) разницу во времени нельзя. Поэтому выбор между хэшом и глобальными переменными - дело вкуса.



10) При поиске ошибок в коде полезно использовать функцию BJDebugMsg("..."), а также неплохой идеей будет скачать счетчик утечек и вставить в свою карту на время теста. Ведь "утечки" могут сказываться только через полчаса и даже более часа игры.

Вроде всё, больше сейчас ничего не вспомню, да и лимит подходит к концу. :D


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

DreiiДата: Пятница, 04 Февраля 2011, 17:09:00 | Сообщение # 2
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
Ajaccio, Норм статья,Узнал новове только про агента)

 

romaN-1998Дата: Пятница, 04 Февраля 2011, 20:43:32 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 1368
Награды: 0
Репутация: 10
Блокировки:
Хорошая статья!
 

PrivatikДата: Пятница, 04 Февраля 2011, 21:21:05 | Сообщение # 4
5 уровень
Группа: Пользователи
Сообщений: 106
Награды: 0
Репутация: -9
Блокировки:
Хорошая статья,очень хорошо что писал сам. Теперь я нубо жассер)
 

AjaccioДата: Пятница, 04 Февраля 2011, 23:58:08 | Сообщение # 5
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Всем спасибо. Надеюсь понятно изложил, а то изначально было подробнее, но вмешался лимит сообщения. ^_^
Впрочем статья в основном интересна для тру-кодеров, желающих докопаться до сути происходящего в Warcraft.


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

QuasarДата: Суббота, 05 Февраля 2011, 01:23:40 | Сообщение # 6
7 уровень
Группа: Проверенные
Сообщений: 334
Награды: 0
Репутация: 41
Блокировки:
Ajaccio, можеш обьяснить как автокаст сделать????

Спелмейкер ищет работу)
 

FkoFFДата: Суббота, 05 Февраля 2011, 02:57:13 | Сообщение # 7
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Ajaccio, тру кодеры итак все это знают; на счет хэша - работа с ним быстрее на порядок чем работа с глобалками, ну и, офк, удобнее. )

 

DanteLoLДата: Суббота, 05 Февраля 2011, 04:45:53 | Сообщение # 8
1 уровень
Группа: Пользователи
Сообщений: 6
Награды: 0
Репутация: 0
Блокировки:
Хочу научиться с нуля писать скрипты на Джасе ө штудирую статейки с тупым выражением лица - потому что нифига не понимаю(( скиньп лиз FAQ где будет описан простой пример, в котром будет описанно как с нуля делать простенький тригер на джасе (юнит умер - тип юнита горный король - создасть спецэфект - тип этого) я слышал там какойто особый едитор нужен для скриптов? объясните плиз! зарание признателен)
 

DreiiДата: Суббота, 05 Февраля 2011, 11:30:36 | Сообщение # 9
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
DanteLoL, Сначало обучись триггерам

 

AjaccioДата: Суббота, 05 Февраля 2011, 13:08:01 | Сообщение # 10
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Цитата (FkoFF)
работа с ним быстрее на порядок чем работа с глобалками


Пруфлинк? В Warcraft нельзя организовать длительный поток, плодить потоки тоже нельзя. По крайней мере "в лоб". Значит не проверить.
У вас есть дизассемблированный код функций работы с хэшом? Скорость любого хэша, в основном, зависит от выбранного алгоритма.
Сборка функции (любой) тоже занимает некоторое время, но оно -> 0.0. Время обращения к глобальной переменной -> 0.0.
Как сравнить тут что-то? На счет удобнее, пожалуй, согласен, но я использую структуры, а хэш подрабатывает базой данных.

Цитата (Quasar)
Ajaccio, можеш обьяснить как автокаст сделать????


Идеальный вариант - глобальная система отлова урона.
Способность изготавливаем на основе ледяных стрел (любые характеристики, главное - баф), далее создаем событие "юнит получил урон".
По событию, если урон > 0.0 и юнит имеет баф ледяных стрел, то удаляем его (баф, если нужно) и делаем свои дела.
Возможно стоит создать тему в "вопросах"?


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

DanteLoLДата: Суббота, 05 Февраля 2011, 13:39:53 | Сообщение # 11
1 уровень
Группа: Пользователи
Сообщений: 6
Награды: 0
Репутация: 0
Блокировки:
Quote (Dreii)
Сначало обучись триггерам
брат я картостроитель с әх годовым стажем)) gui знаю на раз-два) но вот все пытался обойти Джас - раньше получалось - ведь требования к картам были не такие ка сейчас - но теперь придется изучить ведь игроки требуют такого что бы всех вставило по полной а Gui уже исчерпал свой ресурс да и понял уже что в джасе функций гоооооооооооооооооооораздо больше)) так что ГОТОВ К ОБУЧЕНИЮ И ПОСТОРАЮСЬ НЕ ТУПИТЬ! кинье чтонибуть для начало добрые люди!)
 

DreiiДата: Суббота, 05 Февраля 2011, 14:41:09 | Сообщение # 12
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
DanteLoL, пиши в ЛС сделаю мега нубом в JAssе как я будешь нубом)

 

ZakenДата: Воскресенье, 27 Февраля 2011, 07:01:32 | Сообщение # 13
3 уровень
Группа: Пользователи
Сообщений: 62
Награды: 0
Репутация: 22
Блокировки:
эх. меня юы кто мега нубом сделал бы :D

http://avsn.3dn.ru - мой сайт
Вечно докапываясь до мозилы, пытаясь найти во вкладке инструменты игровые константы(говорит уже о фанатизме или пора завязывать)
Ищу учителя по Jass.
 

FaionДата: Воскресенье, 27 Февраля 2011, 12:15:33 | Сообщение # 14
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Цитата (Ajaccio)
Также появилась интересная, но мало популярная функция SaveAgentHandle(...). Она позволяет сохранять любой тип, дочерний от handle без указания самого типа.

Не рекомендуется использовать, по то причине что читабельность кода падает.
Цитата (Ajaccio)
code

Вот если бы code мог быть массивом...
Цитата (Ajaccio)
Как только lol расслоятся его кости (вроде 88 секунд в константах), он покинет мир игры навсегда.

Время настраивается, рекомендую ставить значение ~25.
Цитата (Ajaccio)
Невозможно мгновенно повернуть юнита... максимальная скорость обеспечивается функцией call SetUnitFacingTimed() с параметром времени на 0.01. Это соответствует скорости поворота 3.0 в настройках этого юнита.

В РО можно поставить любое значение.
Цитата (Ajaccio)
Получается, что вы прибавляете "пустоту" к 1... как результат, данный поток немедленно завершится, ни одно действие после set i = i + 1 не выполнится никогда, по крайней мере, пока i остается неопределённым. Однако ошибка не вылезет!

Гуишникам боятся нечего, гуи производит инициализацию самостоятельно.
Цитата (Ajaccio)
Если вам нужно создать эффект, а удалять его лень, можете использовать запись вида:

Code
call DestroyEffect(AddSpecialEffectTarget(...))

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

Цитата (Ajaccio)
В чём отличие SetUnitX/SetUnitY и SetUnitPosition(...)? На самом деле SetUnitPosition(...) дополнительно проверяет точку на проходимость, как результат работает немного медленней, что сильно заметно при обработке большого числа юнитов. Также использование SetUnitX/SetUnitY может привести к вылету без отчета, если перемещаемый юнит выйдет за границы карты.


Что бы юнит не улетел за границы карты(это кстати вызовет крит эррор), используем эту конструкцию:


Цитата (Ajaccio)
Что быстрее глобалки или хэш?

Большая таблица ХТ серьезно снижает скорость работы. Настоятельно рекомендую в целях оптимизации, а так же защиты нужных данных от удаления, использовать сразу много ХТ. Спрашивается зачем?
Во первых при поиске данных в хт, провека идет всех ячеек, т.е. чем больше табл. тем больше проверок, это не круто. Во вторых у вас может быть тонна систем которые вешают данные на юнит. И очищая таблицу, которая привязана к юниту, вы можете удалить нужные вам данные. В некоторых случаях это может привести даже к фаталам. Глобалки быстрее массива, так же отмечу что локалки не всегда быстрее глобалок, в прочем это больше зависит от платформы, как дело обстоит на вар, не известно. Не стоит ими злоупотреблять.
Цитата (Ajaccio)
Использование структур и, например, единого таймера сводит необходимость хэша на 0.0, хотя вы и можете сохранять в хэш структуру, но зачастую это превращается в лишнюю трату времени и ресурсов. Впрочем, сохранять значения в хэш можно и с помощью строки, что открывает довольно широкие возможности для использования его в роли базы данных.

Можно просто написать 1 раз функцию, и наслаждатся, а так же аттачить структуры черех хт.


О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

lawsonДата: Воскресенье, 27 Февраля 2011, 13:14:01 | Сообщение # 15
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Киньте эту статью в статьи на главной странице!!!!!! Статья полезная

Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

SirNikolasДата: Воскресенье, 27 Февраля 2011, 15:19:37 | Сообщение # 16
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Цитата (Ajaccio)
Как только расслоятся его кости (вроде 88 секунд в константах), он покинет мир игры навсегда.
Цитата (Faion)
Время настраивается, рекомендую ставить значение ~25.


 

AjaccioДата: Воскресенье, 27 Февраля 2011, 16:58:35 | Сообщение # 17
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Faion, SirNikolas спасибо за ценные добавления, жалко не могу обновить статью. :)

XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

facerДата: Воскресенье, 27 Февраля 2011, 17:18:34 | Сообщение # 18
1 уровень
Группа: Пользователи
Сообщений: 19
Награды: 0
Репутация: 2
Блокировки:
Ajaccio, блиин прочитал , и захотел на жасе чтот зделать, научите плиииз!!!

Уйди старушка, | Администрацыя что за беспредел??
Я в печали , |
У меня акаунт сломали((( |
______________________________
Киньте плюсик плиз))
 

lawsonДата: Воскресенье, 27 Февраля 2011, 23:06:16 | Сообщение # 19
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (facer)
facer

Статьи


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

FaionДата: Понедельник, 28 Февраля 2011, 15:42:02 | Сообщение # 20
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Ajaccio, Ну внеси поправки, потом мне текст скинь в личку, я модеров пну что б изменили=) Или можешь попробовать сразу Дракона попросить в личку, он няшка, поправит ;)

О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

ПозитронычДата: Понедельник, 30 Января 2012, 21:26:11 | Сообщение # 21
2 уровень
Группа: Пользователи
Сообщений: 32
Награды: 0
Репутация: 0
Блокировки:
У меня вот какой вопрос. В самом конце статьи написано про счётчик утечек, не могли бы вы сказать, где его можно скачать?
 

SirNikolasДата: Вторник, 31 Января 2012, 11:41:42 | Сообщение # 22
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
[code=jass]function LeakChecker takes nothing returns nothing
local timer t = CreateTimer()
call DisplayTimedTextToPlayer(GetLocalPlayer(), .0, .0, 60., "Leak Checker: " + I2S(GetHandleId(t)))
call DestroyTimer(t)
set t = null
endfunction[/code]


 

Ty3uKДата: Вторник, 31 Января 2012, 12:09:01 | Сообщение # 23
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Ник, объясни плз, как этот таймер ловит утечки

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

SirNikolasДата: Вторник, 31 Января 2012, 12:26:43 | Сообщение # 24
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Все очень просто. Когда создаются объекты, им даются ID handle'ов по порядку. Т. е. если между вызовами функции было много утечек, второе число будет больше первого. Правда, есть один существенный недостаток: если удалить какой-нибудь "старый" объект, его ID будет считаться свободным, и ID таймера счетчика утечек будет маленьким. Так что функцию надо вызывать чаще, чем раз в минуту.

 

ПозитронычДата: Вторник, 31 Января 2012, 13:14:42 | Сообщение # 25
2 уровень
Группа: Пользователи
Сообщений: 32
Награды: 0
Репутация: 0
Блокировки:
То есть количество утечек определяется не самим отображаемым числом, а разностью между числами?

Добавлено (31 Январь 2012, 13:14:42)
---------------------------------------------
И ещё: какая зависимость между этой разностью и количеством утечек? Т.е.,к примеру, если было число 1049068, потом несколько раз выполнилась некая функция ( скажем, 10 раз), и получилось 1050994, то эта функция утечная?

 

Форум о Warcraft 3 » Раздел для картостроителей » Раздел картостроителя » [СТАТЬЯ]Теория скриптописания на языке Jass. (Большущая!)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Copyright © 2006 - 2022 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz