XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Variecs

offline
Опыт: 2,508
Активность:
Триггер запускается без проверки условия
После того, как условие единожды возвращает положительный результат, проверка этого условия вообще прекращается и триггер запускается без неё. Не подскажете, в чём проблема? Текст триггера:

Код:
function DeathSteel takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local boolean b = ( GetUnitTypeId( u ) == 'h011' )
    set u = null
    return b
endfunction  

function SparePart takes nothing returns boolean
    local unit u = GetFilterUnit()
    local boolean b = ( GetUnitTypeId( u ) == 'h012' )
    set u = null
    return b
endfunction

function Repair_Heal takes nothing returns nothing
    local unit u = GetEnteringUnit()
    local group g = CreateGroup()
    local boolexpr b = Condition( function SparePart )
    local unit sp = null
    call GroupEnumUnitsInRange( g, GetUnitX( u ),  GetUnitY( u ), 100, b )
    set sp = GroupPickRandomUnit( g )
    call UnitDamageTarget( sp, u, -400, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
    call RemoveUnit( sp )
    call DestroyGroup( g )
    call DestroyBoolExpr( b )
    set b = null
    set g = null
    set u = null
    set sp = null
endfunction

function Emergency_Repair_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local player p = Player(4)
    local unit sp = CreateUnit( p, 'h012', GetUnitX( u ), GetUnitY( u ), bj_UNIT_FACING )
    local trigger t = CreateTrigger()
    local boolexpr b = Condition( function DeathSteel )
    call SetUnitInvulnerable( sp, true )
    call SetUnitPathing( sp, false )
    call TriggerRegisterUnitInRange( t, sp, 100, null )
    call TriggerAddCondition( t, b )
    call TriggerAddAction( t, function Repair_Heal )
    call DestroyBoolExpr( b )
    set b = null
    set u = null
    set p = null
    set sp = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Emergency_Repair takes nothing returns nothing
    set gg_trg_Emergency_Repair = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Emergency_Repair, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Emergency_Repair, Condition( function DeathSteel ) )
    call TriggerAddAction( gg_trg_Emergency_Repair, function Emergency_Repair_Actions )
endfunction
Старый 09.03.2013, 17:48
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
function DeathSteel takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local boolean b = ( GetUnitTypeId( u ) == 'h011' )
    set u = null
    return b
endfunction 
мазохист
рекомендую
function DeathSteel takes nothing returns boolean
    return GetUnitTypeId( GetTriggerUnit() ) == 'h011'
endfunction 
Hate добавил:
Hate добавил:
Старый 09.03.2013, 18:01
Variecs

offline
Опыт: 2,508
Активность:
Hate, для этого триггера - возможно, но многие такие проверки будут происходить очень часто, и если утечку не убрать... ну ты понел. Тем более что такие проверки я просто копипастю с уже существующих, меняя только тип юнита.
Старый 09.03.2013, 18:03
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
какая утечка? вы наркоман?
Старый 09.03.2013, 18:10
Киря

offline
Опыт: 769
Активность:
Variecs, слишком много лишнего кода.
Hate правильно написал. Зачем инициализировать лишние переменные, если они используються единожды. Вызывай функции напрямую.
local boolexpr b = Condition( function DeathSteel )
А почему бы сразу не использовать
Condition( function DeathSteel )
Возможно проблема кроется именно в этих излишках. Почисти и проверь еще раз.
Старый 09.03.2013, 18:11
Variecs

offline
Опыт: 2,508
Активность:
~Hate,
Код:
GetUnitTypeId( GetTriggerUnit() )

я чего-то не понимаю?

Variecs добавил:
Я прекрасно знаю, как можно писать короче, и с удовольствием так бы сделал, однако учитывая тот факт, что многие триггеры у меня будут вызываться по 20 раз в секунду, хвосты вроде неудаленных ссылок на юнитов могут сыграть со мной злую шутку.
Старый 09.03.2013, 18:14
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
у вас лишние переменные, утечки в моем коде нету, хоть об стенку разбейтесь, идите читайте статьи по jass
Старый 09.03.2013, 18:17
Киря

offline
Опыт: 769
Активность:
Variecs, забавно.)
Ты в правду считаешь, что
constant native GetTriggerUnit takes nothing returns unit
со временем вызовет утечку?
Безусловно, если ты инициализировал переменную типа unit, то по завершению работы с ней ты должен её обнулить. Но судя из твоих слов ты уже при инициализации типа
unit u = GetTriggerUnit()
получаешь утечку.)
Старый 09.03.2013, 18:19
DioD

offline
Опыт: 45,134
Активность:
call DestroyBoolExpr( b )
Выравнивайте руки об асфальт, хоть бы почитали про оптимизацию, удалятели всего подряд.
Старый 09.03.2013, 18:20
Variecs

offline
Опыт: 2,508
Активность:
Читал и, по-видимому, упоролся. Не понимаю причины, почему утечки нет.

Variecs добавил:
Насколько я понял, утечка возникает по причине того, что вызываемая функция сохраняет возвращаемый результат где-то в лесу, где впоследствии он не обнуляется. Чтобы утечка не возникала, надо возвращать результат в какую-то переменную, которую потом можно обнулить. Но сейчас у меня такое ощущение, что всё это относится к какой-то другой вселенной, а я упорот. Боюсь, ощущение правдиво.
Старый 09.03.2013, 18:29
DioD

offline
Опыт: 45,134
Активность:
почитайте еще раз, и еще раз, в общем читайте до тех пор пока не поймёте.
Старый 09.03.2013, 18:30
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
а почему она должна быть?
Старый 09.03.2013, 18:30
Variecs

offline
Опыт: 2,508
Активность:
Hate,
Цитата:
Насколько я понял, утечка возникает по причине того, что вызываемая функция сохраняет возвращаемый результат где-то в лесу, где впоследствии он не обнуляется. Чтобы утечка не возникала, надо возвращать результат в какую-то переменную, которую потом можно обнулить.

Так я думал. Boy will i change my mind.
Старый 09.03.2013, 18:50
Vadik29
Choice Battle 1.6а
offline
Опыт: 15,845
Активность:
Variecs, Код бред, читай про оптимизацию, все ваши проверки можно легко оптимизировать и убрать лишние переменные. Также советую на такие случаи, создавать глобальный булэкспр, чтобы избежать лишние действия.
player p = Player(4)
В данном случае можно без переменной.
bj_UNIT_FACING ==  270
Вроде как так.

Отредактировано Vadik29, 09.03.2013 в 19:34.
Старый 09.03.2013, 19:28
Variecs

offline
Опыт: 2,508
Активность:
Чтобы избежать в дальнейшем такого нелепого недопонимания:
Код:
function Type1 takes nothing returns boolean
    return ( GetUnitTypeId( GetFilterUnit() ) == udg_UnitType1[udg_Wave] )
endfunction

Здесь нет утечек?
Старый 09.03.2013, 20:00
Киря

offline
Опыт: 769
Активность:
Variecs:
Насколько я понял, утечка возникает по причине того, что вызываемая функция сохраняет возвращаемый результат где-то в лесу, где впоследствии он не обнуляется. Чтобы утечка не возникала, надо возвращать результат в какую-то переменную, которую потом можно обнулить.
TriggerUnit - это юнит, для которого сработало событие. В это время он присутствует у тебя на карте, ты его видишь.
GetTriggerUnit() возвращает ссылку на данного юнита (указатель что-ли). Он не копирует этого юнита.
Старый 09.03.2013, 20:00
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
Variecs:
Чтобы избежать в дальнейшем такого нелепого недопонимания:
function Type1 takes nothing returns boolean
return ( GetUnitTypeId( GetFilterUnit() ) == udg_UnitType1[udg_Wave] )
endfunction
Здесь нет утечек?
нету
Старый 09.03.2013, 20:01
Variecs

offline
Опыт: 2,508
Активность:
Всё, не вижу смысла объяснять суть, почему мой код изобилует таким безобразием, главное я понял, в каких ситуациях возникают утечки. Когда поменяю, отпишусь, но вдруг ошибка не в этом, так что тему пока желательно оставить.
Ах да, и спасибо.
Старый 09.03.2013, 20:06
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
причину вашей проблемы описал диод в посте номер 9, вы удаляете свой кондишн, т.к. слишком увлеклись оптимизацией и попытками сделать совершенный и идеальный код. Печально то, что вы в этих попытках как раз избрали не верный путь, и неверное решение вследствие незнания. Пожалуйста, будьте внимательнее.
Старый 09.03.2013, 20:20
Variecs

offline
Опыт: 2,508
Активность:
Я удаляю кондишн для динамического триггера, а условие перестает работать для базового.
Старый 09.03.2013, 20:36
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 17:18.