215 posts
Location
Netherlands
Posted 18 November 2013 - 12:13 PM
Hello everyone!
I was in my mine today and I am using a simple branching program (link here:
http://pastebin.com/TjELb1rj) and the program is working like a charm. Now is a negative side effect that you can really fall far behind if the branch contains alot of ores.
Now is my question: Is there any way to stop the turtle (for example pressing spacebar) to pause the program and if I press spacebar again to let it continue? Could you give me a script example? It would be really appreciated :)/>
Edited on 19 November 2013 - 02:30 AM
463 posts
Location
Germany
Posted 18 November 2013 - 12:45 PM
My implementation of a pause functionality would be like that:
local pause = false
local runprogram = true
local pausekey = 123 -- I don't know the post key id
function programloop()
while runprogram do
while not pause do -- do stuff when the program is not paused, you can replace this with anything, only the sleep(0) is important
sleep(0)
-- do turtle stuff
end
while pause do
sleep(0)
end
end
end
function waitforspace()
while runprogram do
while not pause do
local ev = {os.pullEvent("key")}
if ev[2] == pausekey then
pause = true
break
end
end
while pause do
local ev = {os.pullEvent("key")}
if ev[2] == pausekey then
pause = false
break
end
end
end
end
parallel.waitForAny(waitforspace, programloop)
215 posts
Location
Netherlands
Posted 18 November 2013 - 02:47 PM
My implementation of a pause functionality would be like that:
local pause = false
local runprogram = true
local pausekey = 123 -- I don't know the post key id
function programloop()
while runprogram do
while not pause do -- do stuff when the program is not paused, you can replace this with anything, only the sleep(0) is important
sleep(0)
-- do turtle stuff
end
while pause do
sleep(0)
end
end
end
function waitforspace()
while runprogram do
while not pause do
local ev = {os.pullEvent("key")}
if ev[2] == pausekey then
pause = true
break
end
end
while pause do
local ev = {os.pullEvent("key")}
if ev[2] == pausekey then
pause = false
break
end
end
end
end
parallel.waitForAny(waitforspace, programloop)
Can you maybe go through the waitForSpace part step by step so I can maybe personalize it to my likings and understand it?
331 posts
Posted 18 November 2013 - 03:40 PM
function waitforspace() --# make another function to run along side to wait for a pause key
while runprogram do --# this is here so even while paused this will still run
while not pause do --# if it is not paused continue
local ev = {os.pullEvent("key")} --# capture a key press
if ev[2] == pausekey then --# see if key was pause key
pause = true --# pause program
break
end
end
while pause do --# if its paused run this loop because of the runprogram loop still running
local ev = {os.pullEvent("key")} --# capture a key press
if ev[2] == pausekey then --# see if key is pause key
pause = false --#unpause it
break
end
end
end
end
Edited on 18 November 2013 - 02:40 PM
7083 posts
Location
Tasmania (AU)
Posted 18 November 2013 - 05:08 PM
You might consider using
os.queueEvent() here. The idea is that your "programloop" function periodically checks to see if "pause" is true, then if it IS, rather then sleep(0)'ing over and over again flat out, it waits for a custom event type that you'll create when the program unpauses.
Eg:
local pause,runprogram = false,true
function programloop()
while runprogram do
if pause then os.pullEvent("unpause") end
-- Perform turtle tasks.
end
end
function waitforspace()
local ev
while runprogram do
ev = {os.pullEvent("key")}
if ev[2] == keys.space then pause = not pause end
if not pause then os.queueEvent("unpause") end
end
end
parallel.waitForAny(waitforspace, programloop)
Depending on the structure of your current program, you may need to insert multiple checks to see if it should "pause".
8543 posts
Posted 18 November 2013 - 06:04 PM
Instead of the above suggestions, you should create a program that manages the actual program in a coroutine. It would watch the events coming through, and when it saw the space key event come through, it would stop resuming the program, and keep track of any other events it received in a table, until it got the space key again. Then it would play back the stored events (so as not to miss any turtle movement events, but maybe you only want to store those and no others, up to you) and then resume cycling events into the controlled coroutine as usual. Trying to use parallel for this is like trying to put a square peg in a round hole.
215 posts
Location
Netherlands
Posted 19 November 2013 - 03:30 AM
Instead of the above suggestions, you should create a program that manages the actual program in a coroutine. It would watch the events coming through, and when it saw the space key event come through, it would stop resuming the program, and keep track of any other events it received in a table, until it got the space key again. Then it would play back the stored events (so as not to miss any turtle movement events, but maybe you only want to store those and no others, up to you) and then resume cycling events into the controlled coroutine as usual. Trying to use parallel for this is like trying to put a square peg in a round hole.
Could you maybe give an example, Lyqyd?
8543 posts
Posted 19 November 2013 - 11:06 AM
You might give this a shot. Save it as something like "pauseable", then run `pauseable myProgram` if your program's name is "myProgram".
local eventsCache = {}
local args = {...}
if #args < 1 then
print("Usage:"
print(fs.getName(shell.getRunningProgram()).." <program> [arguments]")
return
end
local co = coroutine.create(function() shell.run(unpack(args)) end)
local paused = false
local event = {}
local filter
local function resume(ev)
if coroutine.status(co) == "dead" then return false end
if not filter or (filter and filter == ev[1]) or ev[1] == "terminate" then
ret, filter = coroutine.resume(unpack(ev))
return ret
end
return "skipped"
end
while true do
if not paused then
if not resume(event) then return end
else
table.insert(eventCache, event)
end
event = {os.pullEventRaw()}
if event[1] == "char" and event[2] == " " then
paused = not paused
if not paused then
for i = 1, #eventCache do
resume(table.remove(eventCache, 1))
end
end
end