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

somewhat accurate max-handle-id counter

Status
Not open for further replies.
Level 13
Joined
Nov 7, 2014
Messages
571
This is a method of detecting if one is leaking a lot of handles (the max-handle-id goes up and up and up, forever).

JASS:
library MaxHandleId

globals
    private hashtable ht = InitHashtable()
    private fogstate fs = null
    private location h_location = null
    private group h_group = null
    private force h_force = null
    private effect h_effect = null
    private unit h_unit = null
    private item h_item = null
    private destructable h_destructable = null
    private widget h_widget = null
    private trigger h_trigger = null
    private event h_event = null
    private triggercondition h_triggercondition = null
    private triggeraction h_triggeraction = null
    private boolexpr h_boolexpr = null
    private rect h_rect = null
    private region h_region = null
    private timer h_timer = null
    private timerdialog h_timerdialog = null
    private dialog h_dialog = null
    private button h_button = null
    private leaderboard h_leaderboard = null
    private multiboard h_multiboard = null
    private multiboarditem h_multiboarditem = null
    private sound h_sound = null
    private fogmodifier h_fogmodifier = null
    private trackable h_trackable = null
    private quest h_quest = null
    private questitem h_questitem = null
    private defeatcondition h_defeatcondition = null
    private hashtable h_hashtable = null

endglobals

//! textmacro INTEGER_TO_HANDLE_CAST takes T, F
private function int_as_$T$ takes integer i returns $T$
    call SaveFogStateHandle(ht, 0, 0, ConvertFogState(i))
    set h_$T$ = Load$F$Handle(ht, 0, 0)
    call RemoveSavedHandle(ht, 0, 0)
    return h_$T$
endfunction
//! endtextmacro

//! runtextmacro INTEGER_TO_HANDLE_CAST("location", "Location")
//! runtextmacro INTEGER_TO_HANDLE_CAST("group", "Group")
//! runtextmacro INTEGER_TO_HANDLE_CAST("force", "Force")
//! runtextmacro INTEGER_TO_HANDLE_CAST("effect", "Effect")
//! runtextmacro INTEGER_TO_HANDLE_CAST("unit", "Unit")
//! runtextmacro INTEGER_TO_HANDLE_CAST("item", "Item")
//! runtextmacro INTEGER_TO_HANDLE_CAST("destructable", "Destructable")
//! runtextmacro INTEGER_TO_HANDLE_CAST("widget", "Widget")
//! runtextmacro INTEGER_TO_HANDLE_CAST("trigger", "Trigger")
//! runtextmacro INTEGER_TO_HANDLE_CAST("event", "TriggerEvent")
//! runtextmacro INTEGER_TO_HANDLE_CAST("triggercondition", "TriggerCondition")
//! runtextmacro INTEGER_TO_HANDLE_CAST("triggeraction", "TriggerAction")
//! runtextmacro INTEGER_TO_HANDLE_CAST("boolexpr", "BooleanExpr")
//! runtextmacro INTEGER_TO_HANDLE_CAST("rect", "Rect")
//! runtextmacro INTEGER_TO_HANDLE_CAST("region", "Region")
//! runtextmacro INTEGER_TO_HANDLE_CAST("timer", "Timer")
//! runtextmacro INTEGER_TO_HANDLE_CAST("timerdialog", "TimerDialog")
//! runtextmacro INTEGER_TO_HANDLE_CAST("dialog", "Dialog")
//! runtextmacro INTEGER_TO_HANDLE_CAST("button", "Button")
//! runtextmacro INTEGER_TO_HANDLE_CAST("leaderboard", "Leaderboard")
//! runtextmacro INTEGER_TO_HANDLE_CAST("multiboard", "Multiboard")
//! runtextmacro INTEGER_TO_HANDLE_CAST("multiboarditem", "MultiboardItem")
//! runtextmacro INTEGER_TO_HANDLE_CAST("sound", "Sound")
// //! runtextmacro INTEGER_TO_HANDLE_CAST("camerasetup", "CameraSetup") // doesn't exist
//! runtextmacro INTEGER_TO_HANDLE_CAST("fogmodifier", "FogModifier")
//! runtextmacro INTEGER_TO_HANDLE_CAST("trackable", "Trackable")
//! runtextmacro INTEGER_TO_HANDLE_CAST("quest", "Quest")
//! runtextmacro INTEGER_TO_HANDLE_CAST("questitem", "QuestItem")
//! runtextmacro INTEGER_TO_HANDLE_CAST("defeatcondition", "DefeatCondition")
// //! runtextmacro INTEGER_TO_HANDLE_CAST("gamecache", "GameCache") // doesn't exist
//! runtextmacro INTEGER_TO_HANDLE_CAST("hashtable", "Hashtable")

struct MaxHandleId extends array

static method compute takes nothing returns integer
    local location array locs
    local integer locs_count
    local location loc
    local integer next
    local boolean done
    local integer result

    // we need to pop items (handle-ids) from the free list/stack that is used by the game for reusing handle-ids
    // we do this by creating location handles and testing if the next handle-id is "used"
    // when we detect that it's not used it means we've created the handle with the max-handle-id
    //
    set locs_count = 0
    loop
        set loc = Location(0.0, 0.0)
        set next = GetHandleId(loc) + 1

        set done = true

        if int_as_location(next) != null then
            set h_location = null
            set done = false

        elseif int_as_group(next) != null then
            set h_group = null
            set done = false

        elseif int_as_force(next) != null then
            set h_force = null
            set done = false

        elseif int_as_effect(next) != null then
            set h_effect = null
            set done = false

        elseif int_as_unit(next) != null then
            set h_unit = null
            set done = false

        elseif int_as_item(next) != null then
            set h_item = null
            set done = false

        elseif int_as_destructable(next) != null then
            set h_destructable = null
            set done = false

        elseif int_as_widget(next) != null then
            set h_widget = null
            set done = false

        elseif int_as_trigger(next) != null then
            set h_trigger = null
            set done = false

       elseif int_as_event(next) != null then
            set h_event = null
            set done = false

       elseif int_as_triggercondition(next) != null then
            set h_triggercondition = null
            set done = false

       elseif int_as_triggeraction(next) != null then
            set h_triggeraction = null
            set done = false

       elseif int_as_boolexpr(next) != null then
            set h_boolexpr = null
            set done = false

       elseif int_as_rect(next) != null then
            set h_rect = null
            set done = false

       elseif int_as_region(next) != null then
            set h_region = null
            set done = false

       elseif int_as_timer(next) != null then
            set h_timer = null
            set done = false

       elseif int_as_timerdialog(next) != null then
            set h_timerdialog = null
            set done = false

       elseif int_as_dialog(next) != null then
            set h_dialog = null
            set done = false

       elseif int_as_button(next) != null then
            set h_button = null
            set done = false

       elseif int_as_leaderboard(next) != null then
            set h_leaderboard = null
            set done = false

       elseif int_as_multiboard(next) != null then
            set h_multiboard = null
            set done = false

       elseif int_as_multiboarditem(next) != null then
            set h_multiboarditem = null
            set done = false

       elseif int_as_sound(next) != null then
            set h_sound = null
            set done = false

        elseif int_as_fogmodifier(next) != null then
            set h_fogmodifier = null
            set done = false

        elseif int_as_trackable(next) != null then
            set h_trackable = null
            set done = false

        elseif int_as_quest(next) != null then
            set h_quest = null
            set done = false

        elseif int_as_questitem(next) != null then
            set h_questitem = null
            set done = false

        elseif int_as_defeatcondition(next) != null then
            set h_defeatcondition = null
            set done = false

        elseif int_as_hashtable(next) != null then
            set h_hashtable = null
            set done = false

        endif

        if not done then
            set locs_count = locs_count + 1
            set locs[locs_count] = loc

        else
            // it seems we can't compute the handles-count with this algorithm because
            // when we luckily hit the max-id-handle we stop there and not consider the
            // other items of the free list
            // we need a way to detect when the free list has been drained and a new handle-id
            // was allocated, but is that possible?
            //
            // set result = next - 1 - locs_count - 0x00100000 // hadles-count

            set result = next - 1 - 0x00100000 // maxi-handle-id

            loop
                exitwhen locs_count <= 0
                call RemoveLocation(locs[locs_count])
                set locs[locs_count] = null
                set locs_count = locs_count - 1
            endloop

            call RemoveLocation(loc)
            set loc = null

            return result
        endif
    endloop

    // unreachable
    return 0
endmethod

endstruct

endlibrary
 
Last edited:
Status
Not open for further replies.
Top