• 🏆 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!

[JASS] 'unallocate' a struct instance?

Status
Not open for further replies.
Level 3
Joined
Sep 11, 2008
Messages
58
i have a function that checks an array of struct-instances if the value of an instance is 0 (yes, the value of the instance itself, not of a member). The purpose of that function is to find free indexes in that array. But after i allocated the instances within that array i'm not able to reset the instances values to 0 - destroying the instance doesn't reset it. Is there a way to 'unallocate' it?

For better understanding below the code:

JASS:
        private static method get_free_index takes nothing returns integer
            local integer i
            
            set i = 0
            loop
                exitwhen i == s_traveler.sTravelers.size
                if s_traveler.sTravelers[i] == 0 then
                    return i
                endif
                set i = i + 1
            endloop
            return 999999 //no free index in sTravelers sized array
        endmethod

Thanks for any answers.
whisp
 
Level 3
Joined
Sep 11, 2008
Messages
58
Dr Super Good, this works, thanks!

Captain, you answered a completely different question! ;)
 
Level 3
Joined
Sep 11, 2008
Messages
58
but destroy doesn't unallocate it, the variable keeps the by .allocate() allocated identifier...
 
Level 14
Joined
Nov 20, 2005
Messages
1,156
Structs behave just like pseudohandles in this respect, I believe. IE: They recycle the index even if there are still references to it.

Yeah, there's a BIG difference between setting a reference to null and deallocating... Most likely setting a reference to null will fuck up a lot of stuff.

Setting a struct reference to null (0) without destroying it first may lead to struct leaks...which will eventually cause it to go boom.
 
Level 3
Joined
Sep 11, 2008
Messages
58
Concerning to that sentence
You can override the static method create by declaring your own one, once you do it, you might require another method just to allocate a unique id for the struct, this is the allocate() static method which is added by default to all structs, it is a private method. When a struct does not have an specific create method declared, jasshelper will use allocate directly when .create is called.
from JassHelper i assume that allocate does only assign that identifier and nothing else. Or am i wrong?

And the following code proofs, that destroy doesn't set that identifiers back to 0...

JASS:
globals
    s_test glb_test
endglobals

struct s_test
    integer test
    
    static method onInit takes nothing returns nothing
        local s_test t1
        local s_test t2
        
        set glb_test = s_test.create()
        
            set t1 = glb_test
            set t2 = glb_test
            call glb_test.destroy()
            set t1 = 0
            
            call BJDebugMsg("t1: " + I2S(t1))
            call BJDebugMsg("t2: " + I2S(t2))
            call BJDebugMsg("glb_test: " + I2S(glb_test))        
    endmethod
endstruct

Chat text output:

t1: 0
t2: 1
glb_test: 1

Btw, i don't plan to set any instances to 0 before they're destroyed. The use of my function (in post 1) is just to find an instance (in an array) that isn't created respectively already destroyed. So after destroying an instance i can reuse that 'hole' in the array instead of reaching the arrays limit sometime.
 
Level 3
Joined
Sep 11, 2008
Messages
58
Is it possible that destroy is running in a separate thread?

JASS:
        static method reset takes s_traveler trv returns nothing
            local integer sTIdx           
            
            set sTIdx = s_traveler.get_sTravelers_idx_by_traveler(trv)   
            call trv.destroy()
            set s_traveler.sTravelers[sTIdx] = 0
        endmethod

In the upper function i destroy an instance and afterwards i set the reference within an array of this instances to 0. Afterwards. But sometimes it happens, that i get the 0-struct-destroy-message anyways (in debug mode). Which makes me beliefe that the destroy method is running in a separate thread and thus sometimes isn't finished before i set the identifier to 0. Is this possible or did i mess up somewhere else?

So much concerning "i don't plan to set any instances to 0 before they're destroyed" ... ;)
 
Level 3
Joined
Sep 11, 2008
Messages
58
Probably i misunderstand your question, but possibly you'll find the answer in post 1.

It's to decide which is the first free index in that array. The struct keeps track of its instances by putting them into a static array.
 
Level 3
Joined
Sep 11, 2008
Messages
58
I'm newbie, it's the way i though i will try to do it. ;) There's one instance destroyed every 5 seconds in average, from a planned maximum total of 50 instances. But if there are better ways i'd be glad to use them of course. What would be a proper allocation algorithm?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
For example, the one that vJass uses.

JASS:
globals
    integer currentFree = 0
    integer max = 0
    integer array last
endglobals

function Allocate takes nothing returns integer
    local integer new = currentFree
    if new == 0 then
        set max = max + 1
        set new = max
    else
        set currentFree = last[currentFree]
    endif
    set last[new] = -1
    return new
endfunction

function Deallocate takes index old returns nothing
    set last[old] = currentFree
    set currentFree = old
endfunction
 
Level 6
Joined
Sep 5, 2007
Messages
264
Could you just use a boolean array that uses the same indexes?

When an instance is created it sets that index to true, on destruction it sets it to false. Then you just gotta find the first "false" in the list and you've got your free index...
 
Level 3
Joined
Sep 11, 2008
Messages
58
Beside i thought it would be more elegant to use that existing variable, instead of adding another administrative variable to my instances.

This vJass allocation algorythm is very tricky. I would never ever find to this algorythm by myself. I will implement it for my array. The advantage of the O(n) algorythm relative to the vJass algorythm would be, that it probably is a little faster when using very little instances at once. And it could store 8191 instead of 8190 values! ;)

Thanks!
 
Status
Not open for further replies.
Top