Update gui during libcurl?
BlitzMax Forums/Brucey's Modules/Update gui during libcurl?
| ||
I am using the TEasyCurl class to do some FTP uploads. Is there a way for me to update the GUI of my program when I get the progress callback? This is what I have:Function curlProgress:Int(data:Object, dltotal:Double, dlnow:Double, ultotal:Double, ulnow:Double) If ulnow <> 0 Then UpdateProgBar(TMainWindow.progPublish, ultotal / ulnow) RedrawGadget(TMainWindow.MainWindow) RedrawGadget(TMainWindow.progPublish) EndIf EndFunction The window isn't redrawn and the progress bar appears full after the upload finishes - i.e. when I get back to my main loop that calls WaitEvent(). Adding PollEvent() to this not only didn't help (same behavior - no redrawing) but it actually seemed to cause random events to fire elsewhere in my code. Very strange. Anyway, RedrawGadget seems to have no immediate effect - the documentation says it might not redraw the gadget immediately and I'm afraid that's the case at least on Linux. Is there a way to force a redraw? I guess this might be more appropriate in the GUI programming area... but it is a specific problem with libcurl because it makes it sort of hard to use in a GUI program if it isn't possible. Any ideas? |
| ||
I would say some kind of "system" refresh is what you need there - SystemWait() ? However, TEasyCurl is synchronous, so you are going to have issues like this. How's about using the A-synchronous TCurlMulti instead? Rather than waiting until the transfer is finished, it kicks *them* off in the background and relies on you to keep an eye on how they are doing, rather than the other way around. From the ex_05 example, the main loop looks a bit like this : Local status:Int = multi.multiPerform(running) While status = CURLM_CALL_MULTI_PERFORM status = multi.multiPerform(running) Wend While running And status = CURLM_OK ' wait for network If multi.multiSelect() <> -1 Then ' pull in any new data, or at least handle timeouts status = multi.multiPerform(running) While status = CURLM_CALL_MULTI_PERFORM status = multi.multiPerform(running) Wend End If Wend You could stick this on a quick-firing timer, which would mean that your "main" event loop could happily update the UI like normal. |
| ||
This is what I came up with - does this seem right? TProject.Perform() is called by a timer set to 1000 hertz. Type TProject ' ...Snip... Global curlMulti:TCurlMulti = TCurlMulti.Create() Global curlStatus:Int Global curlTimer:TTimer Global curlRunning:Int Function Perform() If Not curlRunning Then Print "No transfers running, stop curl timer" SetStatusText(TMainWindow.MainWindow, "Publish complete") StopTimer(curlTimer) curlTimer = Null Else If curlStatus = CURLM_OK Then ' wait for network If curlMulti.multiSelect(1) <> -1 Then curlStatus = curlMulti.multiPerform(curlRunning) EndIf ElseIf curlStatus = CURLM_CALL_MULTI_PERFORM curlStatus = curlMulti.multiPerform(curlRunning) End If EndIf EndFunction ' ...Snip... EndType It doesn't seem to use hardly any CPU really, even when doing an upload. I have a method of the TProject class (a project is a local dir and a remote location that we want to publish local files to - much like how Coda handles projects) that turns the timer on and adds a new TCurlEasy to the multi. Seems to be pretty slick really. Had a bit of trouble with larger files, it seemed that multiSelect would fail often. A 1 second max timeout for multiSelect seems to work so far, at least with my current network connection and with the files I've tested. Thanks for your help and for the module! Really awesome that I could put this together just using BM modules :) Now if only I had a cross platform file-change notification...... |
| ||
Looks fine :-) Now if only I had a cross platform file-change notification I use it in wxCodeGen, but it's all tied into the wxMax framework... works well, and means I can have wxCodeGen running in the background while I edit wxFormBuilder projects, and as soon as I save it, wxCodeGen re-generates the files. It's like magic ;-) |
| ||
It's like magic ;-) Best kind of code ;) |