Progress bar design pattern

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Progress bar design pattern

tinchodias
Hello

I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.

The progress bar should be pluggable and decoupled of the algorithms.

I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.

The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.

Thanks,
Martin


Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

Daniel Lyons

On Mar 29, 2011, at 6:17 PM, Martin Dias wrote:

I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.

The progress bar should be pluggable and decoupled of the algorithms.

I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.

The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.

I'm a newcomer here, so I'm sharing my experience with non-Smalltalk systems and my best guess what would constitute good designs. I hope other real Smalltalkers will poke some holes in this and point out the right way to do things! ;)

The simplest design, IMO, would be this API:

MyProgressBar>>percentComplete: aNumber
MyProgressBar>>beIndeterminant
MyProgressBar>>beDeterminant

You would manually invoke percentComplete: with a new percent complete each time you want to advance the progress bar. I've seen this kind of thing in practice somewhere. Maybe it was Cocoa?

The next level of abstraction would be to go a bit more jQuery UI and remove percentComplete: and use this instead:

MyProgressBar>>maximum: anInteger
MyProgressBar>>current: anInteger

Now you'll calculate the progress bar based on some quantity of "tasks" you want to do. You could even go further and just have:

MyProgressBar>>incrementProgress

instead of letting your clients tell you which one they're on. That would prevent progress bar relapse. Either of these would be easy to implement on top of the above API using percent.

The simplest observer-type pattern would be to rely on the built-in observer/event system and use the stuff from Object's updating protocol or events-registering or events-triggering. I don't know which one of these is modern or preferred. Anybody? :) At any rate, they make it possible to expose a simple object/message protocol as in Polymorph, where your progress bar widget would be listening for change notifications from your domain object. Then you can ask the same questions about your model as above, in terms of whether you want to work in terms of simply percent complete or N/M or what. 

Another question is whether or not you want to provide a string message status to go under the progress bar.

Does this help at all, or did I miss the point?

— 
Daniel Lyons

Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

Henrik Sperre Johansen

On Mar 30, 2011, at 7:13 23AM, Daniel Lyons wrote:


On Mar 29, 2011, at 6:17 PM, Martin Dias wrote:

I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.

The progress bar should be pluggable and decoupled of the algorithms.

I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.

The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.

I'm a newcomer here, so I'm sharing my experience with non-Smalltalk systems and my best guess what would constitute good designs. I hope other real Smalltalkers will poke some holes in this and point out the right way to do things! ;)

The simplest design, IMO, would be this API:

MyProgressBar>>percentComplete: aNumber
MyProgressBar>>beIndeterminant
MyProgressBar>>beDeterminant

You would manually invoke percentComplete: with a new percent complete each time you want to advance the progress bar. I've seen this kind of thing in practice somewhere. Maybe it was Cocoa?

The next level of abstraction would be to go a bit more jQuery UI and remove percentComplete: and use this instead:

MyProgressBar>>maximum: anInteger
MyProgressBar>>current: anInteger

Now you'll calculate the progress bar based on some quantity of "tasks" you want to do. You could even go further and just have:

MyProgressBar>>incrementProgress

instead of letting your clients tell you which one they're on. That would prevent progress bar relapse. Either of these would be easy to implement on top of the above API using percent.

The simplest observer-type pattern would be to rely on the built-in observer/event system and use the stuff from Object's updating protocol or events-registering or events-triggering. I don't know which one of these is modern or preferred. Anybody? :) At any rate, they make it possible to expose a simple object/message protocol as in Polymorph, where your progress bar widget would be listening for change notifications from your domain object. Then you can ask the same questions about your model as above, in terms of whether you want to work in terms of simply percent complete or N/M or what. 

Another question is whether or not you want to provide a string message status to go under the progress bar.

Does this help at all, or did I miss the point?

— 
Daniel Lyons

I've used Announcements for this in the past, and liked it quite alot.

- Worker announces WorkCompleted or some such.
Announcement holds details of the work it's done, in my case different properties of an analysis like leak rate, .

- GUI/Client is set up before analysis starts, and initialized with the total work to be done. 
Annnouncement handling contains code to estimate how much progress the Work indicated by it was of the overall total.

I also used a different client which provided ETA based on a more sophisticated analysis of the Work announcements. 

Needless to say, there's no hard dependency on a UI in such a scheme, as there simply won't be any clients instantiated if you run headless. (well, unless you make one writing to stdout or something)

Not sure what would be reasonable to put in a Work-annnouncement intended as superclass for custom solutions...
In other words, the downside is that this approach doesn't lead to something you can use out-of-the-box, you always have to do some customization, either/both to what data you provide, or/and to how you give feedback.
(In this case, a  standard widget using the simplest design you described is preferrable, btw, the pluggability is done at a different level than the widget)

Cheers,
Henry
Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

Henrik Sperre Johansen
In reply to this post by tinchodias

On Mar 30, 2011, at 2:17 23AM, Martin Dias wrote:

> Hello
>
> I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.
>
> The progress bar should be pluggable and decoupled of the algorithms.
>
> I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.
>
> The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.
>
> Thanks,
> Martin

If my previous post wasn't crystal clear:
 I've used this pattern in the past, it works like a charm :)

I'd recommend just using a simple progress bar widget though, and putting the pluggability at a different level.
This is more of a pattern than a framework, it's hard to make a one-size-fits-all solution.
Not to mention using a simple API for updating the widget itself makes it easier later on to substitute if you find a different visualization would be better.

Cheers,
Henry
Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

tinchodias
In reply to this post by Daniel Lyons
Hi!

On Wed, Mar 30, 2011 at 2:13 AM, Daniel Lyons <[hidden email]> wrote:

On Mar 29, 2011, at 6:17 PM, Martin Dias wrote:

I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.

The progress bar should be pluggable and decoupled of the algorithms.

I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.

The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.

I'm a newcomer here, so I'm sharing my experience with non-Smalltalk systems and my best guess what would constitute good designs. I hope other real Smalltalkers will poke some holes in this and point out the right way to do things! ;)

The simplest design, IMO, would be this API:

MyProgressBar>>percentComplete: aNumber
MyProgressBar>>beIndeterminant
MyProgressBar>>beDeterminant

Sorry, what is an indeterminant progress bar?
 

You would manually invoke percentComplete: with a new percent complete each time you want to advance the progress bar. I've seen this kind of thing in practice somewhere. Maybe it was Cocoa?

The next level of abstraction would be to go a bit more jQuery UI and remove percentComplete: and use this instead:

MyProgressBar>>maximum: anInteger
MyProgressBar>>current: anInteger

Now you'll calculate the progress bar based on some quantity of "tasks" you want to do. You could even go further and just have:

MyProgressBar>>incrementProgress

instead of letting your clients tell you which one they're on. That would prevent progress bar relapse. Either of these would be easy to implement on top of the above API using percent.

The simplest observer-type pattern would be to rely on the built-in observer/event system and use the stuff from Object's updating protocol or events-registering or events-triggering. I don't know which one of these is modern or preferred. Anybody? :) At any rate, they make it possible to expose a simple object/message protocol as in Polymorph, where your progress bar widget would be listening for change notifications from your domain object. Then you can ask the same questions about your model as above, in terms of whether you want to work in terms of simply percent complete or N/M or what. 


I was looking to use String>>displayProgressAt:from:to:during:. The example shown on its comment is:

'Now here''s some Real Progress'
    displayProgressAt: Sensor cursorPoint
    from: 0 to: 10
    during: [:bar |
    1 to: 10 do: [:x | bar value: x.
            (Delay forMilliseconds: 500) wait]].

But my doubt was how to connect the algorithm progress with that "bar value: x".

I would like to avoid that the model (my serialization algorithm) explicitly speak of percentages, I prefer the calculus of the percentage to be done in another place, some observer that interprets the progress and then updates the bar.

I will try to follow the idea I understood of your last paragraph:

I will have the algorithm run reified in a class, let say MyAlgorithmRun, which sends itself #changed each time it has progressed, and a dependent, let say an instance of MyAlgorithmRunProgressObserver, receives an #update:. Then the observer interprets the current state of the run, and sends #value: to the UI progress bar.

Is it okay?

 
Another question is whether or not you want to provide a string message status to go under the progress bar.

Does this help at all, or did I miss the point?


Yes! for me it's very useful to think, thanks!
 
— 
Daniel Lyons


Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

Daniel Lyons
On Thu, Mar 31, 2011 at 04:58:04PM -0300, Martin Dias wrote:
> > The simplest design, IMO, would be this API:
> >
> > MyProgressBar>>percentComplete: aNumber
> > MyProgressBar>>beIndeterminant
> > MyProgressBar>>beDeterminant
> >
>
> Sorry, what is an indeterminant progress bar?

On your Mac, it's the barber pole; on Windows, it's when the progress
bar just sort of throbs. It's for when you initially are calculating
how long the task is going to take, or for cleanup after the task is
complete.

--
Daniel

Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

tinchodias
In reply to this post by Henrik Sperre Johansen


On Wed, Mar 30, 2011 at 6:12 AM, Henrik Johansen <[hidden email]> wrote:

On Mar 30, 2011, at 7:13 23AM, Daniel Lyons wrote:


On Mar 29, 2011, at 6:17 PM, Martin Dias wrote:

I have a couple of algorithms and I want to show the progress while they run. I played with the progress bar and it's okay for my needs.

The progress bar should be pluggable and decoupled of the algorithms.

I am writing to you to ask about good designs for my problem. I hope I haven't expressed the problem in a too abstract way.

The design I have in mind is a kind of observer pattern: the serialization algorithm publishes information about the run; a specific listener implements the progress bar for that serialization algorithm, interpreting the information published.

I'm a newcomer here, so I'm sharing my experience with non-Smalltalk systems and my best guess what would constitute good designs. I hope other real Smalltalkers will poke some holes in this and point out the right way to do things! ;)

The simplest design, IMO, would be this API:

MyProgressBar>>percentComplete: aNumber
MyProgressBar>>beIndeterminant
MyProgressBar>>beDeterminant

You would manually invoke percentComplete: with a new percent complete each time you want to advance the progress bar. I've seen this kind of thing in practice somewhere. Maybe it was Cocoa?

The next level of abstraction would be to go a bit more jQuery UI and remove percentComplete: and use this instead:

MyProgressBar>>maximum: anInteger
MyProgressBar>>current: anInteger

Now you'll calculate the progress bar based on some quantity of "tasks" you want to do. You could even go further and just have:

MyProgressBar>>incrementProgress

instead of letting your clients tell you which one they're on. That would prevent progress bar relapse. Either of these would be easy to implement on top of the above API using percent.

The simplest observer-type pattern would be to rely on the built-in observer/event system and use the stuff from Object's updating protocol or events-registering or events-triggering. I don't know which one of these is modern or preferred. Anybody? :) At any rate, they make it possible to expose a simple object/message protocol as in Polymorph, where your progress bar widget would be listening for change notifications from your domain object. Then you can ask the same questions about your model as above, in terms of whether you want to work in terms of simply percent complete or N/M or what. 

Another question is whether or not you want to provide a string message status to go under the progress bar.

Does this help at all, or did I miss the point?

— 
Daniel Lyons

I've used Announcements for this in the past, and liked it quite alot.

I will take a look on that.
 
- Worker announces WorkCompleted or some such.
Announcement holds details of the work it's done, in my case different properties of an analysis like leak rate, .

- GUI/Client is set up before analysis starts, and initialized with the total work to be done. 
Annnouncement handling contains code to estimate how much progress the Work indicated by it was of the overall total.

I also used a different client which provided ETA based on a more sophisticated analysis of the Work announcements. 

Wow! I don't need to estimate time but it's very interesting think on that.
 

Needless to say, there's no hard dependency on a UI in such a scheme, as there simply won't be any clients instantiated if you run headless. (well, unless you make one writing to stdout or something)

Not sure what would be reasonable to put in a Work-annnouncement intended as superclass for custom solutions...
In other words, the downside is that this approach doesn't lead to something you can use out-of-the-box, you always have to do some customization, either/both to what data you provide, or/and to how you give feedback.
(In this case, a  standard widget using the simplest design you described is preferrable, btw, the pluggability is done at a different level than the widget)

In this moment I am interested in a simple solution, I will not write a framework, but I like the discussion. Thanks!
 
Cheers,
Henry

Reply | Threaded
Open this post in threaded view
|

Re: Progress bar design pattern

tinchodias
In reply to this post by Daniel Lyons
On Thu, Mar 31, 2011 at 5:28 PM, Daniel Lyons <[hidden email]> wrote:
On Thu, Mar 31, 2011 at 04:58:04PM -0300, Martin Dias wrote:
> > The simplest design, IMO, would be this API:
> >
> > MyProgressBar>>percentComplete: aNumber
> > MyProgressBar>>beIndeterminant
> > MyProgressBar>>beDeterminant
> >
>
> Sorry, what is an indeterminant progress bar?

On your Mac, it's the barber pole; on Windows, it's when the progress
bar just sort of throbs. It's for when you initially are calculating
how long the task is going to take, or for cleanup after the task is
complete.


Ah! I need that. During big part of the run I don't know the size of the task.
 
--
Daniel