- Joined
- Mar 15, 2012
- Messages
- 2,885
I recently stumbled upon a problem with this auto mui system by Ruke where it eventually climbs past max array size... limit is set in the variable manager to 10 and instance is this part
The part that's bugging, it only continues to increase until it can no longer work past max array size.
Pretty sure the normal reply is not to use such a silly system but it has proven useful in lowering variable count and keeping stuff manageable with GUI triggers. Not sure how to add deindexing to this if that is the problem?
JASS:
local timer expiredTimer = GetExpiredTimer()
local integer expiredTimerId = GetHandleId(expiredTimer)
local integer instance = LoadInteger(udg_hashtable, expiredTimerId, 0)
call MUI_RecycleInstance(instance)
JASS:
function MUI_RecycleInstance takes integer instance returns nothing
set instance = instance / udg_limit
set udg_recycleNext[instance] = udg_recycle
set udg_recycle = instance
endfunction
JASS:
// allocator
// thanks nestharus/vexorian c:
function MUI_CreateInstance takes nothing returns integer
local integer instance
if ( udg_recycle == 0 ) then
set udg_instanceCount = udg_instanceCount + 1
set instance = udg_instanceCount
else
set instance = udg_recycle
set udg_recycle = udg_recycleNext[udg_recycle]
endif
// reserving space
set instance = instance * udg_limit
return instance
endfunction
// deallocator
// thanks nestharus/vexorian c:
function MUI_RecycleInstance takes integer instance returns nothing
set instance = instance / udg_limit
set udg_recycleNext[instance] = udg_recycle
set udg_recycle = instance
endfunction
function MUI_ShowOverLimitError takes nothing returns nothing
call BJDebugMsg("No puedes guardar mas de " + I2S(udg_limit) + ". Si necesitas mas, modifica la variable limit.\nYou can't save more than " + I2S(udg_limit) + ". If you need more, modify the variable called 'limit'")
endfunction
// private
function MUI_SaveUnits takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_unit[instance + i] = udg_set_unit[i]
set udg_set_unit[i] = null
exitwhen i == udg_used_units
set i = i + 1
endloop
set udg_mui_used_units[instance] = udg_used_units
endfunction
// private
function MUI_SaveReals takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_real[instance + i] = udg_set_real[i]
set udg_set_real[i] = 0.
exitwhen i == udg_used_reals
set i = i + 1
endloop
set udg_mui_used_reals[instance] = udg_used_reals
endfunction
// private
function MUI_SavePlayers takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_player[instance + i] = udg_set_player[i]
set udg_set_player[i] = null
exitwhen i == udg_used_players
set i = i + 1
endloop
set udg_mui_used_players[instance] = udg_used_players
endfunction
// private
function MUI_SavePoints takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_point[instance + i] = udg_set_point[i]
set udg_set_point[i] = null
exitwhen i == udg_used_points
set i = i + 1
endloop
set udg_mui_used_points[instance] = udg_used_points
endfunction
// private
function MUI_SaveEffects takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_effect[instance + i] = udg_set_effect[i]
set udg_set_effect[i] = null
exitwhen i == udg_used_effects
set i = i + 1
endloop
set udg_mui_used_effects[instance] = udg_used_effects
endfunction
// private
function MUI_SaveIntegers takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_integer[instance + i] = udg_set_integer[i]
set udg_set_integer[i] = 0
exitwhen i == udg_used_integers
set i = i + 1
endloop
set udg_mui_used_integers[instance] = udg_used_integers
endfunction
// private
function MUI_SaveUnitGroups takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_group[instance + i] = udg_set_group[i]
set udg_set_group[i] = null
exitwhen i == udg_used_groups
set i = i + 1
endloop
set udg_mui_used_groups[instance] = udg_used_groups
endfunction
// private
function MUI_SaveBooleans takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_boolean[instance + i] = udg_set_boolean[i]
set udg_set_boolean[i] = false
exitwhen i == udg_used_booleans
set i = i + 1
endloop
set udg_mui_used_booleans[instance] = udg_used_booleans
endfunction
// private
function MUI_SaveDestructibles takes integer instance returns nothing
local integer i = 1
loop
set udg_mui_destructible[instance + i] = udg_set_destructible[i]
set udg_set_destructible[i] = null
exitwhen i == udg_used_destructibles
set i = i + 1
endloop
set udg_mui_used_destructibles[instance] = udg_used_destructibles
endfunction
// private
function MUI_Periodic takes nothing returns nothing
local timer expiredTimer = GetExpiredTimer()
local integer expiredTimerId = GetHandleId(expiredTimer)
local integer instance = LoadInteger(udg_hashtable, expiredTimerId, 0)
local integer i
// avoid recursion problems
local unit array prevGetUnit
local real array prevGetReal
local player array prevGetPlayer
local location array prevGetPoint
local effect array prevGetEffect
local integer array prevGetInteger
local group array prevGetGroup
local boolean array prevGetBoolean
local destructable array prevGetDestructible
local boolean prevAutomaticClean = udg_automaticClean
local boolean prevFinish = udg_finish
// unit
if ( udg_mui_used_units[instance] > 0 ) then
set i = 1
loop
set prevGetUnit[i] = udg_get_unit[i]
set udg_get_unit[i] = udg_mui_unit[instance + i]
exitwhen i == udg_mui_used_units[instance]
set i = i + 1
endloop
endif
// real
if ( udg_mui_used_reals[instance] > 0 ) then
set i = 1
loop
set prevGetReal[i] = udg_get_real[i]
set udg_get_real[i] = udg_mui_real[instance + i]
exitwhen i == udg_mui_used_reals[instance]
set i = i + 1
endloop
endif
// player
if ( udg_mui_used_players[instance] > 0 ) then
set i = 1
loop
set prevGetPlayer[i] = udg_get_player[i]
set udg_get_player[i] = udg_mui_player[instance + i]
exitwhen i == udg_mui_used_players[instance]
set i = i + 1
endloop
endif
// location
if ( udg_mui_used_points[instance] > 0 ) then
set i = 1
loop
set prevGetPoint[i] = udg_get_point[i]
set udg_get_point[i] = udg_mui_point[instance + i]
exitwhen i == udg_mui_used_points[instance]
set i = i + 1
endloop
endif
// effect
if ( udg_mui_used_effects[instance] > 0 ) then
set i = 1
loop
set prevGetEffect[i] = udg_get_effect[i]
set udg_get_effect[i] = udg_mui_effect[instance + i]
exitwhen i == udg_mui_used_effects[instance]
set i = i + 1
endloop
endif
// integer
if ( udg_mui_used_integers[instance] > 0 ) then
set i = 1
loop
set prevGetInteger[i] = udg_get_integer[i]
set udg_get_integer[i] = udg_mui_integer[instance + i]
exitwhen i == udg_mui_used_integers[instance]
set i = i + 1
endloop
endif
// group
if ( udg_mui_used_groups[instance] > 0 ) then
set i = 1
loop
set prevGetGroup[i] = udg_get_group[i]
set udg_get_group[i] = udg_mui_group[instance + i]
exitwhen i == udg_mui_used_groups[instance]
set i = i + 1
endloop
endif
// boolean
if ( udg_mui_used_booleans[instance] > 0 ) then
set i = 1
loop
set prevGetBoolean[i] = udg_get_boolean[i]
set udg_get_boolean[i] = udg_mui_boolean[instance + i]
exitwhen i == udg_mui_used_booleans[instance]
set i = i + 1
endloop
endif
// destructible
if ( udg_mui_used_destructibles[instance] > 0 ) then
set i = 1
loop
set prevGetDestructible[i] = udg_get_destructible[i]
set udg_get_destructible[i] = udg_mui_destructible[instance + i]
exitwhen i == udg_mui_used_destructibles[instance]
set i = i + 1
endloop
endif
call TriggerExecute(LoadTriggerHandle(udg_hashtable, expiredTimerId, 1))
// unit
if ( udg_mui_used_units[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
set udg_mui_unit[instance + i] = null
else
set udg_mui_unit[instance + i] = udg_get_unit[i]
endif
set udg_get_unit[i] = prevGetUnit[i]
set prevGetUnit[i] = null
exitwhen i == udg_mui_used_units[instance]
set i = i + 1
endloop
endif
// real
if ( udg_mui_used_reals[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
set udg_mui_real[instance + i] = 0.
else
set udg_mui_real[instance + i] = udg_get_real[i]
endif
set udg_get_real[i] = prevGetReal[i]
exitwhen i == udg_mui_used_reals[instance]
set i = i + 1
endloop
endif
// player
if ( udg_mui_used_players[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
set udg_mui_player[instance + i] = null
else
set udg_mui_player[instance + i] = udg_get_player[i]
endif
set udg_get_player[i] = prevGetPlayer[i]
set prevGetPlayer[i] = null
exitwhen i == udg_mui_used_players[instance]
set i = i + 1
endloop
endif
// location
if ( udg_mui_used_points[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
if ( udg_automaticClean ) then
call RemoveLocation(udg_mui_point[instance + i])
call RemoveLocation(udg_get_point[i])
endif
set udg_mui_point[instance + i] = null
else
if ( udg_mui_point[instance + i] != udg_get_point[i] ) then
call RemoveLocation(udg_mui_point[instance + i])
set udg_mui_point[instance + i] = udg_get_point[i]
endif
endif
set udg_get_point[i] = prevGetPoint[i]
set prevGetPoint[i] = null
exitwhen i == udg_mui_used_points[instance]
set i = i + 1
endloop
endif
// effect
if ( udg_mui_used_effects[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
if ( udg_automaticClean ) then
call DestroyEffect(udg_mui_effect[instance + i])
call DestroyEffect(udg_get_effect[i])
endif
set udg_mui_effect[instance + i] = null
else
if ( udg_mui_effect[instance + i] != udg_get_effect[i] ) then
call DestroyEffect(udg_mui_effect[instance + i])
set udg_mui_effect[instance + i] = udg_get_effect[i]
endif
endif
set udg_get_effect[i] = prevGetEffect[i]
set prevGetEffect[i] = null
exitwhen i == udg_mui_used_effects[instance]
set i = i + 1
endloop
endif
// integer
if ( udg_mui_used_integers[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
set udg_mui_integer[instance + i] = 0
else
set udg_mui_integer[instance + i] = udg_get_integer[i]
endif
set udg_get_integer[i] = prevGetInteger[i]
exitwhen i == udg_mui_used_integers[instance]
set i = i + 1
endloop
endif
// groups
if ( udg_mui_used_groups[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
if ( udg_automaticClean ) then
call DestroyGroup(udg_mui_group[instance + i])
call DestroyGroup(udg_get_group[i])
endif
set udg_mui_group[instance + i] = null
else
if ( udg_mui_group[instance + i] != udg_get_group[i] ) then
call DestroyGroup(udg_mui_group[instance + i])
set udg_mui_group[instance + i] = udg_get_group[i]
endif
endif
set udg_get_group[i] = prevGetGroup[i]
set prevGetGroup[i] = null
exitwhen i == udg_mui_used_groups[instance]
set i = i + 1
endloop
endif
// boolean
if ( udg_mui_used_booleans[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
set udg_mui_boolean[instance + i] = false
else
set udg_mui_boolean[instance + i] = udg_get_boolean[i]
endif
set udg_get_boolean[i] = prevGetBoolean[i]
exitwhen i == udg_mui_used_booleans[instance]
set i = i + 1
endloop
endif
// destructible
if ( udg_mui_used_destructibles[instance] > 0 ) then
set i = 1
loop
if ( udg_finish ) then
if ( udg_automaticClean ) then
call RemoveDestructable(udg_mui_destructible[instance + i])
call RemoveDestructable(udg_get_destructible[instance + i])
endif
set udg_mui_destructible[instance + i] = null
else
set udg_mui_destructible[instance + i] = udg_get_destructible[i]
endif
set udg_get_destructible[i] = prevGetDestructible[i]
exitwhen i == udg_mui_used_destructibles[instance]
set i = i + 1
endloop
endif
if ( udg_finish ) then
set udg_mui_used_units[instance] = 0
set udg_mui_used_reals[instance] = 0
set udg_mui_used_players[instance] = 0
set udg_mui_used_points[instance] = 0
set udg_mui_used_effects[instance] = 0
set udg_mui_used_integers[instance] = 0
set udg_mui_used_groups[instance] = 0
set udg_mui_used_booleans[instance] = 0
set udg_mui_used_destructibles[instance] = 0
call MUI_RecycleInstance(instance)
call FlushChildHashtable(udg_hashtable, expiredTimerId)
call PauseTimer(expiredTimer)
call DestroyTimer(expiredTimer)
endif
set udg_automaticClean = prevAutomaticClean
set udg_finish = prevFinish
set expiredTimer = null
endfunction
// private
function MUI_OnTimeoutChange takes nothing returns nothing
local timer periodicTimer = CreateTimer()
local integer instance = MUI_CreateInstance()
// units
if ( udg_used_units > 0 ) then
if ( udg_used_units > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveUnits(instance)
set udg_used_units = 0
endif
endif
// reals
if ( udg_used_reals > 0 ) then
if ( udg_used_reals > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveReals(instance)
set udg_used_reals = 0
endif
endif
// players
if ( udg_used_players > 0 ) then
if ( udg_used_players > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SavePlayers(instance)
set udg_used_players = 0
endif
endif
// points
if ( udg_used_points > 0 ) then
if ( udg_used_points > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SavePoints(instance)
set udg_used_points = 0
endif
endif
// effects
if ( udg_used_effects > 0 ) then
if ( udg_used_effects > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveEffects(instance)
set udg_used_effects = 0
endif
endif
// integers
if ( udg_used_integers > 0 ) then
if ( udg_used_integers > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveIntegers(instance)
set udg_used_integers = 0
endif
endif
// groups
if ( udg_used_groups > 0 ) then
if ( udg_used_groups > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveUnitGroups(instance)
set udg_used_groups = 0
endif
endif
// boolean
if ( udg_used_booleans > 0 ) then
if ( udg_used_booleans > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveBooleans(instance)
set udg_used_booleans = 0
endif
endif
// destructibles
if ( udg_used_destructibles > 0 ) then
if ( udg_used_destructibles > udg_limit ) then
call MUI_ShowOverLimitError()
else
call MUI_SaveDestructibles(instance)
set udg_used_destructibles = 0
endif
endif
call SaveInteger(udg_hashtable, GetHandleId(periodicTimer), 0, instance)
call SaveTriggerHandle(udg_hashtable, GetHandleId(periodicTimer), 1, udg_trigger)
call TimerStart(periodicTimer, udg_timeout, true, function MUI_Periodic)
set udg_timeout = 0.
set udg_trigger = null
set periodicTimer = null
endfunction
// initializer
function InitTrig_MUI takes nothing returns nothing
set gg_trg_MUI = CreateTrigger()
set udg_hashtable = InitHashtable()
call TriggerRegisterVariableEvent(gg_trg_MUI, "udg_timeout", GREATER_THAN, 0)
call TriggerAddAction(gg_trg_MUI, function MUI_OnTimeoutChange)
endfunction
Pretty sure the normal reply is not to use such a silly system but it has proven useful in lowering variable count and keeping stuff manageable with GUI triggers. Not sure how to add deindexing to this if that is the problem?