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

how to get around script hanging, due to os.pullevent

Started by trey777, 01 February 2016 - 07:53 PM
trey777 #1
Posted 01 February 2016 - 08:53 PM
hello, my name is steven/trey if you want. im in the middle of making a new banking system and a DNS system with routers. Let me talk about the program before i get into my questions and issues…

The banking system is comprised of essentially 3 computers: terminal,router,server. i could go further but this already adds up to 48 terminals to access in my world if i where to web it out for you guys.

each router has 2 ports. each port has a generated access key. When a terminal boots it looks for a conection. the terminal sends out a ping to any local routers.when a router gets a ping it assigns the terminal to a port and sends out the key and a port number to use. the port validation key changes with every transmition to the router just to keep things harder for hackers and what not. the ports are to make sure messages to the server are sent and not obstructed by other communications with terminals. ps i could go further with algorithmic equations to jumble tranmitions but thats allot of work…

the router accesses the local server using the same method of finding/searching for it and then connecting allong with generated keys for them. (not implemented yet.. i hit an issue with the terminals)


the issue with my terminal is since the user which is anyone has to type on the machine. this hangs the script… there is a constant line of communication between the router and the terminal and typing would interrupt the flow…

there is a ping comming from the router on each port to make sure the connection has not been lost… a lost connection could mean tamporing which means the router needs to clear the port and generate a new validation_key…

so i dont need this script to hang…

i can on the otyher hand just add another computer to the terminal and have that be the user interface for the terminal pc but thats more coding in the long run and more lag between the systems..


is there any way that i can put the receiving rednet code on a script in the background and have the user interface run in the forground with os.pullevents.???
eniallator #2
Posted 01 February 2016 - 09:10 PM
What i have done to get around this is to just run 2 programs (files) on the computer using the bg [file name] program thats already on there. The way they communicate to eachother is through yet another file that you can store a table in e.g textutils.serialise() & textutils.unserialise().

this is one method i thought of but theres probably a better way to do it.
Dog #3
Posted 01 February 2016 - 09:12 PM
A quick answer is yes, you can do this. If I'm not mistaken, you can use os.pullEvent to look for rednet messages like so…

local event, id, msg = os.pullEvent("rednet_message")

So you could essentially look for your user inputs and rednet messages within the same loop…

local event = { os.pullEvent() }
if event[1] == "rednet_message" then
  --# do rednet stuff
elseif event[1] == "mouse_click" then
  --# do mouse click stuff
elseif ... (etc.)
end

In the example above, I captured the output of os.pullEvent in a table instead of trying to come up with clever names for each possible variable (since the second variable could be rednet ID, or mouse X, or…). If you'd prefer not to use a table, for whatever reason, you can do it like this…

local event, data1, data2, data3, data4, data5 = os.pullEvent()
if event == "rednet_message" then
  --# do rednet stuff
elseif event == "mouse_click" then
  --# do mouse click stuff
elseif... (etc.)
end

Another option would be to use parallel.waitForAny(), but that gets a little more complex. I'd recommend using one of the examples above. If, otoh, you really want to use parallel.waitForAny() then you would do it something like this…

local function netReceive()
  while true do
    --# rednet receive stuff
  end
end

local function userInput()
  while true do
    --# user input stuff
  end
end

parallel.waitForAny(netReceive, userInput)
Edited on 01 February 2016 - 08:14 PM
trey777 #4
Posted 01 February 2016 - 09:20 PM

dog: i see what you mean in the first example but my program looks for stuff on the router and terminal. like looks for 5 seconds and then does calculations. hanging with os.pull in the main script isnt viable.



eniallator i reall like that answer home boy :)/>/> so your saying i can have the main script act as the user interface EG: type in user info and log in and chang ballance stuff, while the back ground scripts look for data and send data to the router ?
Dog #5
Posted 01 February 2016 - 10:05 PM
dog: i see what you mean in the first example but my program looks for stuff on the router and terminal. like looks for 5 seconds and then does calculations. hanging with os.pull in the main script isnt viable.
In that case you'd want to use the parallel API or eniallator's suggestion. The difference being that using the parallel API would allow you to have everything in one program and wouldn't require a text file.
Bomb Bloke #6
Posted 01 February 2016 - 10:09 PM
dog: i see what you mean in the first example but my program looks for stuff on the router and terminal. like looks for 5 seconds and then does calculations. hanging with os.pull in the main script isnt viable.

Just in case this isn't clear to you, rednet.receive() is also functioning by calling os.pullEvent().

eniallator i reall like that answer home boy :)/> so your saying i can have the main script act as the user interface EG: type in user info and log in and chang ballance stuff, while the back ground scripts look for data and send data to the router ?

Indeed, this is much the same as using the parallel API to handle it, only that makes it easier to put all the code into one script file.

Edit: :ph34r:/>'d
Edited on 01 February 2016 - 09:10 PM
trey777 #7
Posted 01 February 2016 - 10:40 PM
how would i go about running a script in the background of the app

also there is one more thing.

this is a copy from the wiki, what does this last line indicate. when one of the parallels finishes they both finish ?? this is whty im in favor of multi scripts at leased for my application.

im not sure how running mutiple scripts work… does this open tabs or does it simply run in the back ground by loading the script and running without the indication of a tab open??

also i need to know if timers work inside the functions like normal?? allot of the code is based of timers to check, send and reset data for packets.
Edited on 01 February 2016 - 10:46 PM
Dog #8
Posted 02 February 2016 - 04:17 PM
If I understand correctly, your terminal code is supposed to process user input *and* handle rednet messages simultaneously, but it's currently 'hanging' while waiting for user input. Post that code to pastebin and put the link here.

As for timers, yes they work inside functions like normal.
KingofGamesYami #9
Posted 02 February 2016 - 04:57 PM
I'm not sure if you'd like to use it or not, but I've created an API that is intended for situations like this one. You'd have to re-write your program entirely to use it though.

It'd be something like this:

os.loadAPI( "statemachine" )
local uread = statemachine.unblock( read )
local ureceive = statemachine.unblock( rednet.receive )
statemachine.setLoop( function()
  local complete, input = uread()
  if complete then
    --#do stuff with input
  end
  local complete, id, message = ureceive()
  if complete then
    --#do stuff with id and message
  end
end )
statemachine.run()