- 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: