This would work in vanilla hooks because iterate-and-remove works with pairs(). But it does not work with this hook library because removing the hook causes the last hook in the sequence to be swapped into its place, then that previous last hook will be skipped by the iteration.
The fix makes hook.Remove put a temporary "gap function" where the removed hook used to be which will be swapped on the next call of the hook (it only does this if there are later hooks). The gap functions are denoted by the lack of an id being mapped to their index.
Code to test it: (output is wrong before change)
local calls, frame = 0, 0
for i=1, 100 do
local n = "hook"..i
hook.Add("Tick", n, function()
if frame ~= engine.TickCount() then
frame = engine.TickCount()
calls = 0
end
calls = calls + 1
hook.Remove("Tick", n)
end)
end
timer.Simple(0.1, function() print("calls", calls) end)
Other changes:
Combine hook_index and hook_id to one table
Store #callbacks in callbacks[0] (this is way faster, #tab is O(logn))
Skip the initial i=i+1 in callback iteration (if this was intentional because of lua jit let me know, idk)
Remove the table from hook_callbacks when the last hook is removed so its faster
type.lua: Fix a big string being a slow edge case on isnumber()
If you do code like:
This would work in vanilla hooks because iterate-and-remove works with pairs(). But it does not work with this hook library because removing the hook causes the last hook in the sequence to be swapped into its place, then that previous last hook will be skipped by the iteration.
The fix makes hook.Remove put a temporary "gap function" where the removed hook used to be which will be swapped on the next call of the hook (it only does this if there are later hooks). The gap functions are denoted by the lack of an id being mapped to their index.
Code to test it: (output is wrong before change)
Other changes:
i=i+1
in callback iteration (if this was intentional because of lua jit let me know, idk)