IceGT_'s Hook System and Table extensions

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
IceGT_
Prole
Posts: 3
Joined: Sun Jan 08, 2017 5:27 am

IceGT_'s Hook System and Table extensions

Postby IceGT_ » Wed Jan 11, 2017 7:59 am

Hi, this would be my first post. What I have to offer is...

Hooks - https://github.com/icegt95/icegts_love2d_extensions/blob/master/e_hook.lua
...another hook system that I'm currently using in a project I hope to get greenlit this year, which is kinda like the one GMod uses, but kinda not - the main difference being that hook.call will return a table of all values returned by any called hook. hook.run will return the first value it receives. The system can be modified easily to perform differently if need be.

Code: Select all

--   Example 1:

      hook.add( "ShouldSkipStartupMessage", "blocking_1", function()
         
         return true
         
      end )

      love.load = function()

         local should_skip = hook.run( "ShouldSkipStartupMessage" )
         if not ( should_skip == true ) then -- for demonstration purposes
            print( "Startup message wasn't skipped" )
         end

      end



--   Example 2:

      hook.add( "LoveGameStartOrSomething", "ex2_hooka", function( num1, num2, num3 )
         
         return "Random numbers to format for results_tab - " .. num1 .. ", " .. num2 .. ", " .. num3 .. "!"
         
      end )

      hook.add( "LoveGameStartOrSomething", "ex2_hookb", function( num1, num2, num3 )
         
         return "This will also be returned in results_tab - " .. num1 .. ", " .. num2 .. ", " .. num3 .. "!"
         
      end )

      love.load = function()

         local results_tab = hook.call( "LoveGameStartOrSomething", math.random(), math.random(), math.random() )
         
         if results_tab then

            for idx, res_str in next, results_tab, nil do

               print( res_str )

            end

         end

      end


Table library extension - https://github.com/icegt95/icegts_love2d_extensions/blob/master/e_table.lua
Expands on lua's table library with functions similar to those in Garry's Mod.
Last edited by IceGT_ on Thu Jan 12, 2017 7:22 pm, edited 7 times in total.

Code: Select all

local ok = dothething and pcall( function() assert( loadfile( "hello_world.luac" ) )() end ) or false
if not ok then print( "spilt chocolate milk :(" ) end

User avatar
Sir_Silver
Citizen
Posts: 82
Joined: Mon Aug 22, 2016 2:25 pm

Re: IceGT_'s Hook System (and other extensions)

Postby Sir_Silver » Wed Jan 11, 2017 11:20 am

Well that is an interesting coincidence that another new user just yesterday shared their reinterpretation of gmod's hook library here: viewtopic.php?f=5&t=83345

I remember also making my own version of the hook library in the past. =)

User avatar
IceGT_
Prole
Posts: 3
Joined: Sun Jan 08, 2017 5:27 am

Re: IceGT_'s Hook System (and other extensions)

Postby IceGT_ » Thu Jan 12, 2017 3:33 am

Just added tables, but it's getting a bit too late for me to implement sorting stuff tonight, so that bit should be out tomorrow if all goes well.

Code: Select all

local ok = dothething and pcall( function() assert( loadfile( "hello_world.luac" ) )() end ) or false
if not ok then print( "spilt chocolate milk :(" ) end

User avatar
Sir_Silver
Citizen
Posts: 82
Joined: Mon Aug 22, 2016 2:25 pm

Re: IceGT_'s Hook System (and other extensions)

Postby Sir_Silver » Thu Jan 12, 2017 4:55 pm

Interesting, pretty soon looks like there's gonna be a working version of gmod in love lol.

I was looking at your library there and I noticed a couple of problems - I've made these same mistakes myself.

The function below that you've written will stack overflow if the index metamethod of a table points to itself (you may or may not consider this an issue depending on whether or not you use the metamethods).

Code: Select all

table.copy = function( t )
   
assert( type( t ) == "table", "Passed argument is not a table." )
   
local tab = {}
   
for k,v in next, t, nil do
      
   tab[k] = ( type( v ) == "table" ) and table.copy( v ) or v
   
end
   
return tab

local metatable = {}
metatable.__index = metatable

table.copy(metatable)
-> [string "table.copy = function( t )..."]:3: stack overflow
end


This one just won't work for a very simple reason, your not overwriting the table that you think you are passing, you are overwriting the reference to the table your passing. That's something that took me a while to understand (not saying you don't understand this, could have just been overlooked).

Code: Select all

table.empty = function( t )

   assert( type( t ) == "table", "Passed argument is not a table." )
   
   t = {}

end

local tab = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

table.empty(tab)

for k, v in pairs(tab) do
   print(k, v)
end

->
1   1      
2   2      
3   3      
4   4      
5   5      
6   6      
7   7      
8   8      
9   9      
10   10   


Hope I didn't sound too mean, just trying to help out a fellow programmer :P

User avatar
IceGT_
Prole
Posts: 3
Joined: Sun Jan 08, 2017 5:27 am

Re: IceGT_'s Hook System (and other extensions)

Postby IceGT_ » Thu Jan 12, 2017 6:35 pm

Thanks for pointing that out, the issue with table.empty was def an overlook on my part - table.copy was just me forgetting that circular references exist (whoops). I've pushed the following fixes, though I want your opinion on how the table.copy fix handles stuff, if you don't mind. This is adapted straight from http://lua-users.org/wiki/PitLibTablestuff, which is apparently where Garry ripped his version from.

Code: Select all

table.empty = function( t )

   assert( type( t ) == "table", "Passed argument is not a table." )
   
   for k,_ in next, t, nil do
      
      t[k] = nil
   
   end

end


Code: Select all

table.copy = function( t, st )

   assert( type( t ) == "table", "Passed argument is not a table." )
   
   local tab = {}
   
   for k,v in next, t, nil do
      
      if type( v ) == "table" then
         
         local st = st or {}
         st[t] = tab
         
         tab[k] = ( not ( st[v] == nil ) ) and v or table.copy( v )
      
      else
      
         tab[k] = v
      
      end
   
   end
   
   return tab

end


Output:
Image

Test code:

Code: Select all

local mt = { ["test"] = "4" }
mt.__index = mt

local x = table.copy( mt )

print( "mt __index:" )
print( mt.__index )
print( "x __index:" )
print( x.__index )

print( "mt.test: " .. mt["test"] )
print( "x.test: " .. x["test"] )

x["test"] = "5"

print( "x.test = 5" )
print( "mt.test: " .. mt["test"] )
print( "x.test: " .. x["test"] )

mt.other = "6"

print( "mt.other = 6" )
print( "mt.other: " .. mt["other"] )
print( "x.other: " .. ( x["other"] or "<not set>" ) )

Code: Select all

local ok = dothething and pcall( function() assert( loadfile( "hello_world.luac" ) )() end ) or false
if not ok then print( "spilt chocolate milk :(" ) end


Return to “Libraries and Tools”

Who is online

Users browsing this forum: Germanunkol and 13 guests