Здраствуйте. Небольшая предыстория. Шел я значит по триггерам, проверял все как мог. И тут дошел до действия с заменой юнита:
Конвертнул его в текст, нашел бж, сразу пошел её проверять
В указанной статье она описана как с утечкой, значит надо что-то делать.
И тут я решил испытать новый подход:
в function list нашел собственно функцию ReplaceUnitBJ, на глаз попытался определить что тут утекает(и что нужно обнулить). Далее скопировал, дописал как надо( set oldUnit = null и set indexItem = null), конвертнул мой триггер в код, функцию написал как без БЖ и собственно проверил. Оно вроде бы заработало, далее я перенес её в шапку карты, оно приняло там такой вид:
в function list нашел собственно функцию ReplaceUnitBJ, на глаз попытался определить что тут утекает(и что нужно обнулить). Далее скопировал, дописал как надо( set oldUnit = null и set indexItem = null), конвертнул мой триггер в код, функцию написал как без БЖ и собственно проверил. Оно вроде бы заработало, далее я перенес её в шапку карты, оно приняло там такой вид:
function ReplaceUnit takes unit whichUnit, integer newUnitId, integer unitStateMethod returns unit
local unit oldUnit = whichUnit
local unit newUnit
local boolean wasHidden
local integer index
local item indexItem
local real oldRatio
// If we have bogus data, don't attempt the replace.
if (oldUnit == null) then
set bj_lastReplacedUnit = oldUnit
return oldUnit
endif
// Hide the original unit.
set wasHidden = IsUnitHidden(oldUnit)
call ShowUnit(oldUnit, false)
// Create the replacement unit.
if (newUnitId == 'ugol') then
set newUnit = CreateBlightedGoldmine(GetOwningPlayer(oldUnit), GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
else
set newUnit = CreateUnit(GetOwningPlayer(oldUnit), newUnitId, GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
endif
// Set the unit's life and mana according to the requested method.
if (unitStateMethod == bj_UNIT_STATE_METHOD_RELATIVE) then
// Set the replacement's current/max life ratio to that of the old unit.
// If both units have mana, do the same for mana.
if (GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE) > 0) then
set oldRatio = GetUnitState(oldUnit, UNIT_STATE_LIFE) / GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE)
call SetUnitState(newUnit, UNIT_STATE_LIFE, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
endif
if (GetUnitState(oldUnit, UNIT_STATE_MAX_MANA) > 0) and (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
set oldRatio = GetUnitState(oldUnit, UNIT_STATE_MANA) / GetUnitState(oldUnit, UNIT_STATE_MAX_MANA)
call SetUnitState(newUnit, UNIT_STATE_MANA, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
endif
elseif (unitStateMethod == bj_UNIT_STATE_METHOD_ABSOLUTE) then
// Set the replacement's current life to that of the old unit.
// If the new unit has mana, do the same for mana.
call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(oldUnit, UNIT_STATE_LIFE))
if (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(oldUnit, UNIT_STATE_MANA))
endif
elseif (unitStateMethod == bj_UNIT_STATE_METHOD_DEFAULTS) then
// The newly created unit should already have default life and mana.
elseif (unitStateMethod == bj_UNIT_STATE_METHOD_MAXIMUM) then
// Use max life and mana.
call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
else
// Unrecognized unit state method - ignore the request.
endif
// Mirror properties of the old unit onto the new unit.
//call PauseUnit(newUnit, IsUnitPaused(oldUnit))
call SetResourceAmount(newUnit, GetResourceAmount(oldUnit))
// If both the old and new units are heroes, handle their hero info.
if (IsUnitType(oldUnit, UNIT_TYPE_HERO) and IsUnitType(newUnit, UNIT_TYPE_HERO)) then
call SetHeroXP(newUnit, GetHeroXP(oldUnit), false)
set index = 0
loop
set indexItem = UnitItemInSlot(oldUnit, index)
if (indexItem != null) then
call UnitRemoveItem(oldUnit, indexItem)
call UnitAddItem(newUnit, indexItem)
endif
set index = index + 1
exitwhen index >= bj_MAX_INVENTORY
endloop
endif
// Remove or kill the original unit. It is sometimes unsafe to remove
// hidden units, so kill the original unit if it was previously hidden.
if wasHidden then
call KillUnit(oldUnit)
call RemoveUnit(oldUnit)
else
call RemoveUnit(oldUnit)
endif
set bj_lastReplacedUnit = newUnit
set oldUnit = null
set indexItem = null
return newUnit
endfunction
В конвертнутом тригге тоже заменил бж на мною созданную "Починенную" функцию.
И вроде бы, по моему мнению, я должен был утечек избежать. Но таблица хендлов начинает скакать то назад, то вперед, а через некоторое время резко доходит до числа 52к+-. Есть два вопроса. Один по поводу того, что я тут наделал: в правильном направлении я шел и убрал ли я утечки этого действия (на большой карте тяжело отследить результат от этого конкретного действия). Второй вопрос: почему постоянно, когда опять же что-то утекает, вдруг происходит взрывной рост до 52+- тысяч. То есть катализатором может быть любой кривой код, но чую причина взрывного роста какая-та иная (может тоже связана с масштабом карты, а может и систему учета утечек не справляется.
В общем, буду благодарен за наводки и предположения.
И вроде бы, по моему мнению, я должен был утечек избежать. Но таблица хендлов начинает скакать то назад, то вперед, а через некоторое время резко доходит до числа 52к+-. Есть два вопроса. Один по поводу того, что я тут наделал: в правильном направлении я шел и убрал ли я утечки этого действия (на большой карте тяжело отследить результат от этого конкретного действия). Второй вопрос: почему постоянно, когда опять же что-то утекает, вдруг происходит взрывной рост до 52+- тысяч. То есть катализатором может быть любой кривой код, но чую причина взрывного роста какая-та иная (может тоже связана с масштабом карты, а может и систему учета утечек не справляется.
В общем, буду благодарен за наводки и предположения.
Принятый ответ
VinerX, посмотри гуи функцию "пропустить остальные действия" по факту это слово "return" в коде, то есть после ретурна ты никак не поставишь set newUnit = null, и правильно это делать после set bj_lastReplacedUnit = newUnit, а возвращать не newUnit, а bj_lastReplacedUnit, вот код если непонятно
set bj_lastReplacedUnit = newUnit
set newUnit = null
set oldUnit = null
set indexItem = null
return bj_lastReplacedUnit
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован VinerX
Отредактирован rsfghd
Так, ну по поводу ретурна понял, огромное спасибо.
А вот случалось нечто подобное из второго вопроса(резкий необъясним скачек хендлов) ? Понимаю, может его сформулировал не понятно, но вдруг. Ну и хендлкаунтер, с ним как, все нормально?
Отредактирован rsfghd
но имей ввиду, хэндлы это всё что находится на карте кроме дудадов