| 03-16-2007, 11:30 PM | #1 |
Anyone knows why this is leaking heavily? (yes I know polarprojection sucks, but im not yet enough interested in the project this code comes from to change it to reals, I also know about the BJ's, but I dont care for the same reason as above) First 15 uses/arrows are fine, after that it starts lagging alot even thou udg_Arrows is empty and soon freezes wc3 JASS:function TargetIsEnemy takes nothing returns boolean return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetEnumUnit())) == true) endfunction function CheckTargetsEmpty takes unit u returns boolean return u == null endfunction function Trig_Timer_Conditions takes nothing returns boolean local unit u = FirstOfGroup(udg_Arrows) return u != null endfunction //just added this function now to prevent this trigger from running every 0.05 sec with no arrows function ArrowBallMoveDamage takes nothing returns nothing local unit pick = GetEnumUnit() local location l = GetUnitLoc(pick) local unit e local group targets = GetUnitsInRangeOfLocMatching(20.00, l, Condition(function TargetIsEnemy)) local unit target = FirstOfGroup(targets) local location arrowpoint if CheckTargetsEmpty(target) then set arrowpoint = PolarProjectionBJ(l, 2.00, GetUnitFacing(pick)) call SetUnitPositionLoc(pick, arrowpoint) call RemoveLocation(arrowpoint) call GroupClear(targets) else call UnitDamageTarget(pick, target, 300.00, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS) set e = CreateUnitAtLoc(Player(0),'h005',l,0) //impact effect call KillUnit(e) call KillUnit(pick) call GroupRemoveUnit( udg_Arrows, pick ) call TriggerSleepAction(1.50) //wait so effects animation can be played call RemoveUnit(e) call RemoveUnit(pick) endif call RemoveLocation(l) call DestroyGroup(targets) set l = null set e = null set pick = null set arrowpoint = null set targets = null set target = null endfunction function Trig_Timer_Actions takes nothing returns nothing call ForGroupBJ( udg_Arrows, function ArrowBallMoveDamage ) endfunction //=========================================================================== function InitTrig_Timer takes nothing returns nothing set gg_trg_Timer = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_Timer, 0.01 ) call TriggerAddCondition( gg_trg_Timer, Condition( function Trig_Timer_Conditions ) ) call TriggerAddAction( gg_trg_Timer, function Trig_Timer_Actions ) endfunction |
| 03-17-2007, 01:56 AM | #2 |
At first glance, RemoveLocation(arrowpoint) is missing EDIT: second glance, you do call it. Although this may still be the problem because if the if is not equal to true, then it wont get cleaned up. Move it to outside the if/then, to where the other cleanup calls are. |
| 03-17-2007, 11:36 AM | #3 |
arrowpoint is never set unless CheckTargetsEmpty is true, so why should I clean a empty variable? Code:
local arrowpoint if theboolean == true then set arrowpoint = some location remove arrowpoint endif set arrowpoint = null *edit* hmm doesnt this leak? JASS:function PolarProjectionBJ takes >location source<, real dist, real angle returns location local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD) local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD) return Location(x, y) endfunction |
| 03-17-2007, 04:27 PM | #4 | |
Quote:
By setting arrowpoint = null, that is cleaning the value. The RemoveLocation(arrowpoint) is actually destroying the variable, which is created when you declare "local location arrowpoint". Switch around the "set arrowpoint = null" and the "call RemoveLocation(arrowpoint)" with each other. |
| 03-17-2007, 05:52 PM | #5 |
I've only heard the opposite, which also sounds more logical :S |
| 03-17-2007, 07:24 PM | #6 |
A handle is a pointer. Its an arrow pointing at the actual data. Nulling the variable removes the arrow. Destroying the location removes the actual data. |
| 03-18-2007, 12:03 AM | #7 |
Aye. So then my code should be correct? |
| 03-20-2007, 01:13 PM | #8 |
*bump* |
| 03-20-2007, 01:35 PM | #9 |
You're not supposed to bump after only two days. Your problems is that trigger sleep actions kill ForGroup callback threads so your units are never removed. And your condition leaks a handle reference. |
| 03-20-2007, 02:44 PM | #10 | ||
Quote:
anyway seems the bump was successful ah right I've heard about that thingy, will fix. *edit* thought Execute could fix it, but it still leaks like *****. could it be the condition handle? :S JASS:function Killing takes nothing returns nothing local unit e = udg_e local unit pick = udg_pick set udg_e = null set udg_pick = null call TriggerSleepAction(1.5) call RemoveUnit(e) call RemoveUnit(pick) set e = null set pick = null endfunction function ArrowBallMoveDamage takes nothing returns nothing local unit pick = GetEnumUnit() local location l = GetUnitLoc(pick) local unit e = null local group targets = GetUnitsInRangeOfLocMatching(20.00, l, Condition(function TargetIsEnemy)) local unit target = FirstOfGroup(targets) local location arrowpoint if CheckTargetsEmpty(target) then set arrowpoint = PolarProjectionBJ(l, 2.00, GetUnitFacing(pick)) call SetUnitPositionLoc(pick, arrowpoint) call RemoveLocation(arrowpoint) call GroupClear(targets) else call UnitDamageTarget(pick, target, 300.00, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS) set e = CreateUnitAtLoc(Player(0),'h005',l,0) call KillUnit(e) call KillUnit(pick) call GroupRemoveUnit( udg_Arrows, pick ) set udg_e = e set udg_pick = pick call ExecuteFunc("Killing") endif call RemoveLocation(l) call DestroyGroup(targets) set e = null set l = null set pick = null set arrowpoint = null set targets = null set target = null endfunction *edit2* seems like PolarProjection caused most of the leak, this is the current code:
Before this thread, I could only use like 30-40 arrows before the game got unplayable, now I'm up in 200+. Though something still leaks.. :/ |
| 03-21-2007, 08:07 AM | #11 |
It's possible your group never has units in and the arrow will never be removed. Try a debug message and check whether or not every arrow is removed (perhaps keep a debug counter of active arrows) and you can check it. |
| 03-21-2007, 03:15 PM | #12 |
Finally some clear results! It seems the arrow removal is not the problem, but the effects. They never seem to be removed :S Will do some further testings to specify what part of the system. *edit* Even thou I am now removing the effects using a periodic timer it still leaks! And now almost even more then before ![]() |
| 03-27-2007, 10:58 AM | #13 |
*bump* |
| 03-27-2007, 11:26 AM | #14 |
First of all, you have a double free. JASS:function ArrowMoveDamage takes nothing returns nothing local unit pick = GetEnumUnit() local location l = GetUnitLoc(pick) local unit e = null local group targets = GetUnitsInRangeOfLocMatching(20.00, l, Condition(function TargetIsEnemy)) local unit target = FirstOfGroup(targets) local location arrowpoint if CheckTargetsEmpty(target) then set arrowpoint = PolarProjectionTJ(l, 2.00, GetUnitFacing(pick)) call SetUnitPositionLoc(pick, arrowpoint) call RemoveLocation(arrowpoint) call GroupClear(targets) else call UnitDamageTarget(pick, target, 300.00, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS) set e = CreateUnitAtLoc(Player(0),'h005',l,0) call KillUnit(e) call KillUnit(pick) call GroupRemoveUnit( udg_Arrows, pick ) set udg_e = e set udg_pick = pick call ExecuteFunc("Killing") endif call RemoveLocation(l) call DestroyGroup(targets) set e = null set l = null set pick = null set arrowpoint = null set targets = null set target = null endfunction JASS:function PolarProjectionTJ takes location source, real dist, real angle returns location local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD) local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD) call RemoveLocation(source) set source = null return Location(x, y) endfunction It's pointless, their references properly maintain themselves. So get rid of all of those. JASS:function CheckTargetsEmpty takes unit u returns boolean if u == null then set u = null return true else set u = null return false endif return u == null endfunction JASS:function CheckTargetsEmpty takes unit u returns boolean return u == null endfunction Next, you are running a function in such a way that the function will be running HUNDREDS of times before the first one finishes. (Thanks to the shittyness of TSA) Notably, WC3's normaly framerate is 0.033 seconds, so using ANYTHING faster is absolutely silly. 0.01 is faster than anything in WC3 should be, and that means you're running the WHOLE thing 100 times a second. That's a lot, and the freeze up may be nothing more than computer overload. Also, you may be breaking WC3. JASS:... else call UnitDamageTarget(pick, target, 300.00, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS) set e = CreateUnitAtLoc(Player(0),'h005',l,0) call KillUnit(e) call KillUnit(pick) call GroupRemoveUnit( udg_Arrows, pick ) set udg_e = e set udg_pick = pick call ExecuteFunc("Killing") endif ... JASS:function Killing takes nothing returns nothing local unit e = udg_e local unit pick = udg_pick set udg_e = null set udg_pick = null call TriggerSleepAction(1.5) call RemoveUnit(e) call RemoveUnit(pick) set e = null set pick = null endfunction If the unit decays within 1.5 seconds, then you're calling RemoveUnit() on an already removed unit. This not only is beyond unsafe, but if you use H2I() anywhere in the map this can cause handles to be created on eachother's indicies, frying any hopes of your map working. And probably not the cause, but that BJ you use to create your group leaks a group reference. Nothing cataclysmic, but anything helps. My best recommendation is to move from locations to reals and to slow down this timer. Yes, it will help that much. |
| 03-28-2007, 03:02 PM | #15 | |
Quote:
Hmm, maybe I'll have to use coordinates anyway then :/ I'll slow down the timer too. The reason why I think it is a leak is because if I never fire any shots, It never starts to freeze. And it only starts to lag heavily after lots of arrows has been shot. |
