Сейчас 17:12:41 Вторник, 26 ноября, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
[СТАТЬЯ] Отряд, ForGroup, GroupLoop
FkoFFДата: Вторник, 24 Мая 2011, 08:39:54 | Сообщение # 1
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Каждый человек использовавший триггеры в той или иной ситуации вынужден воспользоваться группами юнитов, что такое эти группы и с чем их едят я постараюсь изложить максимально доступно для мягкого нубъего мозга.

Итак, самое первое – свойства объекта.

Группа юнитов – объект достаточно легкий, однако обращение с ним стоит достаточно большого количества памяти. Состоит объект из массива чисел, являющихся ссылками на юнитов.



Опасные точки соприкосновения с группами это функции CreateGroup() и DestroyGroup()
В игре бывают моменты когда подобные действия вызывают некоторые повышенные затраты оперативной памяти, хотя я и не решаюсь сказать по чему это конкретно происходит.

Еще одна опасная точка соприкосновения это функции на GUI, требующие конкретную группую юнитов для работы, самая опасная из всех - For Group Matching, создает не только утекающую группу но и утекающий Boolexpr.



Работа с группой юнитов возможна двумя путями: классический(ForGroup) и GroupLoop.
Первый способ ForGroup берет группу и ссылку на функцию, заставляет для каждого юнита в группе исполнять действия в функции. Второй способ – GroupLoop выгодно отличается от первого тем, что не требует выноса за пределы функции, однако обладает рядом ограничений, и по этому в некотором роде ущербен.

Основной минус ForGroup и его переноса в функцию тот что функция не может содержать аргументов, а соответственно мы не можем передать, к примеру, юнита, который должен нанести урон всем в группе. Вторая проблема – нет функции которая бы вернула handle самой группы, для которой производятся действия, то есть нет фактического способа передачи данных в группу напрямую, исключение – глобальные переменные. Основной плюс – все действия происходят параллельно (а не последовательно, как в случае со вторым способом), а соответственно скорость работы данного способа несколько быстрее.

Основные минусы второго способа (GroupLoop) – вероятность того что выполнение цикла прервется из-за превышения максимального количества действий для одной функции. Второй минус – обязательное удаление юнита из группы для прогресса цикла (для перебора юнитов в существующей группе придется использовать еще одну группу). Однако все локальные переменные функции, в которой происходят действия – сохраняются и не требуют передачи.

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

Рассмотрим самый удобный вариант

[code=jass]
function grouploop takes real x, real y, real radius returns nothing
local group g=udg_Temp_Group
local unit forloop
//для работы требуется юнит, назовем его forloop
call GroupEnumUnitsInRange(g,x,y,radius,null)
//функция GroupEnumUnitsInRange последним аргументом требует Boolexpr, однако он,
//мало того что является объектом, так еще и требует отдельную функцию для работы

loop
set forloop=FirstOfGroup(g)
exitwhen forloop==null
if UrCondition1==true and UrCondition2==true then
...
endif
call GroupRemoveUnit(g,forloop)
endloop
//собственно это и есть метод работы с GroupLoop, выбирается юнит, первый из группы
//(g), если в группе нет юнитов, а соответственно forloop==null, цикл прекращается. Все
//требуемые условия вынесены в if\then\else конструкцию, которую, к слову,
//рекомендуется вынести в отдельную функцию, дабы не захламлять все функции с
//груплупом одними и теми же условиями.

set g=null
endfunction
[/code]

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

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

FkoFF, специально для Warcraft 3 Info.


 

lawsonДата: Вторник, 24 Мая 2011, 08:44:58 | Сообщение # 2
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
А что кто то не умеет пользоваться группами?
Допиши call DestroyGroup - а то не которые могут не принять это во внимание.


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

CHLSNДата: Вторник, 24 Мая 2011, 10:56:41 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
FkoFF, думаю идея с использованием глобальной группы оправдана, если команды выполняется последовательно, ведь это так?



Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

FkoFFДата: Вторник, 24 Мая 2011, 13:39:25 | Сообщение # 4
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Quote (CHLSN)
FkoFF, думаю идея с использованием глобальной группы оправдана, если команды выполняется последовательно, ведь это так?

условие только одно - группа после использования должна быть пуста, шансов на конфликт нет вообще.


 

CHLSNДата: Вторник, 24 Мая 2011, 14:03:51 | Сообщение # 5
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Quote (FkoFF)
udg_Temp_Group

Можно наверное и стандартную переменную использовать для полного счастия bj_groupLastCreatedDest ?




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

FkoFFДата: Вторник, 24 Мая 2011, 14:07:51 | Сообщение # 6
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Quote (CHLSN)
bj_groupLastCreatedGroup

Не, определенно глобалка надежнее, там 100% гарантия что переменная не будет переписана.

К слову - для некоторых целей все равно придется использовать "плавающие" группы, как например для снарядов типа волны силы, наносящих однократно х урона каждому юниту сквозь которого проходят )


 

CHLSNДата: Вторник, 24 Мая 2011, 14:19:22 | Сообщение # 7
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Quote (FkoFF)
Не, определенно глобалка надежнее, там 100% гарантия что переменная не будет переписана.

Ага, то есть не используя BJ-функций, Warcraft может там самостоятельно свои переменные писать?




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

FkoFFДата: Вторник, 24 Мая 2011, 14:20:52 | Сообщение # 8
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Quote (CHLSN)
Ага, то есть не используя BJ-функций, Warcraft может там самостоятельно свои переменные писать?

собственно константные переменные bj_LastCreatedObject и используются для передачи в триггеры последнего созданного юнита, на джасс они вообще не используются никогда, за исключением тех случаев когда пишется функция на создание какого-либо объекта для наработки (что бы нубы могли использовать не задумываясь))


 

CHLSNДата: Вторник, 24 Мая 2011, 14:31:15 | Сообщение # 9
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
А по поводу статьи - здорово))
+ что не надо создавать локальную группу, разрушать, обнулять. Экономично получается.




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

SirNikolasДата: Вторник, 24 Мая 2011, 15:22:44 | Сообщение # 10
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
А почему же не рассмотрен третий способ?
Code
globals
     constant group PickGroup = CreateGroup()
     boolexpr PickBool
endglobals

funciton Trig_Temp_Pick takes nothing returns boolean
     local unit u = GetFilterUnit()
     //...
     set u = null
     return false
endfunction

function Trig_Temp_Actions takes nothing returns nothing
     call GroupEnumUnitsInRect(PickGroup, bj_mapInitialPlayableArea, PickBool)
endfunction

function InitTrig_Temp takes nothing returns nothing
      set PickBool = Filter(function Trig_Temp_Pick)
endfunction


 

CHLSNДата: Вторник, 24 Мая 2011, 15:41:30 | Сообщение # 11
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Так, к слову, Condition() оставляет неудаленный boolexpr?



Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

lawsonДата: Вторник, 24 Мая 2011, 17:42:38 | Сообщение # 12
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (CHLSN)
Так, к слову, Condition() оставляет неудаленный boolexpr?

Да надо удалять потом boolexpr, если ты об этом.


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

CHLSNДата: Вторник, 24 Мая 2011, 17:48:33 | Сообщение # 13
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Тогда я думаю, что эта муть с boolexpr, которую SirNikolas предложил, не особо нужна, т.к. читабельнее размещать функции условий рядом там, где они используются и писать call GroupEnumUnitsIn<>(PickGroup, <>, Condition( function <> ) )



Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

SirNikolasДата: Вторник, 24 Мая 2011, 19:31:36 | Сообщение # 14
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (CHLSN)
call GroupEnumUnitsIn<>(PickGroup, <>, Condition( function <> ) )
Так писать нельзя именно потому, что будет утечка boolean expression. Можно, конечно, каждый раз создавать локальный буль и удалять его, но это будет хуже.




Сообщение отредактировал SirNikolas - Вторник, 24 Мая 2011, 19:33:59
 

CHLSNДата: Вторник, 24 Мая 2011, 19:39:14 | Сообщение # 15
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
SirNikolas, и куда она утекает?



Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

SirNikolasДата: Вторник, 24 Мая 2011, 19:48:12 | Сообщение # 16
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Condition( function <> ) возвращает conditionfunc (type conditionfunc extends boolexpr), который никуда не записывается и потому "утекает". Вот, запусти и посмотри, что будет:
Code
globals
      constant group GROUP = CreateGroup()
endglobals

function LeakChecker takes nothing returns nothing
      local timer t = CreateTimer()
      call BJDebugMsg(I2S(GetHandleId(t)))
      call DestroyTimer(t)
      set t = null
endfunction

function Trig_LeakTest_Conditions takes nothing returns boolean
      return true//Просто для примера
endfunction

function Trig_LeakTest_Actions takes nothing returns nothing
      call GroupEnumUnitsInRect(GROUP, bj_mapInitialPlayableArea, Condition(function Trig_LeakTest_Conditions) )
      call LeakChecker()
endfunction

function InitTrig_LeakTest takes nothing returns nothing
      call TimerStart(CreateTimer(), .01, true, funciton Trig_LeakTest_Actions)
endfunction




Сообщение отредактировал SirNikolas - Вторник, 24 Мая 2011, 20:02:39
 

CHLSNДата: Вторник, 24 Мая 2011, 19:52:56 | Сообщение # 17
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Quote (SirNikolas)
GroupEnumUnitsInRect(GROUP, bj_mapInitialPlayableArea, Condition(function Trig_LeakTest_Conditions) )

А здесь тогда куда он записывается?




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?
 

SirNikolasДата: Вторник, 24 Мая 2011, 19:59:22 | Сообщение # 18
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
В том и дело, что никуда. И если запустить, то ты увидишь на экране вот это:


 

CHLSNДата: Вторник, 24 Мая 2011, 20:02:24 | Сообщение # 19
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
Quote (SirNikolas)
В том и дело, что никуда.
Сцука, американцы криворукие.

Что ж, в любом случае мне еще раз нужно будет пройтись по спеллам, дабы недочеты исправить, заодно это все поправлю, но, ОМГ, это все равно не подчиняется моей логике
Condition() => boolexpr ->(передача) GroupEnum...
А на деле вот так:
Condition() => boolexpr ->(копирование Оо) GroupEnum...




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?


Сообщение отредактировал CHLSN - Вторник, 24 Мая 2011, 20:05:35
 

FkoFFДата: Вторник, 24 Мая 2011, 23:48:24 | Сообщение # 20
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Quote (SirNikolas)
А почему же не рассмотрен третий способ?

Quote (CHLSN)
Что ж, в любом случае мне еще раз нужно будет пройтись по спеллам, дабы недочеты исправить, заодно это все поправлю, но, ОМГ, это все равно не подчиняется моей логике

создавать бульэкспр - безумие, когда можно просто отфильтровать юнитов внутри цикла. Между прочим сам буль весит больше чем группа (объект) и засоряет память достаточно сильно. По этому втопку булэкспры, размещайте простые условия через if\then.


 

CHLSNДата: Среда, 25 Мая 2011, 00:25:12 | Сообщение # 21
10 уровень
Группа: Проверенные
Сообщений: 1627
Награды: 0
Репутация: 132
Блокировки:
FkoFF, а-ля, теоретически, если юнит проходит проверку один раз, и один раз используется, то без разницы где это делать, в цикле или выборе...

FkoFF, само собой (см. ниже)))




Я в контакте и на warcraft3ft.info.
Кто может сказать, почему **** дизайнер писал вместо "pt" "px" в CSS, благодаря чему нужно смотреть форум через лупу с Ctrl++?


Сообщение отредактировал CHLSN - Среда, 25 Мая 2011, 13:25:05
 

FkoFFДата: Среда, 25 Мая 2011, 01:02:07 | Сообщение # 22
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
CHLSN, удобнее делать это в цикле потому как не надо гемороится с переносом данных в другую функцию через глобалки..

 

  • Страница 1 из 1
  • 1
Поиск:

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