8 posts
Posted 07 July 2015 - 03:57 AM
I'm trying to get this to work but just couldn't. I have buttons and data to show, and it's suppose to render the data in a constant rate.
so i tried using a timer event, but then it will stop rendering if a click event is applied because the function on the mouse_click has an os.sleep so I added a timer after the function, and now its making like another instance of timer that increases the refresh rate of the data being displayed. and i couldnt use os.sleep because it makes the button unclickable for a fraction of a second. Anybody has idea what's a better way of making this?
EDITED
os.startTimer(0)
while true do
local event ,a,b,c = os.pullEvent()
if event == 'mouse_click' then --buttons
--run a functions 1st function has os.sleep, 2nd function dont have os.sleep (alternate between functions)
--os.startTimer(0.5)
end
if event == 'timer' then
--render stuff on screen
os.startTimer(0.5)
end
end
Edited on 07 July 2015 - 04:18 AM
1220 posts
Location
Earth orbit
Posted 07 July 2015 - 05:39 AM
You're capturing the event in 'a' then comparing to 'event'. Change your two if statements from this…
if event ==
to this…
if a ==
8 posts
Posted 07 July 2015 - 06:18 AM
oh sorry its just a pseudo code, the real code is correct but a clutter mess to post
3790 posts
Location
Lincoln, Nebraska
Posted 07 July 2015 - 06:23 AM
It's much easier to debug if you post the actual code though.
8 posts
Posted 07 July 2015 - 07:34 AM
im sorry, here it is
xKdM0CPAthe part i posted is in the render function
Edited on 07 July 2015 - 05:35 AM
8 posts
Posted 07 July 2015 - 02:49 PM
bump
1220 posts
Location
Earth orbit
Posted 07 July 2015 - 05:49 PM
No need to bump your question - someone will jump in when they have the time.
First, you don't need the sleeps, so you can eliminate those. Second you need to track your timers (by naming them) so that you aren't running multiples and causing the problem you're having. Take a look at
this page (specifically the code example) and see if that gives you what you need to better manage your timers and solve the problem.
504 posts
Location
Seattle, WA
Posted 07 July 2015 - 10:20 PM
Just from taking a look at your pseudo code, I think I have an idea of what you're doing and what you're not doing.
The problems you're seeing are due to the fact that functions you're calling from the main loop and up the stack are making os.pullEvent (coroutine.yield) calls which delay the return back to your loop. If you wanted to have this "main loop" structure, a possible solution would be to call the functions in your main loop inside a coroutine, so they yield back to the main loop.
Something like this, for example:
Spoiler
Here, the main loop runs, waiting for a mouse click in the upper left-hand corner of the screen. Once this event occurs, then the function "stuff" is called which uses the native "read" function, making lots of calls to os.pullEvent which ultimately yield back to our main loop. The main loop's "os.pullEvent" call supplies the active threads with their events through "coroutine.resume."
local function stuff()
term.setCursorPos(1, 1)
-- Grab some input.
local input = read() -- This will call os.pullEvent, yielding back to the resuming caller.
local fileHandle = fs.open("/input.log", 'a')
if fileHandle then
fileHandle.writeLine(input)
fileHandle.close()
else
return false
end
return true
end
-- Removes any dead threads from the table.
local function purge(threads)
local deadKeys = {}
for key, thread in pairs(threads) do
if coroutine.status(thread) == "dead" then
table.insert(deadKeys, key)
end
end
for _, deadKey in ipairs(deadKeys) do
table.remove(threads, deadKey)
end
end
local threads = {}
while true do
local eventData = { os.pullEvent() }
-- Update coroutines if there are any currently alive.
for _, thread in pairs(threads) do
coroutine.resume(thread, unpack(eventData))
end
-- Remove any dead threads.
purge()
-- Mouse click in the origin of the screen -> Get some input there.
if eventData[1] == "mouse_click" and eventData[3] == 1 and eventData[4] == 1 then
table.insert(coroutine.create(stuff))
end
end
1220 posts
Location
Earth orbit
Posted 08 July 2015 - 01:05 AM
fwiw, you could just use the
parallel api (in your case, parallel.waitForAny) - it would be much simpler than managing the coroutines yourself.
local timerID --# define our timer ID using a forward declaration (scripts read from top to bottom; we want this variable available to the entire script so we define it at the beginning)
local function input() --# this will handle mouse click events
while true do
local _, button, x, y = os.pullEvent("mouse_click")
--# do mouse stuff here
end
end
local function timer() --# this will handle timer events
while true do
local _, id = os.pullEvent("timer")
if id == timerID then
--# render stuff on screen
timerID = os.startTimer(0.5)
end
end
end
timerID = os.startTimer(0.5) --# start the timer
parallel.waitForAny(input, timer) --# start the program