286 posts
Location
United States
Posted 12 January 2014 - 02:08 AM
I read Bubba's
Advanced Lua Topics - Coroutines (found here
http://www.computerc...ics-coroutines/–thanks Bubba) and Lyqyd's responses to my questions (thanks Lyqyd). I then tried to implement coroutines into my
Real World / MinecraftWorld Time Display Program which I posted in Programs (here
http://www.computerc...isplay-program/).
While the program works better with coroutines implemented (it has fewer hiccups on startup and chunk reloading), I had to abandon full implementation of coroutines because of the
http.get() command. I use this line of code to refresh the time from
http://www.timeapi.org:
time[i].time=(http.get("http://www.timeapi.org/"..(time[i].zone).."/now?format=%25l:%25M%20%25p").readAll())
The code is correct, and it does properly refresh the time values I am displaying. However, using
http.get() appears to cause the coroutine to yield, although I did not expect this behavior. I had to move this code out of the coroutine and into its own function (
refreshTime() in my program). As a result, my code does not really take full advantage of coroutines.
I do not want to repeat the post of my code here, so instead I will link to the pastebin:
http://pastebin.com/AUQfZjRKAm I doing something wrong?
Edited on 30 January 2014 - 12:54 AM
882 posts
Location
Behind you.
Posted 12 January 2014 - 02:17 AM
My guess why it yields is because when you use http.get() it probably sends a signal to that page then waits for a file or an error. That wait might cause the yield.
Don't quote me on it, I'm just now learning how to use both http api and coroutine api.
286 posts
Location
United States
Posted 12 January 2014 - 02:27 AM
That was my first thought as well. However, I would have expected that on an http.request() which is asynchronous. http.get() is synchronous and is not supposed to return until it has either loaded the page or failed to do so. I must be missing something.
7508 posts
Location
Australia
Posted 12 January 2014 - 02:39 AM
http.get does yield, so does
http.post, the only one that does not is
http.request, however you must make your own event loop for this.
here is the code directly from the
bios.lua file so you can see that both
http.get and
http.post yield
-- Install the lua part of the HTTP api (if enabled)
if http then
local function wrapRequest( _url, _post )
local requestID = http.request( _url, _post )
while true do
local event, param1, param2 = os.pullEvent()
if event == "http_success" and param1 == _url then
return param2
elseif event == "http_failure" and param1 == _url then
return nil
end
end
end
http.get = function( _url )
return wrapRequest( _url, nil )
end
http.post = function( _url, _post )
return wrapRequest( _url, _post or "" )
end
end
286 posts
Location
United States
Posted 12 January 2014 - 03:16 AM
Thank you. That is very helpful. Of course, if I am to handle my own event loop for the http.request(), it too will cause my coroutine to yield (won't it?) I will have to think more on this.
7508 posts
Location
Australia
Posted 12 January 2014 - 03:21 AM
yes indeed it will. however with ComputerCraft you have to yield or else the mod will terminate your program. as a note other calls that yield are:
- coroutine.yield (obviously)
- os.pullEvent
- os.pullEventRaw
- read
- sleep
- http.get and http.post
- turtle api except for turtle.getItemCount, turtle.getItemSpace and turtle.getFuelLevel
- rednet.receive
- gps.locate (due to using rednet)
- anything else that asks for user input
Edited on 12 January 2014 - 02:21 AM
286 posts
Location
United States
Posted 12 January 2014 - 03:24 AM
Thank you again. I will have to experiment on how to effectively use coroutines (at least I am starting to use them now).
286 posts
Location
United States
Posted 12 January 2014 - 12:36 PM
I have worked to make my
Real World / MinecraftWorld Time Display Program work well however, for some reason, it sometimes will not run as the startup program when the computer turns on – it just sits there. If I stop it and run it from the shell, it runs fine. Can anyone see what I am doing wrong?
Program located on this forum here ->
http://www.computerc...isplay-program/Pastebin ->
http://pastebin.com/AUQfZjRKI refresh the time variables with the refreshTime() routine, set up two coroutines, fire off my initial timers then start my main loop. Not sure where it is failing to follow through. A fresh set of eyes (and better talent) would be greatly appreciated.
Edited on 12 January 2014 - 11:36 AM
8543 posts
Posted 12 January 2014 - 12:52 PM
Threads merged.
286 posts
Location
United States
Posted 12 January 2014 - 01:17 PM
Strangely enough, the program works fine in my single-player environment. However in my multi-player (same Unleashed version) it hangs on boot up, but will run fine when executed from shell.
286 posts
Location
United States
Posted 12 January 2014 - 02:16 PM
This is a non-problem. It is simply related to the variable amount of time it takes for http.get() to resolve. The code is working. I edited out one piece of inneficiency where I called refreshTime(0 once too often.
Sorry for the trouble.