• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Failing to deallocate

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Hello. I am currently creating a rebirth system. It's supposed to create a unit when a unit dies, and if this new unit is still alive after X seconds the old unit is respawned.

However, my struct fails to deallocate somehow. The message "sss" is displayed but shit keeps updating.


JASS:
struct List
    integer size = 0
    integer array data [99]
    
    public static method create takes nothing returns List
        local thistype this = thistype.allocate()
        return this
    endmethod
    
    public method Add takes integer i returns nothing
        set data[size] = i
        set size = size + 1
    endmethod
    
    public method Remove takes integer id returns nothing
        local integer i = 0
        local integer j = 0
        loop
            exitwhen i >= size
            if data[i] == id then
                loop
                    exitwhen j >= size
                    set data[j] = data[j + 1]
                    set j = j + 1
                endloop
            set size = size - 1
            set i = size + 1 
            endif
            set i = i + 1
        endloop
    endmethod
endstruct


JASS:
globals
	List instances
	integer debugCounter = 0
endglobals

struct Rebirth
	static constant integer DUMMY_TYPE = 'h000'
	static constant real DUMMY_DURATION = 5
	
	integer u
	unit deadUnit
	location l
	real counter
	unit egg
	
	static method onInit takes nothing returns nothing
		set instances = List.create()
	endmethod
	
	static method create takes unit u returns thistype
		local thistype this = thistype.allocate()
		set this.u = GetUnitTypeId(u)
		set this.counter = 0
		set this.deadUnit = u
		set this.l = GetUnitLoc(u)
		set this.egg = CreateUnitAtLoc(GetOwningPlayer(u), DUMMY_TYPE, this.l, 0)
		call instances.Add(this)
		return this
	endmethod
	
	method destroy takes nothing returns nothing
		set this.u = 0
		call RemoveLocation(this.l)
		call instances.Remove(this)
		call this.deallocate()
		call deallocate(this)
		call BJDebugMsg("sss")
	endmethod
	
	method Update takes nothing returns nothing
		set debugCounter = debugCounter + 1
		call BJDebugMsg("Instance: " + I2S(this) + " is being updated!" + "    " + I2S(debugCounter) + "      " + R2S(this.counter))
		set this.counter = this.counter + 0.03
		if this.counter > DUMMY_DURATION then
			call KillUnit(this.egg)
			if IsUnitIdType(this.u, UNIT_TYPE_HERO) == false then
				call CreateUnitAtLoc(Player(0), this.u, this.l, 0)
				call this.destroy()
				call BJDebugMsg("finish1")
			else
				call ReviveHeroLoc(this.deadUnit, this.l, false)
				call this.destroy()
				call BJDebugMsg("finish2")
			endif
		endif
	endmethod
endstruct
  • update
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Custom script: local integer i = instances.size
      • Custom script: loop
      • Custom script: exitwhen i == 0
      • Custom script: call Rebirth( instances.data[i]).Update()
      • Custom script: set i = i - 1
      • Custom script: endloop
 

Attachments

  • rebirth.w3x
    19.8 KB · Views: 67
Level 23
Joined
Apr 16, 2012
Messages
4,041
Whats the call to deallocate(this)?

Are the instances in the list required to be placed in strict order?

You never initialize j in the Remove, so basically it runs from 0 to (size - 1) and basically it only removes the first thing in the list
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
1. I don't really understand the question, I added both the deallocate methods to make sure it was removed properly. But it didn't work.

2. Nope.

3. Oh. I added set j = 0 after the inner loop is finished. That's what you mean right?
JASS:
   public method Remove takes integer id returns nothing
        local integer i = 0
        local integer j = 0
        loop
            exitwhen i >= size
            if data[i] == id then
                loop
                    exitwhen j >= size
                    set data[j] = data[j + 1]
                    set j = j + 1
                endloop
            set size = size - 1
			set j = 0
            set i = size + 1 
            endif
            set i = i + 1
        endloop
    endmethod
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
I'm assuming he means initializing j to i's value before starting the second loop since I'm also assuming that the second loop performs a reordering on the list.

Anyway, could you explain what the loops are doing? Thanks.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Try setting j to i before the second loop:

JASS:
   public method Remove takes integer id returns nothing
        local integer i = 0
        local integer j = 0
        loop
            exitwhen i >= size
            if data[i] == id then
            @set j=i@
                loop
                    exitwhen j >= size
                    set data[j] = data[j + 1]
                    set j = j + 1
                endloop
            set size = size - 1
            set j = 0
            set i = size + 1
            endif
            set i = i + 1
        endloop
    endmethod
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Thanks. It seemed to make the bug come less consistantly.. I applied the rebirth to 6 units and 5 of them got revived properly. Before it was like 2-3 out of 6.

This is the current messages being shown:
8dd94e1d339df73a193a024e7299f3a4.png


As you see the timer is at 11 seconds, and it should've been gone after 5 seconds.
Pretty odd, it's always instance 0.
 
Last edited:
Level 22
Joined
Sep 24, 2005
Messages
4,821
the trigger Update was updating the wrong index, remember you store struct pointers in array index size-1?

JASS:
    public method Add takes integer i returns nothing
        set data[size] = i // <-see
        set size = size + 1 // data[size]'s data is invalid at this point.
    endmethod

a quick fix would be:
  • update
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Custom script: local integer i = instances.size
      • Custom script: loop
      • Custom script: exitwhen i == 0
      • Custom script: set i = i - 1
      • Custom script: call Rebirth( instances.data[i]).Update()
      • Custom script: endloop
 
Status
Not open for further replies.
Top