gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSProgressIndicator movement inside a loop


From: Frederic Stark
Subject: Re: NSProgressIndicator movement inside a loop
Date: Tue, 01 Mar 2005 15:47:20 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.5) Gecko/20031007

Frederico Muñoz wrote:
Warning, long and boring mail ahead.

I have a doubt about the best way to display a progress bar when the
actions that will affect the progress movement are inside a loop.
[...]
I decided to use:

[NSThread detachNewThreadSelector:@selector (installPackage:)
            toTarget:packageManager
            withObject:self];

When you have a problem and the solution is to fork a thread, you generally end up with two problems.

to overcome this (please disregard the "self" bit, I'm just
experimenting for now). I set a autorelease pool in the installPackage
method as per the documentation and now it works, I call [sender
updateProgress] inside the copy loop and the progress bar is updated
in real time. However it was brought to my attention that mixing this
call inside a thread might not be very safe and would produce unpredictable
results. I tried with

[sender performSelectorOnMainThread: @selector(updateProgressWithFile:)
                    withObject: file waitUntilDone: NO];

to be more thread friendly but this doesnt work, since not having it
executing in the main thread (to escape the run loop draw timing) was
the reason I created the thread in the first place, and this way the
problem reapears, the progress bar is only updated after the loop
exits.

So, this is it. I really welcome any advices regarding any issu in
this mail. I must add that dividing the steps into smaller chunks
isn't really doable. I need to update it inside the loop that copies
the file.

You actually have several solutions, I don't know which ones work with GNUstep, but I would recommend option 5:

1/ Separate your work in little chunks. Okay you said you did not want to do that, but I had to say that.

2/ Under NeXTstep, you could draw from a tight loop and call some sort of DPSFlush() to send the drawing to the window server. This was enough to display, but not enough to answer to events (ie: no buttons in the window), but you could cancel anything with the help of NXUserAborted(). Some form of updateWindows also used to do the same thing. More or less, YMMV.

3/ Like in 2, but you handle an inner run loop yourself. This was classic MacOS programming (IIRC, you can do the same in Win32). It basically consist of rewritting one step of the event loop in updateProgress method. You can look at the implementation of -[NSApp run] to grasp some knwoledge of how to do it. In general, the resulting UI are not very responsive, and you may be carefull of launching your install by a performAfterDelay (so you are not in 20 stack frame of UI code already).

4/ Fork a thread. The good thing is that, after fighting with obscure unreproducable bugs for a few days, you'll end up deciding you don't really care about that user interface (or life in general).

5/ Split the code in two processes (or fork). The command line version would do the install and write information on its standard output. The top-level one just listen to the file descriptor in its run loop and update the window.

Cheers,

--fred






reply via email to

[Prev in Thread] Current Thread [Next in Thread]