ui factory - what should it do?

Robert Collins robertc at robertcollins.net
Tue Feb 21 23:08:46 GMT 2006


The current ui factory is designed for the following uses:

 * To let library code be agnostic to the need for different uis. We
ship two uis by default: a silent 'library-like' ui, and a 'interactive'
text user interface.
 * To remove the need for *every* function to have a parameter for the
active ui elements. [many trivial functions call non trivial ones. So
any function might end up doing slow things deep down.]

But there are issues:
 * Thread wise we can have competing UI elements.
 * New progress bars do not cooperate with existing progress bars. This
may apply to other UI elements like user-input requests too.


I think the claims that the ui factory are bogus are bogus ;). Its
definately an anti-pattern to have such a pervasive thing being passed
around everywhere. So heres a proposal for improving the ui factory...

Firstly lets assume that functions do not need to know their callers
intent - they can present a progress bar anytime they choose too, ditto
input dialogs etc.

For thread safety, we have a number of options. But lets qualify what we
are aiming to achieve. Do we want a silent UI in thread 1, and a GUI in
thread 2 with a text ui in thread 3? I think thats nuts and not
something we should aim for supporting [but not deliberately prevent
either]. For console applications, showing multiple threads of execution
at once is a pain, and I'd expect a ncurses or other windowing facility
to be in play rather than our default text ui. So having multiple
factories is not needed IMO, but... once we qualify how progress
interactions are meant to work across threads we may need some thread
local storage for thread specific state. Or not. Lets see..

If I have a function foo calls function quux, then in a console app I
might want a progress bar in quux to alter the appearance of the one foo
is using:
[=====/--         ] Total progress/Current action

In a GUI I might want something like:
[=======          ] Total progress
[=====            ] Current action


This implies that the progress bar for quux is aware of that for foo in
the console case, and that they can exist independently for a GUI. So
our API could be something like
pb = ui.ui_factory.progress_bar(parents_pb)
which suggests that quux has a 'parents_pb' parameter.

Alternatively it could be:
pb = ui.ui_factory.progress_bar()
and the factory knows what the parent is.


Now lets consider threads a little:
Both those apis are thread-capable. The former by call-stack-state, the
latter by threads-specific-state.

If we want foo and quux to be in *different* threads then there is an
obvious difference, but that also implies that foo might have multiple
quux's at once - so the individual quux-level pb's will *still* have to
know about each other to interact properly - but a simple stack of pb's
would be wrong, as would just-a-set, or thread specific stacks.


So, I'm not at all convinced that passing pbs around in functions
'solves' thread safety issues. Its going to be complex any which way its
tackled, and IF that comes up, I'd rather design to address it then.

Until then, the simple factory we have now is thread-capable - anyone
can write a ui that is thread aware and install it.

What I would like is nested-progress bars to be part of the api: for pb
requests to automatically stack inside the factory and to be handed back
by objects when they are finished with.

Rob



-- 
GPG key available at: <http://www.robertcollins.net/keys.txt>.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20060222/8b51bbce/attachment.pgp 


More information about the bazaar mailing list