[Coroutines] Coroutine Dies Each Time it P...
Geforce Fan 05 Jun 2014
Basicly, my coroutine is dieting every time it pulls an event Note that it is actually running this code
Here's the pastebin to my code
Here's the code:
(some of the functions are useless, this is going through massive restructoring
Edited by Geforce Fan, 05 June 2014 - 01:56 AM.
Here's the pastebin to my code
Here's the code:
(some of the functions are useless, this is going through massive restructoring
if OneOS then if shell.getRunningProgram() == "startup" then --to make sure they're not running this in shell --because if they are it'll crash. OneOS.ToolBarColour = colours.lightGrey end end --Credits: --Developers: --Hithere --APIs --Special thanks to: --oeed, for OneOS, the OS Sapphari was --designed for --DEVELOPER CONFIG local waitForMessage = false -------------------------------------------------- sapphariVersionString = "1.0" sapphariVersionNumber = 1 sapphariSites = {} sapphariBlacklist = {} --TESTS: --might fix some crashes --+function error() --The script sets the news, then sets the url vars shell.run("rom/programs/http/pastebin run Jg8D7mLi") --print("--------------------------------------------------") --It would seem I don't need to kill any functions as OneOS handles that for me :D/>/> --Internal functions local sapphInt = {} function sapphInt.redrawUI() term.setBackgroundColor(colors.white) term.setTextColor(colors.black) local termX, termY = term.getSize() for i=1,2 do paintutils.drawLine(1,i,termX,i,colors.lightGray) end paintutils.drawLine(2,1,termX/3,1,colors.white) paintutils.drawLine(termX/3+2,1,termX/3+3,1,colors.green) --this is the last thing getting drawn, --we do not need to specify length. --writing on it takes care of it term.setCursorPos(termX/3+2,1) term.write("Refresh") --now it's the right length. end --this function will get the data for a site, --however, will not run it. function sapphInt.getSite(pasteID) local responce = http.get("http://pastebin.com/raw.php?i="..pasteID) if responce then return loadstring(responce.readAll()) else return false end end function sapphInt.handleMenu(typeClick, clickX, clickY) --handle the user clicking the menu print"cal1" local termX,termY=term.getSize() if typeClick == 1 then --okay, it's a left click, passes first one' if clickX>1 then --okay, in somewhere special if clickX<termX/3+1 then --okay, the user wants to change the url. term.setCursorPos(2,1) print"cal" input = read() print"dun" --we will return the input which will --be returned until the program must --end, then it will be a temporary --global variable and read by safari --again. Complicated? True. return input end end if clickX>termX/3+1 then if clickX<termX/3+8 then --need to refresh page nao return currentSite end end end end function sapphInt.decodeHumanReadableURL(HRURL) --this is where we attempt to decode a --human readable url. If fails, will tell --calling function to attempt to use the --plain url instead. if sapphariSites[HRURL] then --this must be an HRURL, so we'll give them' --the pasteID currentSite = sapphariSites[HRURL] return sapphariSites[HRURL] else currentSite = HRURL return HRURL --this must be a PasteID then end end --WEBSITE FUNCTON --sapphutils, MUST be global!!! sapphUtils = {} function sapphUtils.pullEvent(filter) print"f" termX,termY=term.getSize() print"redaw" sapphInt.redrawUI() while true do local event, p1, p2, p3, p4, p5, p6, p7 = os.pullEventRaw() --note that pullEvent yields --so we have to make sure we don't --kill the routine while it's checking --for events if event == "mouse_click" and p3==1 then print"handling" if p1 == 1 and p3 == 1 then if p2>1 and p2<termX/3+1 then print"menu" term.setCursorPos(5,5) newSiteq=true clickx=p2 clicky=p3 --okay, it'll be elseif p2>termX/3+1 and p3<termX/3+8 then newSiteq=true clickx=p2 clicky=p3 --okay, it'll be Refresh then. end end if newSiteq then print"die" coroutine.yeild() end end if filter then if event == filter then return event, p1, p2, p3, p4, p5, p6, p7 end else return event, p1, p2, p3, p4, p5, p6, p7 end --if they changed sites, we'll never get here. end end function sapphUtils.read(startx, starty, endx, endy) while true do evt, text = os.pullEvent() if evt == "key" then end end end --this must get the pasteid, not the human --redable url function sapphInt.handleWebsite(url) print"Aliv fn" local rurl = sapphInt.decodeHumanReadableURL(url) print"stil" local site = sapphInt.getSite(rurl) print"loadin sit" coSite = coroutine.create(site) end function sapphInt.handleSapphari() local site = sapphInt.handleWebsite("homepage") --coSite = coroutine.create(site) --handleWebsite does this while coroutine.status(coSite) == "suspended" do coroutine.resume(coSite) end print("it diedz") print(coroutine.status(coSite)) end --------------------------------------------------- sapphInt.handleSapphari()
Edited by Geforce Fan, 05 June 2014 - 01:56 AM.
theoriginalbit 05 Jun 2014
okay so I reduced your code down to the code that actually runs just to make sure of my findings. here is the code that actually runs (I also removed the decodeHumanReadableURL function and passed the pastebin code instead of "homepage")
from this code it is very evident that you don't know how coroutines work, you're grabbing the pastebin code, wrapping it in a coroutine, and running it. However whenever you resume this coroutine you're not giving it any event data so it will never function correctly, nor is your own code yielding meaning the program will eventually be killed. I would suggest having a read up on coroutines and learning how they work, Bubba has a tutorial that will help.
The Code
from this code it is very evident that you don't know how coroutines work, you're grabbing the pastebin code, wrapping it in a coroutine, and running it. However whenever you resume this coroutine you're not giving it any event data so it will never function correctly, nor is your own code yielding meaning the program will eventually be killed. I would suggest having a read up on coroutines and learning how they work, Bubba has a tutorial that will help.
Geforce Fan 05 Jun 2014
didn't read the top bit
Second of all, I did read up on that. I thought pullEvent yielded the coroutine of the event you asked for, not your coroutine.
Edited by Geforce Fan, 05 June 2014 - 03:23 AM.
theoriginalbit 05 Jun 2014
Geforce Fan, on 05 June 2014 - 03:21 AM, said:
First of all I'd like to mention you have removed the almost entire code.
Geforce Fan, on 05 June 2014 - 03:21 AM, said:
Second of all, I did read up on that. I thought pullEvent yielded the coroutine of the event you asked for, not your coroutine.
so when a website script will yield via one of those 3 methods (doesn't matter which) if they supply an argument (i.e. an event they wish to wait for) it is returned from the coroutine.resume you used to resume that routine. So to get this desired event you'd do
local ok, evt = coroutine.resume(coSite)now that the coroutine has yielded, it's time for your script to yield too. now another thing to note, like i said before, is when you resume the routine you're not giving it event data, and this is mainly because you're not yielding. So making sure you yield and that you give the event data, would create a while loop like this
coroutine.resume(coSite) --# need to start the routine, now it will be yielding waiting for an event while coroutine.status(coSite) ~= "dead" do --# checking its not dead is a little better local event = { os.pullEvent() } coroutine.resume(coSite, unpack(event)) endthis will resume the coroutine giving it any event data, however it still doesn't respect any filters that were provided, so you'd do something like this
coroutine.resume(coSite) --# need to start the routine, now it will be yielding waiting for an event local _, filter while coroutine.status(coSite) ~= "dead" do --# checking its not dead is a little better local event = { os.pullEvent( filter ) } --# we don't need to always resume, only if the site needs to resume do we need to _, filter = coroutine.resume(coSite, unpack(event)) end
now there's one last problem and that is if any error is risen in the site it won't be displayed, and that is what the first return value from coroutine.resume is for.
coroutine.resume(coSite) --# need to start the routine, now it will be yielding waiting for an event local ok, filter while coroutine.status(coSite) ~= "dead" do --# checking its not dead is a little better local event = { os.pullEvent( filter ) } ok, filter = coroutine.resume(coSite, unpack(event)) if not ok then error( filter, 0 ) end end
all in all, I'm not too sure why you're running the site in a coroutine, as it currently stands all the code I posted above could be removed and you could simply just run the site code, however I assume you may be doing some extra logic once the site has yielded, like rendering or something.
Geforce Fan 06 Jun 2014
Thanks for the help. This REALLY helps explain coroutines. I was about ready to give up the project but now I can continue!
Actually, it's so that I can start making multiple tabs, like a normal web browser or a computer craft operating system. Also to render the top bar once I start calling those functions in that area.
Actually, it's so that I can start making multiple tabs, like a normal web browser or a computer craft operating system. Also to render the top bar once I start calling those functions in that area.