This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Cranium's profile picture

Minor problems with a timer loop

Started by Cranium, 25 August 2014 - 08:10 PM
Cranium #1
Posted 25 August 2014 - 10:10 PM
So I have a program that constantly monitors power, me storage, and fluid levels. I have a timer set up to refresh every so often, but at the same time waiting for a mouse click. The problem I have is that either due to lag or poor programming, it sometimes takes many clicks to register changing the fluid displayed.
Can anyone improve upon this loop?
http://pastebin.com/iyPUG8XC
hilburn #2
Posted 26 August 2014 - 12:00 AM
I normally try to minimise the amount of checks I use and try to use in order of preference ==, ~=, <, >, <=, >=, I do't know if it has any effect in Lua, but I remember being taught that on microcontrollers that's the order of speed, so I would rewrite your final if statement as something like this:



if events[1] == "mouse_click" and events[2] == 1 then
   if events[4]==8 and events[3]~=1 then
	  if events[3] < 5 then
		 ...
	  elseif events[3] < 7 then
		 ...
	  end
   end
   ...
end

the same logic could be used earlier in your program with your other ifs however another thing I would tend to do in this case would be to create a lookup table with keys from 0 to 100 that listed the colour to use, so instead of doing a big control statement where really the only thing you are changing is the colour you are using as the background, you just pass

term.setBackgroundColour(colourLookup[fluidInfo[selected].percent])

As again, a lookup is faster than a bunch of ifs

I'm not sure how much this will help, but I hope it does a bit
Bomb Bloke #3
Posted 26 August 2014 - 03:56 AM
At a glance, the code in the paste looks ok to me.

What I'm not sure about is whether or not the peripheral functions you're calling pull events from the event queue. If any of them do - and it's not all that uncommon, even if they don't "look" like they need to - then they'll randomly consume your mouse click events depending on when you happen to click.

In which case you'd want to rig something up with the parallel API (simply so you've got an unpillaged queue to get the events you want from):

local function redraw()
	while true do
		os.pullEvent("redraw")
		
		-- Code to draw the main display here.
	end
end

local function getInput()
	while true do
		local events = {os.pullEvent()}
		
		-- Code to pick up on mouse clicks here.
		
		-- Whenever you want to run the redraw() function, do os.queueEvent("redraw")
	end
end

parallel.waitForAny(redraw, getInput)

Also bear in mind that if you're in a server environment, ComputerCraft may screw up the click detection on external monitors (rather more often than it usually does - CC 1.6 has been giving me issues even in SSP, but the SMP thing applies to that and earlier builds). So if you're using the "monitor" script to run this code on an external display, ditch that approach for your tests.
Edited on 26 August 2014 - 02:15 AM
Cranium #4
Posted 26 August 2014 - 07:50 PM
Yeah, not sure if events are being fired at all. I might have to try out separate loops, and *gulp* end up using the parallel api…
And no, not using external monitors. I might do that eventually, and actually display all fluids at once.
Cranium #5
Posted 26 August 2014 - 09:17 PM
I think I'm going to just ditch mouse and timer events, and have it draw to a large monitor.
[acronym='Famous Last Words']It should be easy enough to do[/acronym].
Edited on 26 August 2014 - 07:17 PM