• 🏆 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] Struct Allocator

Status
Not open for further replies.
Level 29
Joined
Mar 10, 2009
Messages
5,016
I would like to request coders to test this, but before you do, I can say that this is tested and works
for me and I need more proof that it works for you;
if it does, which one is better?...

Allocator #1
JASS:
library Allocator

module Allocator
    private static integer index = 0
    private static integer recycle = 0
    private integer renew
        
    static method allocate takes nothing returns integer
        local thistype this   
        if recycle==0 then
            set index = index + 1
            set this = index
        else
            set this = recycle
            set recycle = renew
        endif    
        return this
    endmethod
    
    method deallocate takes nothing returns nothing
        set renew = recycle
        set recycle = this
    endmethod
endmodule

endlibrary
Allocator #2
JASS:
module Allocator
    static integer Allocator_instance = 0
    static integer Allocator_recycle = 0
    static integer array Allocator_instanceArray
    
    static method allocate takes nothing returns integer
        local thistype this = Allocator_recycle
        if (this==8191) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Allocator ERROR: Unable to allocate instance "+"["+I2S(this)+"]"+" anymore!")
            return 0
        else
            if this==0 then
                set Allocator_instance = Allocator_instance + 1
                set this = Allocator_instance
            else
                set Allocator_recycle = Allocator_instanceArray[this]
            endif
        endif
        return this
    endmethod

    method deallocate takes nothing returns nothing
        if Allocator_instance==0 then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Allocator ERROR: Instance is 0!")
            return
        endif
        set Allocator_instanceArray[this] = Allocator_recycle
        set Allocator_recycle = this
    endmethod
endmodule


TESTING:
JASS:
scope AllocatorDEMO

struct AllocatorDEMO extends array
    implement Allocator
    unit c
    real dur
    
    static integer instance = 0
    static integer array insAr
    static timer t = CreateTimer()    
    
    static method looper takes nothing returns nothing
        local thistype this
        local texttag tag
        local integer index = 0
        loop
            set index = index + 1
            set this = insAr[index]
            if .dur > 0 then
                set tag = CreateTextTag()
                call SetTextTagPosUnit(tag, .c, 0)
                call SetTextTagText(tag, R2S(.dur), 0.025)
                call SetTextTagPermanent(tag, false)
                call SetTextTagVelocity(tag, 0.03, 0.03)
                call SetTextTagLifespan(tag, 3)
                call SetTextTagFadepoint(tag, 0.01) 
                set tag = null
                set .dur = .dur - 1.0
            else
                call BJDebugMsg("DEALLOCATE")
                call KillUnit(.c)
                set .c = null
                call .deallocate()
                set insAr[index] = insAr[instance]
                set insAr[instance] = this
                set index = index - 1
                set instance = instance - 1
                if instance==0 then
                    call BJDebugMsg("PAUSED")
                    call PauseTimer(t)
                endif
            endif  
            exitwhen index==instance
        endloop
    endmethod

    static method run takes nothing returns nothing
        local thistype this = allocate()
        local rect ma = bj_mapInitialPlayableArea
        local real x = GetRandomReal(GetRectMinX(ma),GetRectMaxX(ma))
        local real y = GetRandomReal(GetRectMinY(ma),GetRectMaxY(ma))
        if instance==0 then
            call TimerStart(t,1.0,true,function thistype.looper)
        endif
        call BJDebugMsg(I2S(this))
        set instance = instance + 1
        set insAr[instance] = this
        set .c = CreateUnit(Player(0), 'hpea', x, y,0)
        set .dur = I2R(GetRandomInt(15,25))
        set ma = null
    endmethod    
    
    static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
        call TriggerAddAction(t,function thistype.run)    
    endmethod    
endstruct

endscope
 
Level 7
Joined
Jan 28, 2012
Messages
266
you are doing to much work on your deallocate, make the deallocate method deal with all of this
JASS:
set insAr[index] = insAr[instance]
                set insAr[instance] = this
                set index = index - 1
                set instance = instance - 1

that way you don't have to use it for every single trigger that you make.
my only other comment is that a linked list is faster(linked list, one array look up < yours with one math function(+) and then an array lookup)
 
Last edited:
Level 7
Joined
Jan 28, 2012
Messages
266
JASS:
 if (this==8191) then
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Allocator ERROR: Unable to allocate instance "+"["+I2S(this)+"]"+" anymore!")
     return 0
  else ....
why do you have this if in the second one, it makes no sense where it is currently placed, right now all it does it check to see if the recycled index is == to 8191, it doesn't check to see if you are allocating an index ab0ve 8190
now if you moved it here
JASS:
if this==0 then
                set Allocator_instance = Allocator_instance + 1
                set this = Allocator_instance
                if (this==8191) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Allocator ERROR: Unable to allocate instance "+"["+I2S(this)+"]"+" anymore!")
                    return 0
                endif
                set Allocator_recycle = Allocator_instanceArray[this]
            endif
then it would make some sense(will test your script later today)
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
your method runs 5 lines everytime, while mine runs 4, also it doesnt work coz running this set Allocator_recycle = Allocator_instanceArray[this] everytime without an else will have a double instance...
it's better to check first if it's not this==8191 then run the else part, if it's true it will skip everything by returning to 0...
'this' cannot pass 8191 coz it will return 0...
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Both are bad. You only need 2 variables for this. Try again ; ).
I dont really care if this is the worst system ever created in WC3 history...I just need proof that these things works for you and which one is faster...

PurgeandFire111 said:
But otherwise we'll just use the method in the second allocator...
Good to hear that if you test the system, thanks!...
 
Status
Not open for further replies.
Top