| 01-15-2008, 02:47 AM | #1 |
When I declare a struct and do not destroy it or assign it, does it leak any data? I can't explain without an example.. Here is some script I made for a spell called exploding arrow. In the function "ArrowCountStart" I declare the struct (immoxstuct) a possible total of 400 times, but it's not created unless certain conditions are met, or is it? Is a stuct only created when I use .create() and not when I actually declare it like "local struct data" but no "struct.create()". I put a comment near the concerned area, just scroll down to the ArrowCountStart function. Edit: Also if anyone has time.. can a method to remove these globals be explained to me? I use the globals because I'm not sure if you can alter any data in a struct without messing something up. Like, I'm using the globals to keep track of what loop in the timer im in. So when the function ends I'm not sure if you like, set an integer to a new value if its remembered next time around. JASS:// Description: Charges an arrow for 4 seconds on a target unit. Every second // the arrow will be stronger. The arrow explodes on impact, creating fire on the // ground dealing damage over time. globals real array IMMOCHECK integer array IMMOLEVEL endglobals struct immoxstruct timer t = CreateTimer() unit v // Target unit. player p // Owner of Caster. integer r // Set level of Immolation. method onDestroy takes nothing returns nothing call FlushHandleLocals(.t) call PauseTimer(.t) call DestroyTimer(.t) endmethod endstruct struct immoarrow timer t = CreateTimer() unit u // Casting unit. unit v // Target unit. player p // Owner of caster. integer i // Player number. integer a // Level of ability. integer d // Duration. real x // X location of caster. real y // Y location of caster. effect e // Special effect on caster left hand. effect f // Special effect on caster right hand. static method create takes nothing returns immoarrow local immoarrow data = immoarrow.allocate() set data.u = GetSpellAbilityUnit() set data.v = GetSpellTargetUnit() set data.p = GetOwningPlayer(data.u) set data.i = GetPlayerId(data.p) set data.x = GetUnitX(data.u) set data.y = GetUnitY(data.u) set data.a = GetUnitAbilityLevel(data.u, 'A00G') set data.e = AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", data.u, "left hand") set data.f = AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", data.u, "right hand") set IMMOCHECK[data.i] = 0 set IMMOLEVEL[data.i] = 0 return data endmethod method onDestroy takes nothing returns nothing call DestroyEffect(.e) call DestroyEffect(.f) call FlushHandleLocals(.t) call PauseTimer(.t) call DestroyTimer(.t) endmethod endstruct function ExplodingArrowCond takes nothing returns boolean return GetSpellAbilityId() == 'A00G' endfunction function ExplodingArrowEffect takes nothing returns nothing local timer t = GetExpiredTimer() local immoxstruct data = GetHandleInt(t, "struct") local integer i = 0 local real x = GetUnitX(data.v) local real y = GetUnitY(data.v) local unit u if GetUnitAbilityLevel(data.v, 'B004') > 0 then call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl", data.v, "head")) loop exitwhen i > 8 set x = GetUnitX(data.v) + 150 * Cos((i*45) * bj_DEGTORAD) set y = GetUnitY(data.v) + 150 * Sin((i*45) * bj_DEGTORAD) set u = CreateUnit(data.p, 'h00A', x, y, 270) call UnitApplyTimedLife(u, 'BTLF', 5) call UnitAddAbility(u, data.r) set i = i + 1 endloop set x = GetUnitX(data.v) set y = GetUnitY(data.v) set u = CreateUnit(data.p, 'h00A', x, y, 270) call UnitApplyTimedLife(u, 'BTLF', 5) call UnitAddAbility(u, data.r) call data.destroy() endif set u = null set t = null endfunction function ArrowCountStart takes nothing returns nothing local timer t = GetExpiredTimer() local immoxstruct Data // THIS IS MY CONCERN, IS THIS LEAKING? local immoarrow data = GetHandleInt(t, "struct") local unit u // Unit to cast dummy. local integer z // The dummy arrow. local integer r // The dummy immolation. set IMMOCHECK[data.i] = IMMOCHECK[data.i] + .10 if IMMOCHECK[data.i] == 1 or IMMOCHECK[data.i] == 2 or IMMOCHECK[data.i] == 3 or IMMOCHECK[data.i] == 4 then set IMMOLEVEL[data.i] = IMMOLEVEL[data.i] + 1 endif if not(GetUnitCurrentOrder(data.u) == OrderId("drain")) or IMMOCHECK[data.i] == 4 then call SetUnitAnimation(data.u, "stand") call SetUnitTimeScale(data.u, 1) if GetWidgetLife(data.v) > 0 and GetWidgetLife(data.u) > 0 then if IMMOLEVEL[data.i] == 0 then set IMMOLEVEL[data.i] = 1 endif if data.a == 1 then set z = 'A00J' set r = 'A00P' elseif data.a == 2 then set z = 'A00I' set r = 'A00O' elseif data.a == 3 then set z = 'A00H' set r = 'A00N' elseif data.a == 4 then set z = 'A00K' set r = 'A00M' elseif data.a == 5 then set z = 'A00L' set r = 'A00Q' endif set u = CreateUnit(data.p, 'h007', data.x, data.y, 270) call UnitAddAbility(u, z) call SetUnitAbilityLevel(u, z, IMMOLEVEL[data.i]) call IssueTargetOrder(u, "acidbomb", data.v) call UnitApplyTimedLife(u, 'BTLF', 3) // Sets the data for when the arrow makes impact. set Data = immoxstruct.create() // HERE IS WHERE I CREATE IT. set Data.r = r set Data.v = data.v set Data.p = data.p call SetHandleInt(Data.t, "struct", data) call TimerStart(Data.t, .01, true, function ExplodingArrowEffect) endif call data.destroy() endif set u = null set t = null endfunction function ExplodingArrowCast takes nothing returns nothing local immoarrow data = immoarrow.create() call SetHandleInt(data.t, "struct", data) call TriggerSleepAction(.01) call SetUnitAnimation(data.u, "attack") call TriggerSleepAction(.10) call SetUnitTimeScale(data.u, .05) call TimerStart(data.t, .10, true, function ArrowCountStart) endfunction function InitTrig_RangerExplodingArrow takes nothing returns nothing set gg_trg_RangerExplodingArrow = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_RangerExplodingArrow, EVENT_PLAYER_UNIT_SPELL_CAST) call TriggerAddCondition(gg_trg_RangerExplodingArrow, Condition(function ExplodingArrowCond)) call TriggerAddAction(gg_trg_RangerExplodingArrow, function ExplodingArrowCast) endfunction |
| 01-15-2008, 04:19 AM | #2 | |
Quote:
I don't know about the second question. |
| 01-15-2008, 08:53 PM | #3 |
Not assigning it doesn't leak, not destroying does (kinda). Struct are just acting like types (unit, player, item.....), only thing: they are not handles, they actually act like integers. JASS:function MyFunc takes nothing returns nothing local MyStruct s endfunction Doesn't leak, but: JASS:function MyFunc takes nothing returns nothing local MyStruct s = MyStruct.create() // ... // no s.destroy() anywhere endfunction Does leak, think of it like this: JASS:function MyFunc takes nothing returns nothing local group g endfunction Doesn't leak, but: JASS:function MyFunc takes nothing returns nothing local group g = CreateGroup() // ... // no DestroyGroup(g) anywhere endfunction Does leak. So a struct is only created when you use .create(), moreover, an instance of it is created with .create(). So in your example immoxstruct would leak if the conditions are true, because it isn't destroyed anywhere. I dont' get the second question. |
| 01-18-2008, 10:33 AM | #4 | |
Quote:
It should be destroyed in the function "ExplodingArrowEffect". When the missile reaches the target it checks for the buff and performs those actions, with the destroy at the bottom.. I think this is correct? And don't worry about my second question.. I didn't know what I was talking about anyway. |
| 01-18-2008, 06:20 PM | #5 | |
Quote:
Oh, yes, sorry. I didn't see it :) |
