Добавлен Fa1korn
В моей карте один единственный триггер вызывается каждый раз при получении юнитом урона и, следовательно, 90% утечек происходит из за этого триггера.
Прошу мастеров оптимизации разобраться, в каком именно месте создаются утечки?
Прошу мастеров оптимизации разобраться, в каком именно месте создаются утечки?
код jass (SDMS триггер)
//set Color[0] = "|c00FF0303"//Игрок 1(красный)
//set Color[1] = "|c000042FF"//и по порядку...
//set Color[2] = "|c001CE6B9"
//set Color[3] = "|c00540079"
//set Color[4] = "|c00FFFC01"
//set Color[5] = "|c00FE8A0E"
//set Color[6] = "|cff00ff00"
//set Color[7] = "|c00E55BB0"
//set Color[8] = "|c00959697"
//set Color[9] = "|c007EBFF1"
//set Color[10] = "|c00106246"
//set Color[11] = "|c004E2A04"
//set Color[12] = "|c00282828"// \
//set Color[13] = "|c00282828"// >>Три нейтральных игрока
//set Color[14] = "|c00282828"// /
//========================================
//----------цветовые переменные-----------
//========================================
function SDMSTextVars takes integer PlayerNumber returns string
local string array Color
set Color[0] = "|cffffa500"//Игрок 1(красный)
set Color[1] = "|cffffa500"//и по порядку...
set Color[2] = "|cffffa500"
set Color[3] = "|cffffa500"
set Color[4] = "|cffffa500"
set Color[5] = "|cffffa500"
set Color[6] = "|cffffa500"
set Color[7] = "|cffffa500"
set Color[8] = "|cffffa500"
set Color[9] = "|cffffa500"
set Color[10] = "|cffffa500"
set Color[11] = "|cffffa500"
set Color[12] = "|cff9db9eb"// \
set Color[13] = "|cff9db9eb"// >>Три нейтральных игрока
set Color[14] = "|cff9db9eb"// /
return Color[PlayerNumber]
endfunction
//========================================
//---------Возвращаемые значения----------
//========================================
function SDMSFontSize takes nothing returns real
return 10.0//Размер шрифта, которым будут писаться плавающие строки. Не ставить слишком маленький, т.к. не будет видно. Рекомендую 10-15 пунктов.
endfunction
function SDMStheTrigger takes nothing returns trigger
return udg_SDMStrigger//Здесь название любой простой глобальной переменной типа триггер.
endfunction
function SDMSLifeTime takes nothing returns real
return 1.0//Время продолжительности строки. Большой не ставить, т. к. будет лагать. Рекомендую 1-2 секунды.
endfunction
function SDMSLifeTimeSecondary takes nothing returns real
return 2.0//Дополнительное время продолжительности жизни строки. Не ставить меньше, чем основное, но чем меньше это значение, тем меньше утечка памяти. Рекомендую 120-200% от основного времени.
endfunction
function SDMSMinus takes nothing returns string
return "-"//Возвращает то, что стоит перед числом нанесённого урона. Примеры:
//"Нанесено " например: Нанесено 15
//"Получено " например: Получено 21
//"" например: 16
//Рекомендую использовать "-" из-за большей производительности
endfunction
function SDMSPlus takes nothing returns string
return ""//Возвращает то, что стоит перед числом нанесённого урона. Примеры:
//" ед. урона" например: 15 ед. урона
//" очков повреждения" например: 21 очков повреждения
//Рекомендую использовать "" из-за большей производительности. Комбинируя функции Minus и Plus, можно добиваться отличных результатов. Например: Нанесено 17 ед. урона.
endfunction
//========================================
//----Постоянные функции - не изменять!---
//========================================
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local player pl=GetOwningPlayer(u)
local player pl2=GetOwningPlayer(s)
local integer i=GetConvertedPlayerId(pl)
local texttag tt=null
local real fontSize=SDMSFontSize()
local real lifeTime=SDMSLifeTime()
local real lifeTime2=SDMSLifeTimeSecondary()
local real dmg=GetEventDamage()
local string minus=SDMSMinus()
local string plus=SDMSPlus()
local string textColor=SDMSTextVars(i-1)
local boolean b
local location l
if ( pl2 == Player(PLAYER_NEUTRAL_AGGRESSIVE) and udg_Players > 1) then
set dmg = dmg + dmg*(udg_Players-1)*0.25
if ( GetUnitStateSwap(UNIT_STATE_LIFE, u) <= dmg*(udg_Players-1)*0.25 ) then
call SetUnitState(u, UNIT_STATE_LIFE, 1.00)
else
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, u) - ( dmg*(udg_Players-1)*0.25 ) ))
endif
endif
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
set tt = CreateTextTag()
call SetTextTagText(tt, textColor+minus+I2S(R2I(dmg))+plus+"|r", TextTagSize2Height(fontSize))
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, TextTagSpeed2Velocity(96.0) * Cos(90 * bj_DEGTORAD), TextTagSpeed2Velocity(96.0) * Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, lifeTime)
call SetTextTagFadepoint(tt, 0.0)
endif
//эффекты брызг крови
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 1.0 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", u, "chest"))
else
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 0.33 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl", u, "chest"))
else
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 0.2 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl", u, "chest"))
endif
endif
endif
//Отлов урона
if GetUnitTypeId(s) == 'u026' then //Прорубающая Атака мастера меча
set s = gg_unit_Nbbc_0091
if ( GetUnitAbilityLevelSwapped('A06B', s) > 0 ) then
if ( GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 1 ) then
if ( GetRandomInt(1, 100) <= 3 + GetUnitAbilityLevelSwapped('A06B', s) ) then
set l=GetUnitLoc(u)
call DummyCastUnit( GetOwningPlayer(s), l, 0.5, 'A045', 1, "bloodlust", s )
call RemoveLocation(l)
endif
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Spirit_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 2 ) then
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call SetUnitState(s, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, s) + I2R(GetHeroAgi(s, true)) * ( 0.04 + ( 0.04 * I2R(GetUnitAbilityLevelSwapped('A06B', s)) ) ) ) )
else
call SetUnitState(s, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, s) + I2R(GetHeroAgi(s, true)) * ( 0.02 + ( 0.02 * I2R(GetUnitAbilityLevelSwapped('A06B', s)) ) ) ) )
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", s, "chest"))
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Grow_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 3 ) then
call DisableTrigger( GetTriggeringTrigger())
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call DamageArea (s, GetUnitX(u), GetUnitY(u), 200, I2R(GetHeroAgi(s, true)) * ( 0.2 + ( 0.2 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL)
else
call DamageArea (s, GetUnitX(u), GetUnitY(u), 200, I2R(GetHeroAgi(s, true)) * ( 0.1 + ( 0.1 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL)
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", u, "chest"))
call EnableTrigger( GetTriggeringTrigger())
else
call DisableTrigger( GetTriggeringTrigger())
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)) * ( 0.2 + ( 0.2 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)) * ( 0.1 + ( 0.1 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call EnableTrigger( GetTriggeringTrigger())
endif
endif
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call DisableTrigger( GetTriggeringTrigger())
call UnitDamageTarget(s, u, 50 + ( 25 * I2R(GetUnitAbilityLevelSwapped('A0A9', s)) ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger())
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Spirit_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 2 ) then
set l=GetUnitLoc(u)
if ( GetRandomInt(1, 100) <= udg_Hero_Grow_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 3 ) then
call DummyCastUnit(GetOwningPlayer(s),l,0.5,'A0IK',2,"acidbomb",u)
else
call DummyCastUnit(GetOwningPlayer(s),l,0.5,'A0IK',1,"acidbomb",u)
endif
call RemoveLocation(l)
endif
endif
//эффекты предметов
if (GetUnitAbilityLevel(u, 'B02S') > 0) then
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + dmg * 2.00 ))
endif
if (GetUnitAbilityLevel(u, 'B01L') > 0) then
call SetUnitState(s, UNIT_STATE_MANA, ( GetUnitState(s, UNIT_STATE_MANA) + 6.00 ))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl", s, "overhead"))
endif
if (GetUnitAbilityLevel(u, 'B01K') > 0) then
call SetUnitState(s, UNIT_STATE_MANA, ( GetUnitState(s, UNIT_STATE_MANA) + 20.00 ))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl", s, "overhead"))
else
if (GetUnitAbilityLevel(u, 'B01E') > 0) then
call DisableTrigger( GetTriggeringTrigger() )
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger() )
else
if (GetUnitAbilityLevel(u, 'B01G') > 0) then
call DisableTrigger( GetTriggeringTrigger() )
call UnitDamageTarget(s, u, ((GetUnitX(u)-GetUnitX(s))*(GetUnitX(u)-GetUnitX(s)) + (GetUnitY(u)-GetUnitY(s))*(GetUnitY(u)-GetUnitY(s)))*0.2, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger() )
endif
endif
endif
if ( GetUnitAbilityLevel(u, 'B02O') > 0 or GetUnitAbilityLevel(u, 'B02N') > 0 ) then
set udg_FireBlades_Target = u
call CreateUnit( pl2, 'u00W', GetUnitX(u), GetUnitY(u), bj_UNIT_FACING )
endif
if (GetUnitAbilityLevel(u, 'B03M') > 0) then
if ( dmg > 50.00 ) then
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + 50.00 ))
else
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + dmg ))
endif
endif
//
call PolledWait(lifeTime2)
set u=null
set s=null
set pl=null
set pl2=null
set l=null
set i=0
set fontSize=0
set lifeTime=0
set lifeTime2=0
set dmg=0
set minus=""
set plus=""
set textColor=""
call DestroyTextTag(tt)
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(SDMStheTrigger(),GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function SDMSGroupFunction takes nothing returns nothing
local unit u=GetEnumUnit()
call TriggerRegisterUnitEvent(SDMStheTrigger(),u,EVENT_UNIT_DAMAGED)
set u=null
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
local trigger TextTagCreate=SDMStheTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter,GetPlayableMapRect())
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
call ForGroupBJ(GetUnitsInRectAll(GetPlayableMapRect()),function SDMSGroupFunction)
set UnitEnter=null
set TextTagCreate=null
endfunction
//========================================
//---------------Не трогать!--------------
//========================================
function InitTrig_the_SDM_Ttrigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(SDMStheTrigger(),function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Карта прилагается
Принятый ответ
Эмм что за ерунда, сократил код, убрав всё лишнее, но утечки все равно остаются, по 1.5 - 2 хэндла за каждое нанесение урона (тип хэндла не знаю как посмотреть). Когда триггер отключаешь, то всё нормально.
Сокращенный код
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local integer i=GetConvertedPlayerId(GetOwningPlayer(u))
local texttag tt=CreateTextTag()
local real dmg=GetEventDamage()
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
if GetPlayerId(GetOwningPlayer(u))==12 then
call SetTextTagText(tt, "|cff9db9eb-"+I2S(R2I(dmg))+"|r", 0.023)
else
call SetTextTagText(tt, "|cffffa500-"+I2S(R2I(dmg))+"|r", 0.023)
endif
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, 0.05325*Cos(90 * bj_DEGTORAD), 0.05325*Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, 1.0)
call SetTextTagFadepoint(tt, 0.0)
endif
call PolledWait(2.0)
call DestroyTextTag(tt)
set u=null
set s=null
set i=0
set dmg=0
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(udg_SDMStrigger,GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter, gg_rct_Arena)
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
set UnitEnter=null
endfunction
function InitTrig_the_SDMS_Trigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(udg_SDMStrigger,function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Wait вызывает утечки ((
Пришлось делать через таймер
Пришлось делать через таймер
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Советую почитать про утечки как следует. Или внимательно просмотреть карту Leak вот здесь xgm.guru/p/wc3/bpe
Melissa:
Пришлось делать через таймер