[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSProgressIndicator movement inside a loop
From: |
Frederico Muñoz |
Subject: |
Re: NSProgressIndicator movement inside a loop |
Date: |
Thu, 03 Mar 2005 11:02:31 +0100 |
Hi,
Thank you very much for your answer.
On 2005-03-01 14:47:20 +0000 Frederic Stark <address@hidden> wrote:
> 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.
>
Ehehe, well, it was the solution I came up by using Google.
(...)
> 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.
>
It's not that I can't do it, it would just lose the any interested. I find this
all very weird since providing feedback inside a loop is the situation where
NSProgressIndicator makes most sense for me, any operation that e.g. loops
trough a enumerator with file names (checking, installing, copying) is where it
is interesting to have a progress bar (and indeed NeXT Installer.app did
this).There isn't a way that I can see to divide this kind of operations in
small chunks.
> 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.
I don't think this is available using GNUstep.
>
> 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).
Sounds interesting, but a whole lot of work and high probability of me messing
it up and just crashing the whole app at random.
>
> 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).
>
LOL!
The funny thing is, although I agree that using threads many times is an added
complexity that worsens things, in my particulat case it actually works, and
works everytime. It is probably because the thread doesn't need to interact
very much with the main one.
> 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.
>
WOuldn't I run into the same problem using NSTask for doing this? I mean, it
would probably block waiting for the FD output, or is I used nonblocking
wouldn't the resulting progress bar be updated at more or less "random"
intervals, according to whenever the main run loop actually updatedd the
progress bar?
I will look into this last alternative closer, thanks you again.
However, and while I, as said, agree with the probable issues that can result,
what I'm doing now, and without any side effect for now, is to call the
installPackage on a NSThread and then make the installPackage method send a
notification each time it does something with a file. Then, in the main object,
I register it for the notification with the updateProgress method. Since I'm
not directly dealing with variables between them (what I need is simply to be
notified, and everything else like the filename can go into a NSDirectory and
passed inside the notification) I think I'm pretty safe, at least while this is
the only thing I need to do. The updateProgress then deals with the
progressIndicator. I've tested this approach many times and it works perfectly
everytime. Since I'm using a notification and not calling an object directly
maybe this will help to keep the side effects down.
Again, thnk you for your advice, was really helpful.
Best Regards,
fsmunoz
--
Frederico Muñoz
address@hidden