Сейчас 21:31:36 Четверг, 27 июня, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Нужна помощоь в устранении утечек
sumertДата: Четверг, 29 Марта 2012, 16:29:10 | Сообщение # 1
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Написал систему выстрелов. Заметил, что лагает, видимо утечки. Отдельно протестировал, вяснил, что лаги в одном триггере. Смутное сомеение, что утечка в недостаточном удалении элементов массива MissileGroupFire. У меня есть два триггера: один создает и иннициализирует выстрелы, задает параметры, а второй отвечает за полет. помогите найти утечку(и). Заранее скажу, что да, я использую в первом тригере CreateGroup(). И пожайлуста не пишите, что-то типа "у тебя говнокод" или "вот тебе сократил все до двух строчек". Заранее благодарен.
Code

function GroupPick takes nothing returns boolean
     local unit f=GetFilterUnit()
     local real r=GetUnitState(f, UNIT_STATE_LIFE)
     local boolean b=false
     set b=GetBooleanAnd( (r>0), ( IsUnitEnemy(f, Player(0)) == true ) )
     set f=null
     set r=0
     return b
endfunction

function PickUnitDamage takes nothing returns nothing
     local unit p=GetEnumUnit()
     local effect e
     if ( IsUnitInGroup(p, udg_MissileGroupFire[udg_loopIndex]) == false) then
           call UnitDamageTarget( udg_Player, p, udg_MissileDamage[udg_loopIndex], true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
           set e = AddSpecialEffectTarget(udg_MissileEffectString[udg_loopIndex], p, "chest")
           call GroupAddUnit( udg_MissileGroupFire[udg_loopIndex],p )
     endif
     call DestroyEffect( e )
     set e=null
     set p = null
endfunction

function DamageType1 takes nothing returns nothing
                 local group G =CreateGroup()  
                 local group G1=CreateGroup()  
                 set G = GetUnitsInRangeOfLocMatching(udg_MissileAOE[udg_loopIndex], udg_MisslePoint, Condition(function GroupPick))
                 set G1 = GetUnitsInRangeOfLocMatching(udg_MissileAOED[udg_loopIndex], udg_MisslePoint, Condition(function GroupPick))
                 set udg_MisslePoint = PolarLocation(udg_MisslePoint, udg_MissileSpeed[udg_loopIndex], udg_MissileAngle[udg_loopIndex])
                 if ( FirstOfGroup(G)!= null ) then
                      call ForGroup( G1, function PickUnitDamage)
                             endif
                 call DestroyGroup (G)
                 set G=null
                 call DestroyGroup (G1)
                 set G1=null
endfunction

function DamageFinal takes nothing returns nothing
                 local group G  
                 set G=CreateGroup()   
                 set G = GetUnitsInRangeOfLocMatching(udg_MissileAOED[udg_loopIndex], udg_MisslePoint, Condition(function GroupPick))
                 if ( FirstOfGroup(G)!= null ) then
                      call ForGroup( G, function PickUnitDamage)
                      set udg_MissileDistanse[udg_loopIndex]=0
                 endif
                 call DestroyGroup (G)
                 set G=null
endfunction

function Trig_Shot2_Actions takes nothing returns nothing
     local real LifeTarget
     local real Distance
     local real alfa
     local real Sinus
     local location StartPoint=GetUnitLoc(udg_Player)
     set udg_loopIndex = 1
     loop
         exitwhen udg_loopIndex > udg_Index
         set LifeTarget=GetUnitState(udg_MissileUnit[udg_loopIndex], UNIT_STATE_LIFE)
         if (LifeTarget> 0) then
             set udg_MisslePoint = GetUnitLoc(udg_MissileUnit[udg_loopIndex])
             if (udg_MissileTypeDamage[udg_loopIndex]== 1) then
                call DamageType1()
             endif
            
             call SetUnitPositionLoc( udg_MissileUnit[udg_loopIndex], udg_MisslePoint)
             call SetUnitFacing(  udg_MissileUnit[udg_loopIndex], udg_MissileAngle[udg_loopIndex])
             set StartPoint=GetUnitLoc(udg_Player)
             set Distance= DistanceBetweenPoints(StartPoint, udg_MisslePoint)
             if ( Distance>= udg_MissileDistanse[udg_loopIndex] ) then
                 call DamageFinal()
                 call KillUnit( udg_MissileUnit[udg_loopIndex] )
                 call DestroyGroup (udg_MissileGroupFire[udg_loopIndex])
                 set udg_IndexZero = ( udg_IndexZero - 1 )
                 if ( udg_IndexZero == 0 ) then
                     call DisableTrigger( gg_trg_Shot2 )
                 endif
              endif
         endif
         call RemoveLocation(udg_MisslePoint)
         call RemoveLocation(StartPoint)
         set StartPoint=null
         set udg_loopIndex = udg_loopIndex + 1
     endloop
endfunction

//===========================================================================
function InitTrig_Shot2 takes nothing returns nothing
     set gg_trg_Shot2 = CreateTrigger(  )
     call TriggerRegisterTimerEventPeriodic( gg_trg_Shot2, 0.03 )
     call TriggerAddAction( gg_trg_Shot2, function Trig_Shot2_Actions )
endfunction

 

SirNikolasДата: Четверг, 29 Марта 2012, 16:37:17 | Сообщение # 2
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Утекают группы. Вместо
Code
G = CreateGroup()
set G = GetUnitsInRangeOfLocMatching(...)
используй
Code
set G = CreateGroup()
call GroupEnumUnitsInRangeOfLoc(...)
Ну и лучше все это перевести на координаты.


 

DreiiДата: Четверг, 29 Марта 2012, 16:40:38 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
А лучше используй мою либу

 

sumertДата: Четверг, 29 Марта 2012, 16:48:39 | Сообщение # 4
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
SirNikolas, а надо использовать call DestroyBoolExpr(filter) после call GroupEnumUnitsInRangeOfLoc(...,filter)?
 

DreiiДата: Четверг, 29 Марта 2012, 16:52:06 | Сообщение # 5
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
sumert, т.к тебе юниты не понадобятся больше лучше делать так:
Code

local unit e
     call GroupEnumUnitsInRange(udg_GG,x,y,radius,null)
     set e=FirstOfGroup(udg_GG)
     exitwhen e=null
     if    CONDITION   then
   //ACTIONS     
     endif
     GroupRemoveUnit(udg_GG,e)
     endloop


 

sumertДата: Четверг, 29 Марта 2012, 17:01:05 | Сообщение # 6
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Dreii, не, юниты мне нужны. Видишь ли, когда летит выстрел и и он поражает кого-то, то этот юнит заносится в группу, чтобы он от этого выстрела больше урон не получил. Выстрел летит сквозь юнитов.
SirNikolas, Хм, помогло, лагать стало меньше, но не перестало. Утечки еще где-то есть.
 

SirNikolasДата: Четверг, 29 Марта 2012, 17:02:30 | Сообщение # 7
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (sumert)
а надо использовать call DestroyBoolExpr(filter) после call GroupEnumUnitsInRangeOfLoc(...,filter)?
Желательно. Но в данном случае лучше grouploop'ом, как сказал Dreii.

Добавлено (29 Март 2012, 17:02:30)
---------------------------------------------

Quote (sumert)
set udg_MisslePoint = PolarLocation(udg_MisslePoint, udg_MissileSpeed[udg_loopIndex], udg_MissileAngle[udg_loopIndex])
Исходная точка теряется.


 

DreiiДата: Четверг, 29 Марта 2012, 17:04:56 | Сообщение # 8
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
sumert, лучше тода сохранять bool на хендл этого юнита и потом проверять

 

sumertДата: Четверг, 29 Марта 2012, 17:05:27 | Сообщение # 9
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Quote (SirNikolas)
Исходная точка теряется.

Это переприсваивание сделано специально.
 

SirNikolasДата: Четверг, 29 Марта 2012, 17:08:09 | Сообщение # 10
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Но ты ее не удаляешь.

Добавлено (29 Март 2012, 17:08:09)
---------------------------------------------

Code
set l = udg_MissilePoint
set udg_MissilePoint = PolarLocation(...)
call RemoveLocation(l)


 

sumertДата: Четверг, 29 Марта 2012, 17:09:17 | Сообщение # 11
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Quote (Dreii)
sumert, лучше тода сохранять bool на хендл этого юнита и потом проверять

Это зачем? Разве утечки от этого уменьшаться? Хм, может ты имеешь в виду удаление уже мертвых юнитов? У меня есть триггер на него:
Code

function removeunittimed takes nothing returns nothing  
local timer t = GetExpiredTimer()  
local unit u = LoadUnitHandle(udg_Hash, GetHandleId(t), 1)  
call RemoveUnit(u)  
call FlushChildHashtable(udg_Hash, GetHandleId(t))  
call DestroyTimer(t)  
set t = null  
set u = null  
endfunction  

function RemUT takes unit u, real time returns nothing  
local timer t = CreateTimer()  
call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u)  
call TimerStart(t, time, false, function removeunittimed)  
set t = null  
endfunction  

function Trig_RemoveUnit_Actions takes nothing returns nothing
local unit u
set u=GetTriggerUnit()
call RemUT(u, 90)  
set u=null
endfunction

//===========================================================================
function InitTrig_RemoveUnit takes nothing returns nothing
     set gg_trg_RemoveUnit = CreateTrigger(  )
     call TriggerRegisterAnyUnitEventBJ( gg_trg_RemoveUnit, EVENT_PLAYER_UNIT_DEATH )
     call TriggerAddAction( gg_trg_RemoveUnit, function Trig_RemoveUnit_Actions )
endfunction
 

DreiiДата: Четверг, 29 Марта 2012, 17:11:08 | Сообщение # 12
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
sumert, я имею ввиду вместо занесения в группу делать проверку через хендл юнита.
А зачем удалять мертвых если они сами удаляются


 

sumertДата: Четверг, 29 Марта 2012, 17:15:31 | Сообщение # 13
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Quote (Dreii)
А зачем удалять мертвых если они сами удаляются

Практика показала, что из игры они по какой-то неведомой мне причины не удаляются, когда умирают. а вот от Remove удаляются.
SirNikolas, да, это помогло, теперь утечек нет. Спасибо. Буду знать, что переприсваивание не удаляется изначальную ссылку на точку.
 

SirNikolasДата: Четверг, 29 Марта 2012, 17:19:52 | Сообщение # 14
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (sumert)
из игры они по какой-то неведомой мне причине не удаляются, когда умирают
На них указывают какие-то переменные. Либо у модели нет анимаций decay. Во всех остальных случаях юнит удаляется после смерти.


 

sumertДата: Четверг, 29 Марта 2012, 17:25:53 | Сообщение # 15
10 уровень
Группа: Проверенные
Сообщений: 2330
Награды: 2
Репутация: 1094
Блокировки:
Хм. Ясненько. Тему можно прикрыть.
 

  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz