|
|
|
|
Нужна помощоь в устранении утечек
|
|
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
Блокировки:
| Хм. Ясненько. Тему можно прикрыть.
|
|
|
|
|
|
|
|
|
|
|