Page 1 of 2
Hook Library
Posted: Fri Sep 04, 2020 3:24 pm
by GlorifiedPig
I created a hook library that works similarly to the one in Garry's Mod. Insanely useful for events and code organization, I personally use it for all my projects. MIT licensed and fully documented, feel free to do whatever with it
You can find the gist here.
Example usage:
main.lua
Code: Select all
function love.update( dt )
Hook.Call( "Update", dt )
end
otherfile.lua
Code: Select all
Hook.Attach( "Update", "UniqueIDHere", function( dt )
print( dt )
end )
This has nothing to do with the debug library hooks, it is completely unrelated.
Re: Hook Library
Posted: Fri Sep 04, 2020 5:29 pm
by ivan
Any examples on how/why this could be used?
Also, I should mention that the debug. module has general purpose hooks.
Re: Hook Library
Posted: Fri Sep 04, 2020 5:37 pm
by GlorifiedPig
ivan wrote: ↑Fri Sep 04, 2020 5:29 pm
Any examples on how/why this could be used?
Also, I should mention that the debug. module has general purpose hooks.
This is completely unrelated to the debug module hooks brother, also sure thing:
main.lua
Code: Select all
function love.update( dt )
Hook.Call( "Update", dt )
end
otherfile.lua
Code: Select all
Hook.Attach( "Update", "UniqueIDHere", function( dt )
print( dt )
end )
Re: Hook Library
Posted: Sat Sep 05, 2020 6:53 am
by ivan
I see. Going over the code I think it closely resembles the publisher->subscriber model.
The primary feature which you forgot to mention is that you can attach multiple hooks/callbacks to one particular event/hookID.
It's not bad although I'm not 100% sold on having to specify uniqueIDs. Also this library is non-deterministic due to the following line:
Code: Select all
for k, v in pairs( cachedHooks[hookID] ) do
pairs does not iterate your hooks in a predictable manner.
I think the lib would be much better if you just stored your hooks in a list and used ipairs. You can also use the func pointer as a unique id anyways.
Re: Hook Library
Posted: Sat Sep 05, 2020 2:51 pm
by GlorifiedPig
ivan wrote: ↑Sat Sep 05, 2020 6:53 am
I see. Going over the code I think it closely resembles the publisher->subscriber model.
The primary feature which you forgot to mention is that you can attach multiple hooks/callbacks to one particular event/hookID.
It's not bad although I'm not 100% sold on having to specify uniqueIDs. Also this library is non-deterministic due to the following line:
Code: Select all
for k, v in pairs( cachedHooks[hookID] ) do
pairs does not iterate your hooks in a predictable manner.
Yes, the first point you mention is the whole reason you'd have a use case for this library over just simply calling the function itself and that's why I created it lol, and Unique IDs have to be specified else how else would you remove a hook if you don't assign it's value to a variable?
I think the lib would be much better if you just stored your hooks in a list and used ipairs. You can also use the func pointer as a unique id anyways.
This goes completely against what the library was made for, the unique IDs are for direct reference to the table. I believe you are having trouble understanding what the system is used for, here is a similar one used in Garry's Mod and you will see the purpose of the library:
https://wiki.facepunch.com/gmod/Hook_Library_Usage
https://github.com/Facepunch/garrysmod/ ... ok.lua#L23
Re: Hook Library
Posted: Sat Sep 05, 2020 3:35 pm
by zorg
GlorifiedPig wrote: ↑Sat Sep 05, 2020 2:51 pm
ivan wrote: ↑Sat Sep 05, 2020 6:53 am
I think the lib would be much better if you just stored your hooks in a list and used ipairs. You can also use the func pointer as a unique id anyways.
This goes completely against what the library was made for, the unique IDs are for direct reference to the table. I believe you are having trouble understanding what the system is used for, here is a similar one used in Garry's Mod and you will see the purpose of the library:
https://wiki.facepunch.com/gmod/Hook_Library_Usage
https://github.com/Facepunch/garrysmod/ ... ok.lua#L23
You can still keep the unique IDs and
also keep a table for the stuff added with the integer keys being the
order in which they were added; if you use pairs, that order doesn't exist, and your users could e.g. call update and draw in a random order each frame... not a good idea. With that one extra table, you could use that for iteration.
Re: Hook Library
Posted: Sat Sep 05, 2020 3:47 pm
by GlorifiedPig
zorg wrote: ↑Sat Sep 05, 2020 3:35 pm
GlorifiedPig wrote: ↑Sat Sep 05, 2020 2:51 pm
ivan wrote: ↑Sat Sep 05, 2020 6:53 am
I think the lib would be much better if you just stored your hooks in a list and used ipairs. You can also use the func pointer as a unique id anyways.
This goes completely against what the library was made for, the unique IDs are for direct reference to the table. I believe you are having trouble understanding what the system is used for, here is a similar one used in Garry's Mod and you will see the purpose of the library:
https://wiki.facepunch.com/gmod/Hook_Library_Usage
https://github.com/Facepunch/garrysmod/ ... ok.lua#L23
You can still keep the unique IDs and
also keep a table for the stuff added with the integer keys being the
order in which they were added; if you use pairs, that order doesn't exist, and your users could e.g. call update and draw in a random order each frame... not a good idea. With that one extra table, you could use that for iteration.
This would work but I cannot find a use case for having it in a specific order as it iterates to the point where it finds the first return value either way
Re: Hook Library
Posted: Sat Sep 05, 2020 4:44 pm
by grump
GlorifiedPig wrote: ↑Sat Sep 05, 2020 3:47 pm
This would work but I cannot find a use case for having it in a specific order
There's this thing called "the principle of least surprise", and library code is usually expected to adhere to it. In this case it means that hooks should be called in the order they were added, instead of the order of iteration being undefined, and even semi-randomly change during the lifetime of the program, which is very surprising.
https://en.wikipedia.org/wiki/Principle ... tonishment
One use case where your approach immediately fails is all kinds of drawing code, e.g. using it with love.draw.
as it iterates to the point where it finds the first return value either way
That's not what the code does though. It iterates over all hooks in unspecified order and returns the first return value that was not nil and not false. It does not stop iteration early.
Not treating false as a valid return value is another surprising behavior btw.
Re: Hook Library
Posted: Sun Sep 06, 2020 9:03 am
by GlorifiedPig
grump wrote: ↑Sat Sep 05, 2020 4:44 pm
GlorifiedPig wrote: ↑Sat Sep 05, 2020 3:47 pm
This would work but I cannot find a use case for having it in a specific order
There's this thing called "the principle of least surprise", and library code is usually expected to adhere to it. In this case it means that hooks should be called in the order they were added, instead of the order of iteration being undefined, and even semi-randomly change during the lifetime of the program, which is very surprising.
https://en.wikipedia.org/wiki/Principle ... tonishment
One use case where your approach immediately fails is all kinds of drawing code, e.g. using it with love.draw.
as it iterates to the point where it finds the first return value either way
That's not what the code does though. It iterates over all hooks in unspecified order and returns the first return value that was not nil and not false. It does not stop iteration early.
Not treating false as a valid return value is another surprising behavior btw.
You are right. Let me change that up quickly.
Re: Hook Library
Posted: Sun Sep 06, 2020 9:19 am
by monolifed
It works on a single cachedHooks table inside the module.
currenthook:Attach rather than Hook.attach would be nicer