boolexpr в событиях
Недавно узнал, что boolexpr очень быстрые и решил немного оптимизировать триггеры, что часто срабатывают. Но у меня появилась пара вопросов.
  1. Выгодно ли делать проверки if-ами в boolexpr, а в зависимости от результата и сами действия?
  1. Пусть есть функция foo и триггер Death с событием TriggerRegisterFilterUnitEvent(Death, SomeUnit, EVENT_UNIT_DEATH, function SomeFilter).
function foo takes something returns something
    ...
    call KillUnit(SomeUnit)
    ...
endfunction
После call KillUnit(SomeUnit) сработает триггер Death. boolexpr SomeFilter унаследует поток foo или создаст свой?
  1. Зачем нужны следующие нативки и в чём их разница, если как boolexpr можно передавать функцию без аргументов, но с любым возвращающим типом?
native DestroyBoolExpr takes boolexpr e returns nothing
native Filter takes code func returns filterfunc
native DestroyFilter takes filterfunc f returns nothing
native Condition takes code func returns conditionfunc
native DestroyCondition takes conditionfunc c returns nothing
UPD (23.09.2018 15:30): Я использую Condition для конвертации в boolexpr, только когда code является переменной, а не явной ссылкой на функцию, потому что компилятор выдаёт следующую ошибку.
Во всех остальных случаях можно обходится без Condition и Filter, компилируется и работает хорошо.

Лучший ответ:
Нет, проверки в болекспрах ифами не делают, а делают And или or ну и Not если необходимо. У болекспра событий свой поток, туда можно передавать аргументы только глобалками, кроме GetFilterUnit() там ниче не робит, это относится только к болекспрам у событий, у кондишенов триггеров и груп все будет работать. Так же советую завести глобалку
globals
 unit bj_lastFilterUnit = null
endglobals

function Filter takes nothing reutrns boolean
set bj_lastFilterUnit  = GetFilterUnit()
return IsUnitType( bj_lastFilterUnit, UNIT_TYPE_HERO ) and ....
endfunction
Насчет нативок
  1. удаление болекспра, не требуется т.к они кешируются и не плодятся, частоиспользуемые можно для удобсва заносить в глобалки, просто и удобно.
  2. Есть два типа болекспр, Filter и Condition, работают абсолютно одинакового, некто не заметил разницы.



Просмотров: 530

» Лучшие комментарии


quq_CCCP #1 - 1 год назад 2

Нет, проверки в болекспрах ифами не делают, а делают And или or ну и Not если необходимо. У болекспра событий свой поток, туда можно передавать аргументы только глобалками, кроме GetFilterUnit() там ниче не робит, это относится только к болекспрам у событий, у кондишенов триггеров и груп все будет работать. Так же советую завести глобалку
globals
 unit bj_lastFilterUnit = null
endglobals

function Filter takes nothing reutrns boolean
set bj_lastFilterUnit  = GetFilterUnit()
return IsUnitType( bj_lastFilterUnit, UNIT_TYPE_HERO ) and ....
endfunction
Насчет нативок
  1. удаление болекспра, не требуется т.к они кешируются и не плодятся, частоиспользуемые можно для удобсва заносить в глобалки, просто и удобно.
  2. Есть два типа болекспр, Filter и Condition, работают абсолютно одинакового, некто не заметил разницы.
Drynwhyl #2 - 1 год назад 0
quq_CCCP, функции And, Or, Not таки плодят булэкспры, хоть и используются не часто.
quq_CCCP #3 - 1 год назад (отредактировано ) 5
Еще есть фишка которую юзал фрог, точнее его умный кодер как оказалось. суть проста.
Есть некий триггер:
local trigger trig = CreateTrigger()
call TriggerAddCondition( trig, Condition( function SomFunc ))
call TriggerregisterDeatEvent( trig , u)
call TriggerRegisterTimerEvent( trig, 8, false )
И у него есть только условие и 2 события, прикол в том что это триггер для абилк, пусть урны ( дебафф на 8 сек периодического урона, рассеивается при смерти) и создается ккаждый раз, и удаляется, но вот если бы мы юзали ашкшины триггера нам бы пришлось их удалять, а кондишены зависают в болекспре и не утекают, т.е всякий раз когда мы будем вешать наш болекспр новому триггеру, к триггеру будет прикручиватся уже существующий болекспр, а не создаватся новый. Способ для ленивых чтобы не удалять лишние обьекты.
Drynwhyl, a не про функции а операторы сравнения.
Так же как я уже писал некоторые события требуют болекспры, т.е позволяют отсеивать обьекты, на которые событие срабатывать не должно, это довольно удобно.
К примеру у вас один триггер на геройские абилки, он следит за тем что кто кастанул у него куча проверок и так далее а срабатывает он на всю шелупонь вроде крипов и даммиков которые нам не интересны, отсеиваем их в болекспре и ура.
Так же помните проверки на уровень абилки довольно медленные, лучше их не юзать там где код "крутится" постоянно, старайтесь обходить это проверками на GetUnitTypeId() или пытатся вручать абилку, если у юнита уже есть абилка с таким ид, функция UnitAddAbility вернет false и не добавит абилку, а если нету то вручит и вернет true это не особо то удобно и мало где применимо но может быть полезно если вы уж сильно увлекаетесь оптимизацией...
PT153 #4 - 1 год назад (отредактировано ) 0
Нет, проверки в болекспрах ифами не делают, а делают And или or ну и Not если необходимо.
Я имел в виду вот что.
function Trig_DeathTrigger_Filter takes nothing returns nothing
    local unit u = GetFilterUnit()
    call DisplayTextToPlayer(Player(0), 0., 0., GetUnitName(u))
    if not IsUnitRace(u, RACE_HUMAN) then
        call CreateUnit(Player(0), 'hfoo', GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
    endif
    set u = null
endfunction

function InitTrig_DeathTrigger takes nothing returns nothing
    set gg_trg_DeathTrigger = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEvent(gg_trg_DeathTrigger, Player(0), EVENT_PLAYER_UNIT_DEATH, function Trig_DeathTrigger_Filter)
endfunction
Стоит ли делать что-то в этом духе?
прикреплены файлы
quq_CCCP #5 - 1 год назад 3
так извращатся не стоит.
nvc123 #6 - 1 год назад (отредактировано ) 4
quq_CCCP, PT153, фильтры имеют намного меньший лимит потока чем триггерэкшены
я когда только начинал юзать джасс не раз сталкивался с тем что условие тупо не выполнялось до конца
поэтому все ресурсоёмкие проверки (например содержащие енумы или большие циклы) приходится выносить в триггерэкшион
выполнять действия в булекспере полный бред
т.е. их стоит использовать только для небольших проверок
DracoL1ch #7 - 1 год назад 0
что есть фильтр? Filter() и Condition() одно и то же, и в той же доте всё работает на Condition(), что равноценно фильтру и оттого точно так же надежно. Лимит 300к на все операции внутри нового треда, если тред не создается, используется счетчик старого треда. Узнать, создавался тред или нет, можно при помощи десинка, вынеся неизвестную часть в локальный код. Если десинкнуло - там был новый тред.
PT153 #8 - 1 год назад (отредактировано ) 0
Узнать, создавался тред или нет, можно при помощи десинка, вынеся неизвестную часть в локальный код. Если десинкнуло - там был новый тред.
Вот тут не понял. Не мог бы расписать?