Reading the table of timers.

So I’ve got this little conundrum that I’m sure can easily be solved by someone more skilled in the art of Lua than myself.

In the file garrysmod/lua/includes/modules/timer.lua garry defines the functions for everything timer related. Inside that file, he creates a local table, called ‘Timer’. I’d like to be able to actually read that table, but I keep getting confundled. I’ve tried the following (please don’t laugh at me):

note: this code is all within timer.lua



function All()

	return Timer
	
end


Trying to run this function either as timer.All() or simply All() returns an undefined function.

I’ve tried


 PrintTable( Timer ) 

inside the file just to print it to my console, but it gives me this error:



Unhandled Lua Refresh: [NAME:includes/modules/timer.lua] [TYPE:]


if I restart my game with the code still there, it simply does not print the table.

The last thing I’ve tried is modifying the timer.Create function to MsgN the timer name, like this:



function Create( name, delay, reps, func, a, b, c )

	if ( !isfunction( func ) || a != nil || b != nil || c != nil || !isnumber( delay ) || !isnumber( reps ) ) then
		error( "timer.Create - called wrong!
" )
		return
	end
	
	MsgN( name )

	if ( Exists( name ) ) then
		Destroy( name )
	end
	
	Adjust( name, delay, reps, func )
	Start( name )

	local timerObj = TIMER_CLASS.New()
		timerObj.name = name
	return timerObj;
end


That doesn’t MsgN anything. I’m confused. Help?

Never heard of printTable before, have you tried print(table.tostring(Timer))
?

Same result as PrintTable( Timer ). First it errors saying it can’t use lua autorefresh, and upon restarting my game, nothing prints.

edit: http://samuelmaddock.github.io/glua-docs/#Global.PrintTable

Try disabling autorefresh in the startup parametres?

I don’t see how that would possibly help. I’m restarting the server after every change to the code anyways, and it’s not working. What would disabling auto refresh possibly hope to achieve?

Well you seem to be having issues with it, I felt it a logical test to perform.

Fair enough. I tried it, didn’t notice a difference except the error message I get about the unhandled refresh is gone. Same end behavior though.

remove timer.lua from cfg/nosend.txt

Imgur

There’s a picture of my cfg directory. Am I supposed to look somewhere else than that?

You can’t modify the timer module file on a listen server, I thought you were running a srcds dedicated server.

Oh. So is there any way to read the timer table on a listen server?

Make your own module to replace the existing one. Timer2.lua

Timer =Timer2

Sorry, I’m very much a beginner in many aspects of Lua. So I should effectively copy and paste the timer.lua file to a new file, and simply change the name? Will that give me control of the timer module?

Am I right in assuming you have put the PrintTable in the module file? Add this at the top of the file if you have:



local PrintTable = PrintTable


To my understanding, each module creates it’s own fenv, so you won’t have direct access to the _G environment.

I’ve done that, but still no dice. What I’d really like to do is to add my own function to the module that will just return the table. Is there any way to do that?

There is no easy way of doing it. You could call the a timer function that uses the Timer table and use the debug library to get locals (You will need to start in the second thread) but short of that, You can’t modify the timer.lua file.
I would suggest you go what Gfoose said.

No using the debug library to get locals sounds perfect! I’ve looked around and the debug library is fairly undocumented. Could you possibly help me out in this regard?

[editline]21st January 2014[/editline]

Alrighty so I’ve made a fair amount of progress:

First: Here’s the function I’m using to debug. timer.Create.



function Exists( name )

	return Timer[name] != nil

end


and here is the code I have in an attempt to debug it:



local function test()
	
	local co = coroutine.create( timer.Exists )
	debug.sethook( co, function()
		
		local k, v = debug.getlocal( 2, 1 )
		print( k, v )
		
	end, "c" )

end

test()


It prints I giant list of values, and I’ve crashed my game more times than I can count fooling around with those values.

I tried using debug.getregistry, but the timer table isn’t stored there. I tried using debug.getupvalue, but if you use debug.getinfo( timer.Exists ) you can see that the function contains no upvalues, so I’ve b een trying to use this. Unfortunately at this point I’m quite confused. Any help would be grealy appreciated.

I wouldn’t use the ‘c’ debug hook, Because that will get called every time a function get’s called. I am in college right now so I can’t exactly post any code that will help but here is an approximation of how I would do it:



local Timer = { ['test'] = 'test',
		['test2'] = 'test'
}

function Exists( name )

	return Timer[name] == nil and false or true

end

do

	Exists( 'Test' )
	local t = {}
	local key , value = debug.getlocal( 1 , 1 )
	for k,v in pairs(value) do
		print(k,v)

	end

end


will output:



test	test
test2	test


Using the Lua online demo. (Hence why I had to create the function and table.)

But the problem with that is that none of the new code I put inside the timer.lua code actually runs. Even simple print statements do not run. I’ve included them at the top of the file as well. So I figure I’ve got to do this from outside the file, which is what makes it so tough.

timer.lua isn’t used anymore, the timer module is handled by the engine nowadays.