Jump to content




read() persisting after parallel waitForAny returned a different function

lua help

  • You cannot reply to this topic
3 replies to this topic

#1 applesauce10189

  • Members
  • 162 posts

Posted 31 July 2017 - 07:43 PM

I'm playing with a lot of mods, I plan to have one central computer that controls many aspects of my base and gathers relevant statistics. None of that's actually in yet, because I was testing it before adding all that and encountered this issue.

The program's called startup so it boots up when you open the computer, and you're greeted with a password prompt. If you put in the password, you'll be taken to a placeholder prompt where read() is called, but I also used the parallel API's waitForAny to have a "logOut" function co-exist with the main function, so at any time I could press f1 to bring back the password prompt, or press f3 to kill the program entirely.

However, if I use f1 to bring back the password prompt, the read prompt from before is still accepting input, and basically providing an uncensored version of what should be asterisks. So basically I need a way to interrupt the read function that was called.

--uncomment this line when ready
--os.pullEvent = os.pullEventRaw
rednet.open("back")

--Set up the 'to do' list on the right monitors
mon = peripheral.wrap("right")
mon.clear()
mon.setCursorPos(1,1)
mon.setTextColor(colors.white)
mon.write("To do list:")
mon.setCursorPos(1,2)
mon.write("1: Finish the machinery line")
mon.setCursorPos(1,3)
mon.write("2: Begin project 'Alpha'")
mon.setCursorPos(1,4)
mon.write("3: Mine. Always need more everything")
mon.setCursorPos(1,5)
mon.write("4: Get a nether star")
mon.setCursorPos(1,6)
mon.write("5: Improve power armor")
mon.setCursorPos(1,7)
mon.write("6: Expand the 'to do' list")

--self explanatory
function myClear(color)
  term.clear()
  term.setCursorPos(1,1)
  term.setTextColor(colors.purple)
  term.write("AppleOS Master Computer")
  term.setCursorPos(1,2)
  term.setTextColor(color)
end

--Bring back the password screen, or kill the program entirely, if these buttons are pushed
function logOut()
  while true do
    blank = " "
key = " "
    blank, key = os.pullEvent("key")
if key == keys.f1 then
 parallel.waitForAny(password, logOut)
elseif key == keys.f3 then
 error("wut")
end
  end
end

--Require a password to access the heart of the computer
function password()
  while true do
    myClear(colors.white)
    term.setCursorPos(1,2)
    term.write("Password: ")
inPass = read("*")
if inPass == "yoloswag" then
 command()
else
 term.setCursorPos(1,3)
 term.setTextColor(colors.red)
 term.write("Nope.")
 sleep(3)
end
  end
end

--do all the fancy things I plan to do with this computer
function command()
  --while true do
    term.write("this is temporary.")
read()
  --end
end


parallel.waitForAny(password, logOut)



I did some research, is the coroutine API something I should look into? I'm very bad with programming, but I'm willing to learn it if that's how I gotta fix this

#2 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 31 July 2017 - 11:45 PM

Instead of using coroutines, try changing the os.pullEvent function to implement the behaviour you seek.

local killed = false
local oldPullEvent = os.pullEvent

function os.pullEvent(filter)
	while true do
		local event, r1, r2, r3, r4, r5 = os.pullEvent()
		--# In place of this comment, check if the event would trigger the custom behaviour and, if so, set killed = true and return an enter key event.
		if not filter or event == filter then
			return event, r1, r2, r3, r4, r5
		end
	end
end

local input = read()
if killed then
    --# Custom behaviour
else
    --# Enter pressed by the user
end
os.pullEvent = oldPullEvent

There are different ways of editing os.pullEvent to cause the behaviour you want. This is only one way of doing it.

Edited by The Crazy Phoenix, 31 July 2017 - 11:47 PM.


#3 Dog

  • Members
  • 1,179 posts
  • LocationEarth orbit

Posted 01 August 2017 - 12:52 AM

A quick and dirty fix would be to wrap your main parallel call in a while loop and replace the parallel call in logOut with a return. That'll cycle the main parallel call and start the routines over, abandoning the read call in command.
function logOut()
  while true do
    _, key = os.pullEvent("key")
    if key == keys.f1 then
      return --# instead of using parallel here, use a return to exit this function and cause the main parallel call to exit and restart
    elseif key == keys.f3 then
      error("wut")
    end
  end
end

...

--# main parallel call
while true do --# use a while loop to restart the parallel call if it exits
  parallel.waitForAny(password, logOut)
end

Edited by Dog, 01 August 2017 - 12:56 AM.


#4 applesauce10189

  • Members
  • 162 posts

Posted 01 August 2017 - 08:02 PM

View PostDog, on 01 August 2017 - 12:52 AM, said:

A quick and dirty fix would be to wrap your main parallel call in a while loop and replace the parallel call in logOut with a return. That'll cycle the main parallel call and start the routines over, abandoning the read call in command.
function logOut()
  while true do
	_, key = os.pullEvent("key")
	if key == keys.f1 then
	  return --# instead of using parallel here, use a return to exit this function and cause the main parallel call to exit and restart
	elseif key == keys.f3 then
	  error("wut")
	end
  end
end

...

--# main parallel call
while true do --# use a while loop to restart the parallel call if it exits
  parallel.waitForAny(password, logOut)
end

Your solution works beautifully, thank you





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users