// ===================================== //
// Start Allocator Core //
// ===================================== //
// ===================================== //
// Start Allocator Main //
// ===================================== //
function AllocMain_deallocate takes integer mainKey returns nothing
// Since it's possible for a wrong type of debug message to be printed.
if mainKey <= 0 then
if udg_Allocator_DEBUG_MODE then
if mainKey == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Main__deallocate:|r Null-pointer exception! [Key specified is 0].")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Main__deallocate:|r Invalid-pointer exception! [Key {" + I2S(mainKey) + "} specified is less than 0].")
endif
endif
return
elseif HaveSavedInteger(udg_Allocator_HASH, 0, mainKey) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Main__deallocate:|r Double-free procedure detected! {Index " + I2S(mainKey) + "}")
endif
return
endif
// Clear out the contents of the mainKey first
call FlushChildHashtable(udg_Allocator_HASH, mainKey)
// Standard deallocation procedure. (Store reference as pointed by 0 in deallocated index and let 0 point to the index.
// From 0 -> 3 to (0 -> 2 -> 3), to (0 -> 3 -> 2 -> 3) [3 is deindex, and has been recently deallocated]
call SaveInteger(udg_Allocator_HASH, 0, mainKey, LoadInteger(udg_Allocator_HASH, 0, 0))
call SaveInteger(udg_Allocator_HASH, 0, 0, mainKey)
endfunction
function AllocMain_allocate takes nothing returns integer
local integer constantValue = 2147483647
set udg_Allocator_NewKey = LoadInteger(udg_Allocator_HASH, 0, 0)
if LoadInteger(udg_Allocator_HASH, 0, udg_Allocator_NewKey) == 0 then
set udg_Allocator_NewKey = udg_Allocator_NewKey + 1
call SaveInteger(udg_Allocator_HASH, 0, 0, udg_Allocator_NewKey)
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cff00ff00Allocator_Main__allocate:|r Retrieved a new key {" + I2S(udg_Allocator_NewKey) + "}")
endif
else
call SaveInteger(udg_Allocator_HASH, 0, 0, LoadInteger(udg_Allocator_HASH, 0, udg_Allocator_NewKey))
call RemoveSavedInteger(udg_Allocator_HASH, 0, udg_Allocator_NewKey)
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffffcc00Allocator_Main__allocate:|r Retrieved a recycled key {" + I2S(udg_Allocator_NewKey) + "}")
endif
endif
call SaveInteger(udg_Allocator_HASH, udg_Allocator_NewKey, -2, udg_Allocator_MaxInstances)
set udg_Allocator_MaxInstances = 2147483647
return udg_Allocator_NewKey
endfunction
// ===================================== //
// End Allocator Main //
// ===================================== //
// ===================================== //
// Start Allocator Engine //
// ===================================== //
// Added via _Guhun_'s request.
function GetKeySize takes integer mainKey returns integer
if udg_Allocator_DEBUG_MODE then
if not HaveSavedInteger(udg_Allocator_HASH, mainKey, -1) then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {GetKeySize} Invalid-pointer exception!")
return 0
elseif mainKey == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {GetKeySize} null-pointer exception!")
return 0
endif
endif
return LoadInteger(udg_Allocator_HASH, mainKey, -1)
endfunction
function SizeOfKey takes integer mainKey returns integer
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {SizeOfKey} This function is deprecated. Use SizeOfKey instead.")
endif
return GetKeySize(mainKey)
endfunction
function GetKeyBounds takes integer mainKey returns integer
if not HaveSavedInteger(udg_Allocator_HASH, mainKey, -2) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {GetKeyBounds} Invalid-pointer exception!")
endif
return 0
elseif mainKey == 0 then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {GetKeyBounds} null-pointer exception!")
endif
return 0
endif
return LoadInteger(udg_Allocator_HASH, mainKey, -2)
endfunction
function SetKeyBounds takes integer mainKey, integer newSize returns nothing
if not HaveSavedInteger(udg_Allocator_HASH, mainKey, -2) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {SetKeyBounds} Invalid-pointer exception!")
endif
return
elseif mainKey == 0 then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {SetKeyBounds} null-pointer exception!")
endif
return
elseif newSize < LoadInteger(udg_Allocator_HASH, mainKey, -2) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {SetKeyBounds} Reducing instance size might have some unintended consequences.")
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine: {SetKeyBounds} Are you sure?")
endif
endif
call SaveInteger(udg_Allocator_HASH, mainKey, -2, newSize)
endfunction
function IsInstanceAllocated takes integer mainKey, integer index returns boolean
set udg_Allocator_isAllocated = (HaveSavedInteger(udg_Allocator_HASH, mainKey, index) and LoadInteger(udg_Allocator_HASH, mainKey, index) == 0)
return udg_Allocator_isAllocated
endfunction
// Deallocates an instance.
function AllocEngine_deallocate takes integer mainKey, integer deindex returns nothing
// Check if instance is within bounds.
if deindex <= 0 then
if udg_Allocator_DEBUG_MODE then
if deindex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__deallocate:|r Null-pointer exception! [Index specified is 0].")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__deallocate:|r Invalid-pointer exception! [Index {" + I2S(deindex) + "} specified is less than 0].")
endif
endif
return
elseif not IsInstanceAllocated(mainKey, deindex) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__deallocate:|r Double-free procedure detected! {Index " + I2S(deindex) + "}")
endif
return
elseif mainKey <= 0 then
if udg_Allocator_DEBUG_MODE then
if mainKey == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__deallocate:|r Null-pointer exception! [Key specified is 0].")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__deallocate:|r Invalid-pointer exception! [Key {" + I2S(mainKey) + "} specified is less than 0].")
endif
endif
return
endif
call SaveInteger(udg_Allocator_HASH, mainKey, deindex, LoadInteger(udg_Allocator_HASH, mainKey, 0))
call SaveInteger(udg_Allocator_HASH, mainKey, 0, deindex)
// Updates the internal number of the list in specified key.
call SaveInteger(udg_Allocator_HASH, mainKey, -1, LoadInteger(udg_Allocator_HASH, mainKey, -1) - 1)
endfunction
function AllocEngine_allocate takes integer mainKey returns integer
if mainKey <= 0 then
if udg_Allocator_DEBUG_MODE then
if mainKey == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__allocate:|r Null-pointer exception! [Key specified is 0].")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffff0000Allocator_Engine__allocate:|r Invalid-pointer exception! [Key {" + I2S(mainKey) + "} specified is invalid].")
endif
endif
set udg_Allocator_NewIndex = -1
else
set udg_Allocator_NewIndex = LoadInteger(udg_Allocator_HASH, mainKey, 0)
if LoadInteger(udg_Allocator_HASH, mainKey, udg_Allocator_NewIndex) == 0 then
if udg_Allocator_NewIndex >= LoadInteger(udg_Allocator_HASH, mainKey, -2) then
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cff00ff00Allocator_Engine__allocate:|r Exceeded maximum instance count {" + I2S(udg_Allocator_NewIndex) + "}")
endif
set udg_Allocator_NewIndex = 0
return udg_Allocator_NewIndex
endif
set udg_Allocator_NewIndex = udg_Allocator_NewIndex + 1
call SaveInteger(udg_Allocator_HASH, mainKey, 0, udg_Allocator_NewIndex)
call SaveInteger(udg_Allocator_HASH, mainKey, udg_Allocator_NewIndex, 0)
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cff00ff00Allocator_Engine__allocate:|r Retrieved a new Index {" + I2S(udg_Allocator_NewIndex) + "}")
endif
else
call SaveInteger(udg_Allocator_HASH, mainKey, 0, LoadInteger(udg_Allocator_HASH, mainKey, udg_Allocator_NewIndex))
call SaveInteger(udg_Allocator_HASH, mainKey, udg_Allocator_NewIndex, 0)
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffffcc00Allocator_Engine__allocate:|r Retrieved a recycled Index {" + I2S(udg_Allocator_NewIndex) + "}")
endif
endif
call SaveInteger(udg_Allocator_HASH, mainKey, -1, LoadInteger(udg_Allocator_HASH, mainKey, -1) + 1)
endif
return udg_Allocator_NewIndex
endfunction
// ===================================== //
// End Allocator Engine //
// ===================================== //
// ===================================== //
// End Allocator Core //
// ===================================== //
////////////////////////////////////////////////////////
//Guhun's MUI Engine version 2.0.0
////////////////////////////////////////////////////////
//This code generates an instance number for a RecycleKey
function GMUI_GetIndex takes integer RecycleKey returns integer
local integer instance
set instance = LoadInteger(udg_GMUI_Hashtable, RecycleKey, 0)
if not HaveSavedInteger(udg_GMUI_Hashtable, RecycleKey, instance) then
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, instance + 1)
else
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, LoadInteger(udg_GMUI_Hashtable, RecycleKey, instance))
call RemoveSavedInteger(udg_GMUI_Hashtable, RecycleKey, instance)
endif
return instance
endfunction
//This code generates recycles a used instance number for a RecycleKey
function GMUI_RecycleIndex takes integer RecycleKey, integer instance returns nothing
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, instance, LoadInteger(udg_GMUI_Hashtable, RecycleKey, 0))
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, instance)
endfunction
//This code generates a new, unused, RecycleKey
function GMUI_CreateRecycleKey takes nothing returns integer
local integer newKey = GMUI_GetIndex(0)
call SaveInteger(udg_GMUI_Hashtable, newKey, 0, 1)
return newKey
endfunction
//This code recycles a used RecycleKey
function GMUI_DestroyRecycleKey takes integer whichKey returns nothing
if whichKey == 0 then
return
endif
call GMUI_RecycleIndex(0, whichKey)
call FlushChildHashtable(udg_GMUI_Hashtable, whichKey)
endfunction
//This function initializes GMUI if it has not yet been initialized
function GMUI_Initialize takes nothing returns nothing
if udg_GMUI_Hashtable == null then
//Initialize Hashtable
set udg_GMUI_Hashtable = InitHashtable()
//Initialize the recycling algorithm for Recycle Keys
call SaveInteger(udg_GMUI_Hashtable, 0, 0, 1)
//Initialize the generic Recycle Key
call GMUI_CreateRecycleKey() //Will always be 1
endif
endfunction
////////////////////////////////////////////////////////
//End of MUI Engine
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//GLL : Guhun's Ordered Sets v.1.2.0
// An implementation of an ordered set with a linked list backend. AKA. LinkedHashSet.
////////////////////////////////////////////////////////////////////////////////////////////////////
//==============================================
// System API
//==============================================
//==============
// Set Navigation
//Returns the next element after the specified "data" in the set
//To get the first element, pass "0" as the parameter "data"
function GLL_GetNext takes integer setKey,integer data returns integer
return LoadInteger(udg_Lists_Hashtable, setKey, data)
endfunction
//Returns the element that preceeds the specified "data" in the set
//To get the last element, pass "0" as the parameter "data"
function GLL_GetPrev takes integer setKey,integer data returns integer
return LoadInteger(udg_Lists_Hashtable, - setKey, data)
endfunction
//Returns the first element of a set
//Available since 1.2.0
function GLL_FirstOf takes integer setKey returns integer
return (LoadInteger(udg_Lists_Hashtable, (setKey ), ( 0))) // INLINED!!
endfunction
//Returns the last element of a set
//Available since 1.2.0
function GLL_LastOf takes integer setKey returns integer
return (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( 0))) // INLINED!!
endfunction
//Returns whether a set contains the specified data or not
function GLL_ListHasData takes integer setKey,integer data returns boolean
return HaveSavedInteger(udg_Lists_Hashtable, setKey, data)
endfunction
//Returns wheter there are any elements in a set
//Available since 1.2.0
function GLL_IsEmpty takes integer setKey returns boolean
return (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) == 0 // INLINED!!
endfunction
//Returns the number of elements contained in a set
//Available since 1.2.0
function GLL_SizeOf takes integer setKey returns integer
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0
set count=count + 1
endloop
return count
endfunction
//==============
// Element Addition/Removal
//Adds an element to a set, in the position preceeding the element passed as the second parameter
//If data is already present in set, behaviour is undefined
function GLL_AddData takes integer setKey,integer next,integer data returns nothing
local integer prev= (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( next))) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( prev ), ( data)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( next ), ( data)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( data ), ( next)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( data ), ( prev)) // INLINED!!
endfunction
//Adds an element to a set, in the position following the element passed as the second parameter
//Available since 1.2.0
function GLL_AddDataAfter takes integer setKey,integer prev,integer data returns nothing
call GLL_AddData(- setKey , prev , data)
endfunction
//Adds an element to the end of the set
//Available since 1.2.0
function GLL_Append takes integer setKey,integer data returns nothing
call GLL_AddData(setKey , 0 , data)
endfunction
//Adds an element to the beginning of the set
//Available since 1.2.0
function GLL_Prepend takes integer setKey,integer data returns nothing
call GLL_AddData((- setKey ) , 0 , ( data))
endfunction
//Removes the given element from a set
//If data is not present in Set, behaviour is undefined
function GLL_RemoveData takes integer setKey,integer data returns nothing
local integer next= (LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
local integer prev= (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( data))) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( next ), ( prev)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( prev ), ( next)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, (setKey ), ( data)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, - (- setKey ), ( data)) // INLINED!!
endfunction
//==============
// Set Creation/Destruction
//Creates a new set and returns its ID/key
function GLL_CreateList takes nothing returns integer
local integer listId= GMUI_GetIndex(udg_Lists_RECYCLE_KEY)
call SaveInteger(udg_Lists_Hashtable, listId, 0, 0)
call SaveInteger(udg_Lists_Hashtable, - listId, 0, 0)
return listId
endfunction
//Destroys the specified set
function GLL_DestroyList takes integer listId returns nothing
call FlushChildHashtable(udg_Lists_Hashtable, listId)
call FlushChildHashtable(udg_Lists_Hashtable, - listId)
call GMUI_RecycleIndex(udg_Lists_RECYCLE_KEY , listId)
endfunction
//==============
// Looping Functionality
// If you want to execute a backwards loop, pass the opposite (negative) of the setKey.
//This function loops through a Set and executes a trigger for each element, setting the udg_List variables to their relevant equivalents each time
//If until is a non-negative number, then the loop will break after iterating over that many elements
function GLL_Loop takes integer setKey,trigger trig,integer until returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0 or count == until
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
if IsTriggerEnabled(trig) and TriggerEvaluate(trig) then
call TriggerExecute(trig)
endif
set count=count + 1
endloop
endfunction
//Works like GLL_Loop, but is more efficient if you want to loop over all elements
//Available since 1.2.0
function GLL_LoopAll takes integer setKey,trigger trig returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
loop
exitwhen data == 0
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
if IsTriggerEnabled(trig) and TriggerEvaluate(trig) then
call TriggerExecute(trig)
endif
endloop
endfunction
//Same as GLL_Loop, however, you may specify a code that will run in a ForPlayer loop instead of a trigger
//If until is a non-negative number, then the loop will break after iterating over that many elements
//Added in version 1.1.0
function GLL_CodeLoop takes integer setKey,code func,integer until returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0 or count == until
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call ForForce(bj_FORCE_PLAYER[0], func)
set count=count + 1
endloop
endfunction
//Works like GLL_CodeLoop, but is more efficient if you want to loop over all elements
//Available since 1.2.0
function GLL_CodeLoopAll takes integer setKey,code func returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
loop
exitwhen data == 0
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call ForForce(bj_FORCE_PLAYER[0], func)
endloop
endfunction
//Loops over a set from the value following "start" to the value preceding "finish" (or the end of the list, whichever comes first)
//Each iteration sets Lists_Data to the current value and then runs the specified code in a ForForce loop
//Added in version 1.1.0
function GLL_ClearList takes integer setKey,integer start,integer finish,code func returns integer
local integer data= (LoadInteger(udg_Lists_Hashtable, (setKey ), ( start))) // INLINED!!
local integer nextData
local integer countRemoved= 0
loop
exitwhen data == finish or data == 0
set nextData=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, (setKey ), ( data)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, - (- setKey ), ( data)) // INLINED!!
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
call ForForce(bj_FORCE_PLAYER[0], func)
set data=nextData
set countRemoved=countRemoved + 1
endloop
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( data ), ( start)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( start ), ( data)) // INLINED!!
return countRemoved
endfunction
//==============
// System initialization
//This function initializes GLL if it has not yet been initialized
function GLL_Initialize takes nothing returns nothing
if udg_Lists_Hashtable == null then
//Initialize dependencies
call GMUI_Initialize()
//Initialize Hashtable
set udg_Lists_Hashtable=InitHashtable()
//Get Recycle Key
set udg_Lists_RECYCLE_KEY=GMUI_CreateRecycleKey()
endif
endfunction
////////////////////////////////////////////////////////////////////////////////////////////////////
//End of Ordered Sets
////////////////////////////////////////////////////////////////////////////////////////////////////
// ============================= //
// Start DebugTrigger //
// ============================= //
function DebugTrigger_SetTraceTrigger takes trigger trig, boolean trace returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_SetTraceTrigger: This trigger has not been added to the watch list!")
return
endif
if udg_DEBUGTRIGGER_TRACE_DISABLE then
if trace then
if not IsTriggerEnabled(trig) then
call EnableTrigger(trig)
endif
else
if IsTriggerEnabled(trig) then
call DisableTrigger(trig)
endif
endif
endif
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex, trace)
endfunction
function DebugTrigger_SetWatchTrigger takes trigger trig, boolean watch returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_SetWatchTrigger: This trigger has not been added to the watch list!")
return
endif
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex, watch)
endfunction
// Displays a message to the game about the trigger (if it is registered to the system)
function DebugTrigger_DisplayStackTrace takes trigger trig returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_DisplayStackTrace: This trigger has not been added to the watch list!")
return
endif
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Trigger Name: " + LoadStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex))
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Number of iterations: " + I2S(LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex)))
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex) then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Watch Status: Enabled!")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Watch Status: Disabled!")
endif
endfunction
// Increments the number of which a successful trigger evaluation has been performed.
function DebugTrigger__OnWatch takes nothing returns boolean
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(GetTriggeringTrigger()))
local boolean result = LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex)
if result then
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex, LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex) + 1)
endif
if result then
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex) then
call DebugTrigger_DisplayStackTrace(GetTriggeringTrigger())
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, " ")
endif
endif
return true
endfunction
// Unwatches all registered triggers from the system.
// Does not deregister them
function DebugTrigger_DiscardAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
loop
exitwhen triggerNode == 0
call DebugTrigger_SetWatchTrigger(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode), false)
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
endfunction
// Rewatches all registered triggers from the system.
function DebugTrigger_AllowAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
loop
exitwhen triggerNode == 0
call DebugTrigger_SetWatchTrigger(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode), true)
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
endfunction
// Displays all watched registered triggers. Does not display unwatched registered triggers.
function DebugTrigger_DisplayAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "Stack-tracing triggers!" + "\n\n->")
loop
exitwhen triggerNode == 0
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerNode) then
call DebugTrigger_DisplayStackTrace(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode))
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "->")
endif
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "End Stack-trace!")
endfunction
// Registers a trigger into the system, with its' passed name.
function DebugTrigger_WatchTrigger takes trigger trig, string trigName returns integer
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
local integer trigNameId = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_StringKey, StringHash(trigName))
if trigNameId != 0 then
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: Another trigger with this name already exists!")
set trigName = trigName + "[" + I2S(LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId)) + "]"
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId, LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId) + 1)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: Provided trigger name has been renamed to " + trigName)
endif
if triggerIndex == 0 then
set triggerIndex = AllocEngine_allocate(udg_DebugTrigger_TriggerIndex)
call TriggerAddCondition(trig, Condition(function DebugTrigger__OnWatch))
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig), triggerIndex)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_StringKey, StringHash(trigName), triggerIndex)
call SaveTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerIndex, trig)
call SaveStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex, trigName)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex, 0)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameCount, triggerIndex, 0)
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex, true)
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex, false)
call GLL_Append(udg_DebugTrigger_TriggerList, triggerIndex)
else
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: The trigger already exists in the system!")
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: The name of the trigger is " + LoadStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex))
endif
return triggerIndex
endfunction
// ============================= //
// End DebugTrigger //
// ============================= //
Name | Type | is_array | initial_value |
Allocator_DEBUG_MODE | boolean | No | |
Allocator_deIndex | integer | No | |
Allocator_deKey | integer | No | |
Allocator_HASH | hashtable | No | |
Allocator_Instruction | integer | No | |
Allocator_Instruction_ALLOC | integer | No | |
Allocator_Instruction_DEALLOC | integer | No | |
Allocator_Instruction_IS_ALLOC | integer | No | |
Allocator_Instruction_RESIZE | integer | No | |
Allocator_isAllocated | boolean | No | |
Allocator_MainIndex | integer | No | |
Allocator_MainKey | integer | No | |
Allocator_MaxInstances | integer | No | |
Allocator_NewIndex | integer | No | |
Allocator_NewKey | integer | No | |
DebugTrigger_EnumPlayer | player | No | |
DebugTrigger_Instruction | integer | No | |
DebugTrigger_ListenerCountKey | integer | No | |
DebugTrigger_ListenerKey | integer | No | |
DebugTrigger_ListenerTrace | integer | No | |
DebugTrigger_ParamTrigger | trigger | No | |
DebugTrigger_ParamTriggerName | string | No | |
DEBUGTRIGGER_REGISTER | integer | No | |
DebugTrigger_StringInstance | integer | No | |
DebugTrigger_StringKey | integer | No | |
DebugTrigger_SubString | string | Yes | |
DEBUGTRIGGER_TRACE | integer | No | |
DEBUGTRIGGER_TRACE_DISABLE | boolean | No | |
DebugTrigger_TriggerHandle | integer | No | |
DebugTrigger_TriggerIndex | integer | No | |
DebugTrigger_TriggerKey | integer | No | |
DebugTrigger_TriggerList | integer | No | |
DebugTrigger_TriggerNameCount | integer | No | |
DebugTrigger_TriggerNameKey | integer | No | |
DebugTrigger_TriggerResult | trigger | No | |
DEBUGTRIGGER_UNTRACE | integer | No | |
GMUI_Hashtable | hashtable | No | |
GMUI_Index | integer | No | |
GMUI_RecycleKey | integer | No | |
Lists_Data | integer | No | |
Lists_Hashtable | hashtable | No | |
Lists_Instance | integer | No | |
Lists_ListID | integer | No | |
Lists_LoopUntil | integer | No | |
Lists_RECYCLE_KEY | integer | No | |
Lists_Trigger | trigger | No |
// ========================= //
// Backwards Compatibility //
// ========================= //
function Allocator_Main__allocate takes nothing returns integer
return AllocMain_allocate()
endfunction
function Allocator_Main__deallocate takes integer deKey returns nothing
call AllocMain_deallocate(deKey)
endfunction
// This function gets a new index for you
function Trig_Allocator_Main_Actions takes nothing returns nothing
if udg_Allocator_Instruction == udg_Allocator_Instruction_ALLOC then
call AllocMain_allocate()
elseif udg_Allocator_Instruction == udg_Allocator_Instruction_ALLOC then
call AllocMain_deallocate(udg_Allocator_deKey)
else
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffffcc00Allocator_Main_Actions:|r Unrecognized instruction!")
endif
endif
endfunction
//===========================================================================
function InitTrig_Allocator_Main takes nothing returns nothing
set udg_Allocator_HASH = InitHashtable()
set udg_Allocator_MaxInstances = 2147483647
set udg_Allocator_Instruction_RESIZE = 3
set udg_Allocator_Instruction_IS_ALLOC = 2
set udg_Allocator_Instruction_ALLOC = 1
set udg_Allocator_Instruction_DEALLOC = 0
set gg_trg_Allocator_Main = CreateTrigger( )
call TriggerAddAction( gg_trg_Allocator_Main, function Trig_Allocator_Main_Actions )
endfunction
// ========================= //
// Backwards Compatibility //
// ========================= //
function Allocator_Engine__allocate takes integer mainKey returns integer
return AllocEngine_allocate(mainKey)
endfunction
function Allocator_Engine__deallocate takes integer mainKey, integer deindex returns nothing
call AllocEngine_deallocate(mainKey, deindex)
endfunction
function Allocator_Engine__IsInstanceAllocated takes integer mainKey, integer index returns boolean
return IsInstanceAllocated(mainKey, index)
endfunction
function Trig_Allocator_Engine_Actions takes nothing returns nothing
if udg_Allocator_Instruction == udg_Allocator_Instruction_RESIZE then
call SetKeyBounds(udg_Allocator_MainKey, udg_Allocator_MaxInstances)
set udg_Allocator_MaxInstances = 2147483647
elseif udg_Allocator_Instruction == udg_Allocator_Instruction_IS_ALLOC then
call Allocator_Engine__IsInstanceAllocated(udg_Allocator_MainKey, udg_Allocator_MainIndex)
elseif udg_Allocator_Instruction == udg_Allocator_Instruction_ALLOC then
call Allocator_Engine__allocate(udg_Allocator_MainKey)
elseif udg_Allocator_Instruction == udg_Allocator_Instruction_DEALLOC then
call Allocator_Engine__deallocate(udg_Allocator_MainKey, udg_Allocator_deIndex)
else
if udg_Allocator_DEBUG_MODE then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> |cffffcc00Allocator_Engine_Actions:|r Unrecognized instruction!")
endif
endif
endfunction
//===========================================================================
function InitTrig_Allocator_Engine takes nothing returns nothing
set gg_trg_Allocator_Engine = CreateTrigger( )
call TriggerAddAction( gg_trg_Allocator_Engine, function Trig_Allocator_Engine_Actions )
endfunction
////////////////////////////////////////////////////////
//Guhun's MUI Engine version 2.0.0
////////////////////////////////////////////////////////
//This code generates an instance number for a RecycleKey
function GMUI_GetIndex takes integer RecycleKey returns integer
local integer instance
set instance = LoadInteger(udg_GMUI_Hashtable, RecycleKey, 0)
if not HaveSavedInteger(udg_GMUI_Hashtable, RecycleKey, instance) then
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, instance + 1)
else
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, LoadInteger(udg_GMUI_Hashtable, RecycleKey, instance))
call RemoveSavedInteger(udg_GMUI_Hashtable, RecycleKey, instance)
endif
return instance
endfunction
//This code generates recycles a used instance number for a RecycleKey
function GMUI_RecycleIndex takes integer RecycleKey, integer instance returns nothing
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, instance, LoadInteger(udg_GMUI_Hashtable, RecycleKey, 0))
call SaveInteger(udg_GMUI_Hashtable, RecycleKey, 0, instance)
endfunction
//This code generates a new, unused, RecycleKey
function GMUI_CreateRecycleKey takes nothing returns integer
local integer newKey = GMUI_GetIndex(0)
call SaveInteger(udg_GMUI_Hashtable, newKey, 0, 1)
return newKey
endfunction
//This code recycles a used RecycleKey
function GMUI_DestroyRecycleKey takes integer whichKey returns nothing
if whichKey == 0 then
return
endif
call GMUI_RecycleIndex(0, whichKey)
call FlushChildHashtable(udg_GMUI_Hashtable, whichKey)
endfunction
//This function initializes GMUI if it has not yet been initialized
function GMUI_Initialize takes nothing returns nothing
if udg_GMUI_Hashtable == null then
//Initialize Hashtable
set udg_GMUI_Hashtable = InitHashtable()
//Initialize the recycling algorithm for Recycle Keys
call SaveInteger(udg_GMUI_Hashtable, 0, 0, 1)
//Initialize the generic Recycle Key
call GMUI_CreateRecycleKey() //Will always be 1
endif
endfunction
////////////////////////////////////////////////////////
//End of MUI Engine
////////////////////////////////////////////////////////
function Trig_GMUI_Main_Actions takes nothing returns nothing
if udg_GMUI_RecycleKey == 0 then
set udg_GMUI_RecycleKey = GMUI_CreateRecycleKey()
else
call GMUI_DestroyRecycleKey(udg_GMUI_RecycleKey)
endif
endfunction
function Trig_GMUI_Main_Conditions takes nothing returns boolean
if udg_GMUI_Index == 0 then
set udg_GMUI_Index = GMUI_GetIndex(udg_GMUI_RecycleKey)
else
call GMUI_RecycleIndex(udg_GMUI_RecycleKey, udg_GMUI_Index)
endif
return false
endfunction
//===========================================================================
function InitTrig_GMUI_Main takes nothing returns nothing
call GMUI_Initialize()
//Create Trigger for GUI users
set gg_trg_GMUI_Main = CreateTrigger( )
call TriggerAddAction( gg_trg_GMUI_Main, function Trig_GMUI_Main_Actions )
call TriggerAddCondition(gg_trg_GMUI_Main, Condition(function Trig_GMUI_Main_Conditions))
endfunction
////////////////////////////////////////////////////////////////////////////////////////////////////
//GLL : Guhun's Ordered Sets v.1.2.0
// An implementation of an ordered set with a linked list backend. AKA. LinkedHashSet.
////////////////////////////////////////////////////////////////////////////////////////////////////
//==============================================
// System API
//==============================================
//==============
// Set Navigation
//Returns the next element after the specified "data" in the set
//To get the first element, pass "0" as the parameter "data"
function GLL_GetNext takes integer setKey,integer data returns integer
return LoadInteger(udg_Lists_Hashtable, setKey, data)
endfunction
//Returns the element that preceeds the specified "data" in the set
//To get the last element, pass "0" as the parameter "data"
function GLL_GetPrev takes integer setKey,integer data returns integer
return LoadInteger(udg_Lists_Hashtable, - setKey, data)
endfunction
//Returns the first element of a set
//Available since 1.2.0
function GLL_FirstOf takes integer setKey returns integer
return (LoadInteger(udg_Lists_Hashtable, (setKey ), ( 0))) // INLINED!!
endfunction
//Returns the last element of a set
//Available since 1.2.0
function GLL_LastOf takes integer setKey returns integer
return (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( 0))) // INLINED!!
endfunction
//Returns whether a set contains the specified data or not
function GLL_ListHasData takes integer setKey,integer data returns boolean
return HaveSavedInteger(udg_Lists_Hashtable, setKey, data)
endfunction
//Returns wheter there are any elements in a set
//Available since 1.2.0
function GLL_IsEmpty takes integer setKey returns boolean
return (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) == 0 // INLINED!!
endfunction
//Returns the number of elements contained in a set
//Available since 1.2.0
function GLL_SizeOf takes integer setKey returns integer
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0
set count=count + 1
endloop
return count
endfunction
//==============
// Element Addition/Removal
//Adds an element to a set, in the position preceeding the element passed as the second parameter
//If data is already present in set, behaviour is undefined
function GLL_AddData takes integer setKey,integer next,integer data returns nothing
local integer prev= (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( next))) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( prev ), ( data)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( next ), ( data)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( data ), ( next)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( data ), ( prev)) // INLINED!!
endfunction
//Adds an element to a set, in the position following the element passed as the second parameter
//Available since 1.2.0
function GLL_AddDataAfter takes integer setKey,integer prev,integer data returns nothing
call GLL_AddData(- setKey , prev , data)
endfunction
//Adds an element to the end of the set
//Available since 1.2.0
function GLL_Append takes integer setKey,integer data returns nothing
call GLL_AddData(setKey , 0 , data)
endfunction
//Adds an element to the beginning of the set
//Available since 1.2.0
function GLL_Prepend takes integer setKey,integer data returns nothing
call GLL_AddData((- setKey ) , 0 , ( data))
endfunction
//Removes the given element from a set
//If data is not present in Set, behaviour is undefined
function GLL_RemoveData takes integer setKey,integer data returns nothing
local integer next= (LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
local integer prev= (LoadInteger(udg_Lists_Hashtable, - (setKey ), ( data))) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( next ), ( prev)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( prev ), ( next)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, (setKey ), ( data)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, - (- setKey ), ( data)) // INLINED!!
endfunction
//==============
// Set Creation/Destruction
//Creates a new set and returns its ID/key
function GLL_CreateList takes nothing returns integer
local integer listId= GMUI_GetIndex(udg_Lists_RECYCLE_KEY)
call SaveInteger(udg_Lists_Hashtable, listId, 0, 0)
call SaveInteger(udg_Lists_Hashtable, - listId, 0, 0)
return listId
endfunction
//Destroys the specified set
function GLL_DestroyList takes integer listId returns nothing
call FlushChildHashtable(udg_Lists_Hashtable, listId)
call FlushChildHashtable(udg_Lists_Hashtable, - listId)
call GMUI_RecycleIndex(udg_Lists_RECYCLE_KEY , listId)
endfunction
//==============
// Looping Functionality
// If you want to execute a backwards loop, pass the opposite (negative) of the setKey.
//This function loops through a Set and executes a trigger for each element, setting the udg_List variables to their relevant equivalents each time
//If until is a non-negative number, then the loop will break after iterating over that many elements
function GLL_Loop takes integer setKey,trigger trig,integer until returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0 or count == until
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
if IsTriggerEnabled(trig) and TriggerEvaluate(trig) then
call TriggerExecute(trig)
endif
set count=count + 1
endloop
endfunction
//Works like GLL_Loop, but is more efficient if you want to loop over all elements
//Available since 1.2.0
function GLL_LoopAll takes integer setKey,trigger trig returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
loop
exitwhen data == 0
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
if IsTriggerEnabled(trig) and TriggerEvaluate(trig) then
call TriggerExecute(trig)
endif
endloop
endfunction
//Same as GLL_Loop, however, you may specify a code that will run in a ForPlayer loop instead of a trigger
//If until is a non-negative number, then the loop will break after iterating over that many elements
//Added in version 1.1.0
function GLL_CodeLoop takes integer setKey,code func,integer until returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
local integer count= 0
loop
exitwhen data == 0 or count == until
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call ForForce(bj_FORCE_PLAYER[0], func)
set count=count + 1
endloop
endfunction
//Works like GLL_CodeLoop, but is more efficient if you want to loop over all elements
//Available since 1.2.0
function GLL_CodeLoopAll takes integer setKey,code func returns nothing
local integer data= (LoadInteger(udg_Lists_Hashtable, ((setKey) ), ( 0))) // INLINED!!
loop
exitwhen data == 0
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
set data=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call ForForce(bj_FORCE_PLAYER[0], func)
endloop
endfunction
//Loops over a set from the value following "start" to the value preceding "finish" (or the end of the list, whichever comes first)
//Each iteration sets Lists_Data to the current value and then runs the specified code in a ForForce loop
//Added in version 1.1.0
function GLL_ClearList takes integer setKey,integer start,integer finish,code func returns integer
local integer data= (LoadInteger(udg_Lists_Hashtable, (setKey ), ( start))) // INLINED!!
local integer nextData
local integer countRemoved= 0
loop
exitwhen data == finish or data == 0
set nextData=(LoadInteger(udg_Lists_Hashtable, (setKey ), ( data))) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, (setKey ), ( data)) // INLINED!!
call RemoveSavedInteger(udg_Lists_Hashtable, - (- setKey ), ( data)) // INLINED!!
set udg_Lists_Data=data
set udg_Lists_ListID=setKey
call ForForce(bj_FORCE_PLAYER[0], func)
set data=nextData
set countRemoved=countRemoved + 1
endloop
call SaveInteger(udg_Lists_Hashtable, - (setKey ), ( data ), ( start)) // INLINED!!
call SaveInteger(udg_Lists_Hashtable, (setKey ), ( start ), ( data)) // INLINED!!
return countRemoved
endfunction
//==============
// System initialization
//This function initializes GLL if it has not yet been initialized
function GLL_Initialize takes nothing returns nothing
if udg_Lists_Hashtable == null then
//Initialize dependencies
call GMUI_Initialize()
//Initialize Hashtable
set udg_Lists_Hashtable=InitHashtable()
//Get Recycle Key
set udg_Lists_RECYCLE_KEY=GMUI_CreateRecycleKey()
endif
endfunction
////////////////////////////////////////////////////////////////////////////////////////////////////
//End of Ordered Sets
////////////////////////////////////////////////////////////////////////////////////////////////////
function Trig_GLL_Main_Actions takes nothing returns nothing
if udg_Lists_ListID == 0 then
set udg_Lists_ListID = GLL_CreateList()
else
call GLL_DestroyList(udg_Lists_ListID)
endif
endfunction
function Trig_GLL_Main_Conditions takes nothing returns boolean
if HaveSavedInteger(udg_Lists_Hashtable, udg_Lists_ListID, udg_Lists_Data) then //Faster than GLL_ListHasData function
call GLL_RemoveData(udg_Lists_ListID, udg_Lists_Data)
else
call GLL_AddData(udg_Lists_ListID, udg_Lists_Instance, udg_Lists_Data)
endif
return false
endfunction
//===========================================================================
function InitTrig_GLL_Main takes nothing returns nothing
call GLL_Initialize()
set gg_trg_GLL_Main = CreateTrigger( )
call TriggerAddAction( gg_trg_GLL_Main, function Trig_GLL_Main_Actions )
call TriggerAddCondition( gg_trg_GLL_Main, Condition(function Trig_GLL_Main_Conditions))
endfunction
Debug Trigger v.1.0.0
Welcome to Debug Trigger!
Debugging is the act of locating or isolating the error, and resolving them. Sometimes, it
involves step-by-step review of the code, or affixing debug messages, etc. It can prove quite
cumbersome to find errors in your code, even more so in your triggers, as it becomes pesky
to find and resolve.
Debug Trigger is a system that gives you additional information on your triggers such as the
number of times it has evaluated itself and executed itself. It also has the option of tracing
your triggers to see if they get executed. Finally, it has the ability to isolate which triggers
(which are registered into the system) are problematic with a simple command tool, (more on that
later...)
If used correctly, this could prove to be one of the most helpful tools in debugging your
triggers.
Functions available:
DebugTrigger_SetTraceTrigger(trigger, boolean)
If the trigger is in the system, this enables the tracing of the trigger in the evaluation
of conditions.
Also, if udg_DEBUGTRIGGER_TRACE_DISABLE is true, the boolean flag determines the state of the
trigger such that setting it to true would enable it, and the inverse is true.
DebugTrigger_SetWatchTrigger(trigger, boolean)
If the trigger is in the system, this enables the watching of the trigger. This is enabled by
default. When tracing is enabled, a trace message will be displayed.
Player Commands:
discard XX..
- If the rest of the text is empty, it will no longer watch any registered trigger.
- Otherwise, it only discards the specified trigger.
allow XX..
- If the rest of the text is empty, it will watch any registered trigger once again.
- Otherwise, it will enable the watching of the specified trigger.
display XX...
- If the rest of the text is empty, it displays all watched triggers.
- Otherwise, it will only display information on the watched trigger.
Note:
Do not try to leave out a lot of spaces after the commands, as it will be interpreted as a
trigger name, and may make your debug-console (log) look awkward.
For GUI Users:
If you want to register certain triggers without the custom script shenanigans, you can assign the
following variable/s:
udg_DebugTrigger_ParamTrigger - The trigger which you want to affect.
udg_DebugTrigger_ParamTriggerName - The assigned name of the trigger.
udg_DebugTrigger_Instruction - The assigned instruction.
You can assign the instruction variable into these values:
0 - Makes the system watch the trigger above, with the assigned name.
1 - Enables stack-tracing of the trigger. This will display info on every triggerevaluation.
2 - Disables stack-tracing of the trigger. If udg_DEBUGTRIGGER_TRACE_DISABLE is set to true,
this also disables the trigger.
There are helper variables specifically for that purpose. They are
udg_DEBUGTRIGGER_REGISTER -> 0
udg_DEBUGTRIGGER_TRACE -> 0
udg_DEBUGTRIGGER_UNTRACE -> 0
For instructions 1, and 2, you only need to provide udg_DebugTrigger_ParamTrigger.
For instruction 0, you need to provide both.
For your safety, try not to assign an invalid value to either of these variables. However, the system
can handle such a case under a premature-exit routine.
Potential bugs:
Too many triggers would result into collisions in registration, as using StringHash would prove.
Otherwise, it is all fine.
P.S:
I would like to end my notes and documentation of this resource by stating that whatever I have
not described here, it is not described for a reason; they are fundamentally not accessible to
the end-user.
-------------------------------------------------------------
Credits:
Darkfang for the idea of Debug Trigger in the first place
-------------------------------------------------------------
// ============================= //
// Start DebugTrigger //
// ============================= //
function DebugTrigger_SetTraceTrigger takes trigger trig, boolean trace returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_SetTraceTrigger: This trigger has not been added to the watch list!")
return
endif
if udg_DEBUGTRIGGER_TRACE_DISABLE then
if trace then
if not IsTriggerEnabled(trig) then
call EnableTrigger(trig)
endif
else
if IsTriggerEnabled(trig) then
call DisableTrigger(trig)
endif
endif
endif
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex, trace)
endfunction
function DebugTrigger_SetWatchTrigger takes trigger trig, boolean watch returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_SetWatchTrigger: This trigger has not been added to the watch list!")
return
endif
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex, watch)
endfunction
// Displays a message to the game about the trigger (if it is registered to the system)
function DebugTrigger_DisplayStackTrace takes trigger trig returns nothing
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
if triggerIndex == 0 then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_DisplayStackTrace: This trigger has not been added to the watch list!")
return
endif
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Trigger Name: " + LoadStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex))
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Number of iterations: " + I2S(LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex)))
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex) then
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Watch Status: Enabled!")
else
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "-> Watch Status: Disabled!")
endif
endfunction
// Increments the number of which a successful trigger evaluation has been performed.
function DebugTrigger__OnWatch takes nothing returns boolean
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(GetTriggeringTrigger()))
local boolean result = LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex)
if result then
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex, LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex) + 1)
endif
if result then
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex) then
call DebugTrigger_DisplayStackTrace(GetTriggeringTrigger())
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, " ")
endif
endif
return true
endfunction
// Unwatches all registered triggers from the system.
// Does not deregister them
function DebugTrigger_DiscardAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
loop
exitwhen triggerNode == 0
call DebugTrigger_SetWatchTrigger(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode), false)
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
endfunction
// Rewatches all registered triggers from the system.
function DebugTrigger_AllowAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
loop
exitwhen triggerNode == 0
call DebugTrigger_SetWatchTrigger(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode), true)
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
endfunction
// Displays all watched registered triggers. Does not display unwatched registered triggers.
function DebugTrigger_DisplayAll takes nothing returns nothing
local integer triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, 0)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "Stack-tracing triggers!" + "\n\n->")
loop
exitwhen triggerNode == 0
if LoadBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerNode) then
call DebugTrigger_DisplayStackTrace(LoadTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerNode))
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "->")
endif
set triggerNode = GLL_GetNext(udg_DebugTrigger_TriggerList, triggerNode)
endloop
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "End Stack-trace!")
endfunction
// Registers a trigger into the system, with its' passed name.
function DebugTrigger_WatchTrigger takes trigger trig, string trigName returns integer
local integer triggerIndex = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig))
local integer trigNameId = LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_StringKey, StringHash(trigName))
if trigNameId != 0 then
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: Another trigger with this name already exists!")
set trigName = trigName + "[" + I2S(LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId)) + "]"
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId, LoadInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, trigNameId) + 1)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: Provided trigger name has been renamed to " + trigName)
endif
if triggerIndex == 0 then
set triggerIndex = AllocEngine_allocate(udg_DebugTrigger_TriggerIndex)
call TriggerAddCondition(trig, Condition(function DebugTrigger__OnWatch))
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerKey, GetHandleId(trig), triggerIndex)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_StringKey, StringHash(trigName), triggerIndex)
call SaveTriggerHandle(udg_Allocator_HASH, udg_DebugTrigger_TriggerHandle, triggerIndex, trig)
call SaveStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex, trigName)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_ListenerCountKey, triggerIndex, 0)
call SaveInteger(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameCount, triggerIndex, 0)
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerKey, triggerIndex, true)
call SaveBoolean(udg_Allocator_HASH, udg_DebugTrigger_ListenerTrace, triggerIndex, false)
call GLL_Append(udg_DebugTrigger_TriggerList, triggerIndex)
else
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: The trigger already exists in the system!")
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 50000, "DebugTrigger_WatchTrigger: The name of the trigger is " + LoadStr(udg_Allocator_HASH, udg_DebugTrigger_TriggerNameKey, triggerIndex))
endif
return triggerIndex
endfunction
// ============================= //
// End DebugTrigger //
// ============================= //
function Debug_Trigger_IsPlayer takes nothing returns boolean
return (GetPlayerController(udg_DebugTrigger_EnumPlayer) == MAP_CONTROL_USER) and (GetPlayerSlotState(udg_DebugTrigger_EnumPlayer) == PLAYER_SLOT_STATE_PLAYING)
endfunction
function Debug_Trigger_AddCommandListener takes nothing returns nothing
set udg_DebugTrigger_EnumPlayer = GetEnumPlayer()
if Debug_Trigger_IsPlayer() then
call TriggerRegisterPlayerChatEvent(gg_trg_Debug_Trigger_Core, udg_DebugTrigger_EnumPlayer, "discard", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Debug_Trigger_Core, udg_DebugTrigger_EnumPlayer, "display", false)
call TriggerRegisterPlayerChatEvent(gg_trg_Debug_Trigger_Core, udg_DebugTrigger_EnumPlayer, "allow", false)
endif
endfunction
function Trig_Debug_Trigger_Init_Actions takes nothing returns nothing
local trigger eventTrig = GetTriggeringTrigger()
call DisableTrigger( eventTrig )
call ForForce( bj_FORCE_ALL_PLAYERS, function Debug_Trigger_AddCommandListener)
call DestroyTrigger(eventTrig)
set eventTrig = null
endfunction
//===========================================================================
function InitTrig_Debug_Trigger_Init takes nothing returns nothing
set gg_trg_Debug_Trigger_Init = CreateTrigger( )
set udg_DEBUGTRIGGER_REGISTER = 0
set udg_DEBUGTRIGGER_TRACE = 1
set udg_DEBUGTRIGGER_UNTRACE = 2
set udg_DebugTrigger_ListenerCountKey = AllocMain_allocate()
set udg_DebugTrigger_ListenerKey = AllocMain_allocate()
set udg_DebugTrigger_ListenerTrace = AllocMain_allocate()
set udg_DebugTrigger_StringKey = AllocMain_allocate()
set udg_DebugTrigger_TriggerHandle = AllocMain_allocate()
set udg_DebugTrigger_TriggerIndex = AllocMain_allocate()
set udg_DebugTrigger_TriggerKey = AllocMain_allocate()
set udg_DebugTrigger_TriggerNameCount = AllocMain_allocate()
set udg_DebugTrigger_TriggerNameKey = AllocMain_allocate()
set udg_DebugTrigger_TriggerList = GLL_CreateList()
call TriggerAddAction( gg_trg_Debug_Trigger_Init, function Trig_Debug_Trigger_Init_Actions )
endfunction
// Actually typed instead of GUI generated...
function Trig_Debug_Trigger_Test_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'AHfs' ) ) then
return false
endif
return true
endfunction
function Trig_Debug_Trigger_Test_Actions takes nothing returns nothing
call BJDebugMsg("Spell cast")
endfunction
//===========================================================================
function InitTrig_Debug_Trigger_Test takes nothing returns nothing
set gg_trg_Debug_Trigger_Test = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Debug_Trigger_Test, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Debug_Trigger_Test, Condition( function Trig_Debug_Trigger_Test_Conditions ) )
call TriggerAddAction( gg_trg_Debug_Trigger_Test, function Trig_Debug_Trigger_Test_Actions )
call DebugTrigger_WatchTrigger(gg_trg_Debug_Trigger_Test, "Spell-Effect Test")
call DebugTrigger_SetTraceTrigger(gg_trg_Debug_Trigger_Test, true)
endfunction
function Trig_Debug_Trigger_Test_2_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'AHfs' ) ) then
return false
endif
return true
endfunction
function Trig_Debug_Trigger_Test_2_Actions takes nothing returns nothing
call BJDebugMsg("Cast success!")
endfunction
//===========================================================================
function InitTrig_Debug_Trigger_Test_2 takes nothing returns nothing
set gg_trg_Debug_Trigger_Test_2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Debug_Trigger_Test_2, EVENT_PLAYER_UNIT_SPELL_FINISH )
call TriggerAddCondition( gg_trg_Debug_Trigger_Test_2, Condition( function Trig_Debug_Trigger_Test_2_Conditions ) )
call TriggerAddAction( gg_trg_Debug_Trigger_Test_2, function Trig_Debug_Trigger_Test_2_Actions )
// This trigger is not part of the watch list, so it will not be displayed when
// typing the command display.
call DebugTrigger_WatchTrigger(gg_trg_Debug_Trigger_Test_2, "Spell-Effect Test 2")
call DebugTrigger_SetWatchTrigger(gg_trg_Debug_Trigger_Test_2, false)
endfunction