Добавлен ArhiMEN
Делал триггер и увидел огромное количество утечек, совершенно не понятных для меня, можете объяснить, как их убрать?
Утечки
function Trig_TerribleWounds_Actions takes nothing returns nothing
local real TerribleWoundsCount
local real UnitLifeOld
local real UnitLifeNow
local group TWGroup = CreateGroup()
local unit TWUnit
call GroupEnumUnitsInRect(TWGroup, GetWorldBounds( ), null)
loop
set TWUnit = FirstOfGroup(TWGroup)
exitwhen TWUnit == null
set TerribleWoundsCount = LoadReal(H, GetHandleId(TWUnit), StringHash("TerribleWoundsCount"))
set UnitLifeOld = LoadReal(H, GetHandleId(TWUnit), StringHash("UnitLifeOld"))
set UnitLifeNow = GetUnitState(TWUnit, UNIT_STATE_LIFE)
if TerribleWoundsCount > 1 then
set TerribleWoundsCount = 1
endif
if (UnitLifeOld < UnitLifeNow) and UnitLifeOld != 0 and TerribleWoundsCount != 0 then
call SetUnitState(TWUnit, UNIT_STATE_LIFE, (UnitLifeNow - (UnitLifeNow - UnitLifeOld) * TerribleWoundsCount))
endif
set UnitLifeOld = GetUnitState(TWUnit, UNIT_STATE_LIFE)
call SaveReal(H, GetHandleId(TWUnit), StringHash("UnitLifeOld"), UnitLifeOld)
call GroupRemoveUnit(TWGroup, TWUnit)
endloop
set TWGroup = null
set TWUnit = null
endfunction
//===========================================================================
function InitTrig_TerribleWounds takes nothing returns nothing
local trigger TerribleWoundsTrigger
set TerribleWoundsTrigger = CreateTrigger( )
call TriggerRegisterTimerEvent(TerribleWoundsTrigger, 0.01, true)
call TriggerAddAction(TerribleWoundsTrigger, function Trig_TerribleWounds_Actions)
set TerribleWoundsTrigger = null
endfunction
При этом делал схожий триггер, но он утечки не вызывает.
Нет утечек
//! nocjass
library Horror requires MemoryHackDamageEventHook
globals
group HorrorGroup = CreateGroup( )
endglobals
function HorrorCheckGroup takes nothing returns nothing
local real HorrorTime = LoadReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"))
local effect HorrorEffect = LoadEffectHandle(H, GetHandleId(GetEnumUnit()), StringHash("HorrorEffect"))
local unit Isazam = LoadUnitHandle(H, GetHandleId(GetEnumUnit()), StringHash("Isazam"))
local real TargetX = GetUnitX(GetEnumUnit())
local real TargetY = GetUnitY(GetEnumUnit())
local real IsazamX = GetUnitX(Isazam)
local real IsazamY = GetUnitY(Isazam)
local integer HorrorQuest = LoadInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"))
if HorrorTime >= 20 then
set HorrorQuest = 1
call SaveInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"), HorrorQuest)
endif
if SquareRoot((IsazamX - TargetX) * (IsazamX - TargetX) + (IsazamY - TargetY) * (IsazamY - TargetY)) >= 700 then //Указываем желаемую дальность увеличенного снижения ужаса
set HorrorTime = HorrorTime - 1.5
else
set HorrorTime = HorrorTime - 1
endif
if HorrorTime <= 0 then
call DestroyEffect(HorrorEffect)
call GroupRemoveUnit(HorrorGroup, GetEnumUnit())
set HorrorTime = 0
else
call PingMinimapEx(TargetX, TargetY, 1, 255, 0, 0, false)
endif
call SaveReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"), HorrorTime)
set HorrorEffect = null
set Isazam = null
endfunction
function HorrorCheckAction takes nothing returns nothing
call ForGroup(HorrorGroup, function HorrorCheckGroup)
endfunction
function Damaged_Handler takes unit source, unit target, real dmg returns nothing
local integer evnt = GetDamageEventESPData()
local integer data = ReadRealMemory(evnt + 0x00)
local real init_dmg = CleanReal(IndexToReal(ReadRealMemory(evnt + 0x04)))
local integer flags = ReadRealMemory(data + 0x0C)
local integer atk_t = ReadRealMemory(data + 0x20)
local real HorrorTime = LoadReal(H, GetHandleId(target), StringHash("HorrorTime"))
local effect HorrorEffect
local unit Isazam
local integer HorrorQuest = LoadInteger(H, GetHandleId(source), StringHash("HorrorQuest"))
if GetUnitTypeId(source) == 'U005' then // Ставим свой ID Исазама
call SaveReal(H, GetHandleId(target), StringHash("HorrorTime"), HorrorTime + 2 + HorrorQuest)
if HorrorTime <= 0 then
set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl", target, "chest")
call SaveEffectHandle(H, GetHandleId(target), StringHash("HorrorEffect"), HorrorEffect)
call SaveUnitHandle(H, GetHandleId(target), StringHash("Isazam"), source)
call GroupAddUnit(HorrorGroup, target)
elseif (IsFlagBitSet(flags, 0x100) or IsFlagBitSet(flags, 0x101)) and atk_t != 0 and HorrorTime > 0 then
set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", source, "origin")
call DestroyEffectTimer(HorrorEffect, 0.3)
call SetUnitState(source, UNIT_STATE_LIFE, (GetUnitState(source, UNIT_STATE_LIFE) + init_dmg * 0.2))
endif
endif
set HorrorEffect = null
set Isazam = null
endfunction
function Damage_Event takes nothing returns nothing
call DisableTrigger( GetTriggeringTrigger( ) )
call Damaged_Handler( GetEventDamageSource( ), GetTriggerUnit( ), GetEventDamage( ) )
call EnableTrigger( GetTriggeringTrigger( ) )
endfunction
endlibrary
function InitTrig_Horror takes nothing returns nothing
local group gMain = CreateGroup()
local unit uTemp
local trigger trTemp
local trigger HorrorCheck
if true then
set trTemp = CreateTrigger( )
call GroupEnumUnitsInRect( gMain, GetWorldBounds( ), null )
loop
set uTemp = FirstOfGroup( gMain )
exitwhen uTemp == null
call TriggerRegisterUnitEvent( trTemp, uTemp, EVENT_UNIT_DAMAGED )
call GroupRemoveUnit( gMain, uTemp )
endloop
call TriggerAddAction( trTemp, function Damage_Event )
endif
set HorrorCheck = CreateTrigger( )
call TriggerRegisterTimerEvent(HorrorCheck, 1, true)
call TriggerAddAction(HorrorCheck, function HorrorCheckAction)
set gMain = null
set uTemp = null
set trTemp = null
set HorrorCheck = null
endfunction
//! endnocjass
Принятый ответ
Да, в самом коде тоже можно оптимизировать. Про вынос стрингхешей уже сказали.
Еще например функция GetWorldBounds(), насколько помнится, создает новый рект каждый вызов. То есть его как минимум надо удалять после этого. А лучше только один раз ее вызвать и тоже просто загнать в глобалку на всю игру. Или можно пользоваться БЖшной глобалкой bj_mapInitialPlayableArea (но она учитывает только играбельную зону карты, без черных краев).
Еще например функция GetWorldBounds(), насколько помнится, создает новый рект каждый вызов. То есть его как минимум надо удалять после этого. А лучше только один раз ее вызвать и тоже просто загнать в глобалку на всю игру. Или можно пользоваться БЖшной глобалкой bj_mapInitialPlayableArea (но она учитывает только играбельную зону карты, без черных краев).
`
ОЖИДАНИЕ РЕКЛАМЫ...
Показан только небольшой набор комментариев вокруг указанного.
Перейти к актуальным.
0
Показать
XGM Bot
4 года
0
Показать
Похожие вопросы:
- Простой вопрос по поводу утечек в BJ
ответ
nvc123:
- Утечки в системе динамических триггеров
ответ
quq_CCCP:
- Как автоматически убрать все утечки в триггерах?
ответ
Hate:
- Выявление утечек в коде имитации крипов в МОБА (как в Доте)
ответ
ScorpioT1000:
- Мини триггер для выявления утечек в карте.
ответ
Пушистый:
Поиск по всем ресурсам на сайте
0
Показать
rsfghd
4 года
0
Показать
там нет утечек, действия происходят в основном с реальными, единственное что обнулять в конце юнита не нужно, если цикл уже заканчивается юнит == null, но это явно не причина твоих бед
а стоп, нашел утечку, ты создал группу в начале но не удалил в конце, лол)
короче будь внимательнее
0
Показать
ArhiMEN
4 года
0
Показать
Эта функция? Если да, то не поммогло.
Для проверки утечек я пользуюсь счётчиком хендлов и он за минуту 1500+ показывает
2
Показать
quq_CCCP
4 года
2
Показать
ArhiMEN, а что за код, я чето не понял что это за триггер с переодическим таймером 100 раз в сек, чето делает. Каждый раз создается новая группа, зачем? Обьясни что собрался делать?
0
Показать
rsfghd
4 года
0
Показать
ArhiMEN, ну так и правильно показывает, ерунду делаешь. Сделай глобалку и ей перебирай
0
Показать
JackFastGame
4 года
0
Показать
quq_CCCP:
Я делал бенчмарк (на попугаях Анрайза) прохода по глобальной группе и локально создаваемой группе, разницы практически нет.
0
Показать
Берги
4 года
0
Показать
JackFastGame:
Наконец-то некоторые начинают понимать что разницы практически нет и этим можно пренебречь
Показан только небольшой набор комментариев вокруг указанного.
Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.