Lots of code (174 senders) use something like:
Cursor wait showWhile: ["stuff"]
That's great, and neat, and causes a dependency on the entire Graphics package. I propose breaking this dependency by extending UIManager's protocol. You would then write:
UIManager default showCursor: #wait during: ["stuff"]
I use a Symbol to identify the cursor because that doesn't require depending on any particular classes. Perhaps UIManager >> #showCursor:during: can lay out the minimum expected set of labels (whatever Cursor currently lists). Then MorphicUIManager and MVCUIManager can implement this method in the existing way, with ^ Cursor foo showWhile: aBlock
One other change is needed, and that's to handle mistakes. So I propose
Cursor class >> #named: aSymbol ^ (self respondsTo: #named) ifTrue: [self perform: aSymbol] ifFalse: [self normal].
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts?
frank
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
Cheers, Juan Vuletich
Quoting Frank Shearar frank.shearar@gmail.com:
Lots of code (174 senders) use something like:
Cursor wait showWhile: ["stuff"]
That's great, and neat, and causes a dependency on the entire Graphics package. I propose breaking this dependency by extending UIManager's protocol. You would then write:
UIManager default showCursor: #wait during: ["stuff"]
I use a Symbol to identify the cursor because that doesn't require depending on any particular classes. Perhaps UIManager >> #showCursor:during: can lay out the minimum expected set of labels (whatever Cursor currently lists). Then MorphicUIManager and MVCUIManager can implement this method in the existing way, with ^ Cursor foo showWhile: aBlock
One other change is needed, and that's to handle mistakes. So I propose
Cursor class >> #named: aSymbol ^ (self respondsTo: #named) ifTrue: [self perform: aSymbol] ifFalse: [self normal].
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts?
frank
Cheers, Juan Vuletich
On 06/24/2013 09:28 AM, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor.
Does this work also for long-running primitives? I think the #showWhile: approach works in that situation.
Tony
It should work if you use the MT Cog VM, that allows Squeak to continue running alongside primitives. Never tested it, though.
Quoting Tony Garnock-Jones tonyg@ccs.neu.edu:
On 06/24/2013 09:28 AM, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor.
Does this work also for long-running primitives? I think the #showWhile: approach works in that situation.
Tony
Cheers, Juan Vuletich
On 24-06-2013, at 7:57 AM, "Juan Vuletich (mail lists)" juanlists@jvuletich.org wrote:
It should work if you use the MT Cog VM, that allows Squeak to continue running alongside primitives. Never tested it, though.
Given that you are deliberately doing things different in Cuis, perhaps you might consider a new prim to do this even without multi-threading support. The Stack/Cog VMs use a heartbeat timer and it would be pretty simple to add a primitiveLongWaitCursor that took a suitable cursor and a time delay, and after said delay, swapped the cursor. The tricky part would be making it cleanly work in the tick interrupt so that long running primitives don't block it.
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim An algorithm must be seen to be believed.
Quoting tim Rowledge tim@rowledge.org:
On 24-06-2013, at 7:57 AM, "Juan Vuletich (mail lists)" juanlists@jvuletich.org wrote:
It should work if you use the MT Cog VM, that allows Squeak to continue running alongside primitives. Never tested it, though.
Given that you are deliberately doing things different in Cuis, perhaps you might consider a new prim to do this even without multi-threading support. The Stack/Cog VMs use a heartbeat timer and it would be pretty simple to add a primitiveLongWaitCursor that took a suitable cursor and a time delay, and after said delay, swapped the cursor. The tricky part would be making it cleanly work in the tick interrupt so that long running primitives don't block it.
Yes, good idea. But I'm trying not to modify the VM, and to always use the current Squeak VMs. I'm already short of time, and I try to focus on the image side of things.
If some kind soul would do it, I'd adopt it for sure.
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim An algorithm must be seen to be believed.
Cheers, Juan Vuletich
On 24-06-2013, at 5:31 AM, Frank Shearar frank.shearar@gmail.com wrote:
You would then write:
UIManager default showCursor: #wait during: ["stuff"]
snip]
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts
Well I really dislike seeing #respondsTo: et al in general code so I'd propose something along the lines of a list of known cursors (it's reasonable in my opinion to make that list using reflection at either startup or add-new-cursor time) and then
Cursor class >> #named: aSymbol ^ cursorList at: aSymbol ifAbsent:[self normal]
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CCC: Crash if Carry Clear
On 24 June 2013 18:30, tim Rowledge tim@rowledge.org wrote:
On 24-06-2013, at 5:31 AM, Frank Shearar frank.shearar@gmail.com wrote:
You would then write:
UIManager default showCursor: #wait during: ["stuff"]
snip]
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts
Well I really dislike seeing #respondsTo: et al in general code so I'd propose something along the lines of a list of known cursors (it's reasonable in my opinion to make that list using reflection at either startup or add-new-cursor time) and then
Cursor class >> #named: aSymbol ^ cursorList at: aSymbol ifAbsent:[self normal]
Yep, reflection hides the actual API, and makes things slow as well. So in Cursor's particular case, it has loads of classvars with names of the form FooCursor, Foo naturally corresponding to the selector #foo. So there's CrossHairCursor, BlankCursor, etc. That means you end up duplicating the list of cursors (between the set of class vars and cursorList), or you make a rather invasive change of ripping out all the class vars. A middle ground might be this:
Cursor >> named: aSymbol ^ aSymbol caseOf: { [#down] -> [self down]. [#wait] -> [self wait]. } otherwise: [self normal].
frank
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CCC: Crash if Carry Clear
My requirements are that control needs to remain with applications to provide feedback about any of a _variety_ of actions a program may be *doing* -- not simply how long a user has been waiting. Changing the cursor form is already process-intensive enough without needing to endure any more performance degradation, please.
I struggle to understand why, for any package that thinks it wants to do something graphical like operate on a Cursor, should not depend on the Graphics package anyway? Why so worried to the point of getting away from simple OO sending a message to the Form object and moving to some kind of relational lookup simply because of a valid package dependency..?
If we MUST sterilize the system, Frank seems to have the best compromise with performance so far with the CASE statement. Unfortunately it still chips away at the simplicity and also functionality we have now, such as the ability for an application to conveniently extend with its own cursor forms. Is it about "feeling squeaky clean," or is there some bigger payoff I'm missing? Is this about getting to a smaller core?
On Mon, Jun 24, 2013 at 12:43 PM, Frank Shearar frank.shearar@gmail.com wrote:
On 24 June 2013 18:30, tim Rowledge tim@rowledge.org wrote:
On 24-06-2013, at 5:31 AM, Frank Shearar frank.shearar@gmail.com wrote:
You would then write:
UIManager default showCursor: #wait during: ["stuff"]
snip]
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts
Well I really dislike seeing #respondsTo: et al in general code so I'd propose something along the lines of a list of known cursors (it's reasonable in my opinion to make that list using reflection at either startup or add-new-cursor time) and then
Cursor class >> #named: aSymbol ^ cursorList at: aSymbol ifAbsent:[self normal]
Yep, reflection hides the actual API, and makes things slow as well. So in Cursor's particular case, it has loads of classvars with names of the form FooCursor, Foo naturally corresponding to the selector #foo. So there's CrossHairCursor, BlankCursor, etc. That means you end up duplicating the list of cursors (between the set of class vars and cursorList), or you make a rather invasive change of ripping out all the class vars. A middle ground might be this:
Cursor >> named: aSymbol ^ aSymbol caseOf: { [#down] -> [self down]. [#wait] -> [self wait]. } otherwise: [self normal].
frank
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CCC: Crash if Carry Clear
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
I don't need to be concerned about performance since a hard dependency to Cursor showWhile: can be maintained. But at least the in-image "apps" like the Browsers and stuff, performance should not be noticably affected by their occasional flipping of the cursor, and so Tims idea of a Dictionary of forms / form names should be plenty fast enough for that and with ability to extend without changing code by apps putting into that Dictionary..
On Mon, Jun 24, 2013 at 3:50 PM, Chris Muller asqueaker@gmail.com wrote:
My requirements are that control needs to remain with applications to provide feedback about any of a _variety_ of actions a program may be *doing* -- not simply how long a user has been waiting. Changing the cursor form is already process-intensive enough without needing to endure any more performance degradation, please.
I struggle to understand why, for any package that thinks it wants to do something graphical like operate on a Cursor, should not depend on the Graphics package anyway? Why so worried to the point of getting away from simple OO sending a message to the Form object and moving to some kind of relational lookup simply because of a valid package dependency..?
If we MUST sterilize the system, Frank seems to have the best compromise with performance so far with the CASE statement. Unfortunately it still chips away at the simplicity and also functionality we have now, such as the ability for an application to conveniently extend with its own cursor forms. Is it about "feeling squeaky clean," or is there some bigger payoff I'm missing? Is this about getting to a smaller core?
On Mon, Jun 24, 2013 at 12:43 PM, Frank Shearar frank.shearar@gmail.com wrote:
On 24 June 2013 18:30, tim Rowledge tim@rowledge.org wrote:
On 24-06-2013, at 5:31 AM, Frank Shearar frank.shearar@gmail.com wrote:
You would then write:
UIManager default showCursor: #wait during: ["stuff"]
snip]
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts
Well I really dislike seeing #respondsTo: et al in general code so I'd propose something along the lines of a list of known cursors (it's reasonable in my opinion to make that list using reflection at either startup or add-new-cursor time) and then
Cursor class >> #named: aSymbol ^ cursorList at: aSymbol ifAbsent:[self normal]
Yep, reflection hides the actual API, and makes things slow as well. So in Cursor's particular case, it has loads of classvars with names of the form FooCursor, Foo naturally corresponding to the selector #foo. So there's CrossHairCursor, BlankCursor, etc. That means you end up duplicating the list of cursors (between the set of class vars and cursorList), or you make a rather invasive change of ripping out all the class vars. A middle ground might be this:
Cursor >> named: aSymbol ^ aSymbol caseOf: { [#down] -> [self down]. [#wait] -> [self wait]. } otherwise: [self normal].
frank
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CCC: Crash if Carry Clear
On 25 June 2013 03:12, Chris Muller asqueaker@gmail.com wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies.
File depends on Graphics solely through Cursor, while Compression depends on Graphics through Cursor, BitBlt and Form. As it happens, this gigantically invasive change would remove exactly one dependency. I'm thus tempted to ignore this apparently low-hanging but rather unripe fruit, at least for the nonce.
If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
That's a good idea. It communicates the intent, rather than the mechanism.
I don't need to be concerned about performance since a hard dependency to Cursor showWhile: can be maintained. But at least the in-image "apps" like the Browsers and stuff, performance should not be noticably affected by their occasional flipping of the cursor, and so Tims idea of a Dictionary of forms / form names should be plenty fast enough for that and with ability to extend without changing code by apps putting into that Dictionary..
I don't mind applications loaded into an image having a dependency on Graphics. What I'm trying to do with #showCursor:during: is avoid unnecessary entanglements in the _base_ image. I see no reason at all why Files or Collections or Compression should depend on Graphics. None of these packages require a UI element. (Compression uses BitBlt, I think, to make use of BitBlt's primitives.)
I'm trying to introduce a strictly layered set of packages in the base image, with as few cyclic dependencies (ideally none) as possible.
I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
Since Cursor is effectively a(n undelimited) dynamic variable it occurs to me we could signal the start and end of some busy block with Notifications, but Notifications are relatively expensive - linear in the depth of the call stack. In fact I'd _prefer_ to use delimited dynamic variables (through resumable exceptions), because that's friendly to stack slicing. But to make the massive use of delimited dynamic variables performant would probably require VM level changes.
So in summary this is kinda-sorta a nice idea, except at the moment it doesn't buy us particularly much. It looked like an easy way to decouple parts of the system, but it isn't. Let's shelve it for now.
frank
On Mon, Jun 24, 2013 at 3:50 PM, Chris Muller asqueaker@gmail.com wrote:
My requirements are that control needs to remain with applications to provide feedback about any of a _variety_ of actions a program may be *doing* -- not simply how long a user has been waiting. Changing the cursor form is already process-intensive enough without needing to endure any more performance degradation, please.
I struggle to understand why, for any package that thinks it wants to do something graphical like operate on a Cursor, should not depend on the Graphics package anyway? Why so worried to the point of getting away from simple OO sending a message to the Form object and moving to some kind of relational lookup simply because of a valid package dependency..?
If we MUST sterilize the system, Frank seems to have the best compromise with performance so far with the CASE statement. Unfortunately it still chips away at the simplicity and also functionality we have now, such as the ability for an application to conveniently extend with its own cursor forms. Is it about "feeling squeaky clean," or is there some bigger payoff I'm missing? Is this about getting to a smaller core?
On Mon, Jun 24, 2013 at 12:43 PM, Frank Shearar frank.shearar@gmail.com wrote:
On 24 June 2013 18:30, tim Rowledge tim@rowledge.org wrote:
On 24-06-2013, at 5:31 AM, Frank Shearar frank.shearar@gmail.com wrote:
You would then write:
UIManager default showCursor: #wait during: ["stuff"]
snip]
The reason for the icky reflection is to fit in with the existing way cursors are used. I'd be happy to unroll the #perform: into a #caseOf: mapping explicitly to the existing cursors.
Thoughts
Well I really dislike seeing #respondsTo: et al in general code so I'd propose something along the lines of a list of known cursors (it's reasonable in my opinion to make that list using reflection at either startup or add-new-cursor time) and then
Cursor class >> #named: aSymbol ^ cursorList at: aSymbol ifAbsent:[self normal]
Yep, reflection hides the actual API, and makes things slow as well. So in Cursor's particular case, it has loads of classvars with names of the form FooCursor, Foo naturally corresponding to the selector #foo. So there's CrossHairCursor, BlankCursor, etc. That means you end up duplicating the list of cursors (between the set of class vars and cursorList), or you make a rather invasive change of ripping out all the class vars. A middle ground might be this:
Cursor >> named: aSymbol ^ aSymbol caseOf: { [#down] -> [self down]. [#wait] -> [self wait]. } otherwise: [self normal].
frank
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CCC: Crash if Carry Clear
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Cheers, Juan Vuletich
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists) wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely, but I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the intent is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an MVCProject might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
On 6/25/13, David T. Lewis lewis@mail.msen.com wrote:
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists) wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely, but I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the intent is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an MVCProject might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
+ 1
That reminds me the post from Travis Griggs, citing ideas from Vassili Bykov
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&a...
And I think that Juan's implementation is clearly in this spirit, so +1
2013/6/25 H. Hirzel hannes.hirzel@gmail.com
On 6/25/13, David T. Lewis lewis@mail.msen.com wrote:
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists)
wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely,
but
I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists)
wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the intent is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an MVCProject might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
- 1
On 25 June 2013 16:35, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
That reminds me the post from Travis Griggs, citing ideas from Vassili Bykov
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&a...
And I think that Juan's implementation is clearly in this spirit, so +1
There's nothing wrong with Juan's code. It just doesn't have much to do with the problem that spawned this thread.
The link is, however: Vassili and Travis are saying "remove Cursor showWhile:". And that _would_ solve my problem. Removing these senders would make Files no longer depend on Graphics.
(Juan's suggestion would address the second half of the linked article. Again, it's great, and maybe we should port that to Trunk ASAP, but it's not what I was posting about.)
frank
2013/6/25 H. Hirzel hannes.hirzel@gmail.com
On 6/25/13, David T. Lewis lewis@mail.msen.com wrote:
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists) wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely, but I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the intent is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an MVCProject might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
- 1
But can we agree that File should not bother with UI things, it's not it's business, be it by direct access to Cursor, or indirect access thru a UIManager?
2013/6/25 Frank Shearar frank.shearar@gmail.com
On 25 June 2013 16:35, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
That reminds me the post from Travis Griggs, citing ideas from Vassili
Bykov
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&a...
And I think that Juan's implementation is clearly in this spirit, so +1
There's nothing wrong with Juan's code. It just doesn't have much to do with the problem that spawned this thread.
The link is, however: Vassili and Travis are saying "remove Cursor showWhile:". And that _would_ solve my problem. Removing these senders would make Files no longer depend on Graphics.
(Juan's suggestion would address the second half of the linked article. Again, it's great, and maybe we should port that to Trunk ASAP, but it's not what I was posting about.)
frank
2013/6/25 H. Hirzel hannes.hirzel@gmail.com
On 6/25/13, David T. Lewis lewis@mail.msen.com wrote:
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists) wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely, but I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It
is
trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency
on
Graphics from many packages? If so, then I do understand the
interest
in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the
intent
is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an
MVCProject
might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
- 1
Well, there needs to be *some* mechanism for communication from low-level code to the UI. A direct dependency is bad, obviously.
Juan's suggestion works for any long-running operation, without the need to code anything. That's great. But it wouldn't let us distinguish what the cause of it is - showing the read cursor or write cursor did that.
Maybe the two should be combined? For example, there could be a ResourceAccessProgressNotification that knew about read/write/network access. This combined with Juan's "watchdog" would let the UI indicate more specifically what the cause of the delay is.
- Bert -
On 25.06.2013, at 08:52, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
But can we agree that File should not bother with UI things, it's not it's business, be it by direct access to Cursor, or indirect access thru a UIManager?
2013/6/25 Frank Shearar frank.shearar@gmail.com On 25 June 2013 16:35, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
That reminds me the post from Travis Griggs, citing ideas from Vassili Bykov
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&a...
And I think that Juan's implementation is clearly in this spirit, so +1
There's nothing wrong with Juan's code. It just doesn't have much to do with the problem that spawned this thread.
The link is, however: Vassili and Travis are saying "remove Cursor showWhile:". And that _would_ solve my problem. Removing these senders would make Files no longer depend on Graphics.
(Juan's suggestion would address the second half of the linked article. Again, it's great, and maybe we should port that to Trunk ASAP, but it's not what I was posting about.)
frank
2013/6/25 H. Hirzel hannes.hirzel@gmail.com
On 6/25/13, David T. Lewis lewis@mail.msen.com wrote:
On Tue, Jun 25, 2013 at 07:16:03AM -0300, Juan Vuletich (mail lists) wrote:
Quoting Frank Shearar frank.shearar@gmail.com:
... I realise that I'm advocating the removal of a host of Graphics dependencies only to replace them with ToolBuilder-Kernel dependencies. I'd prefer to not have the latter either, but it's a lesser of two evils.
... frank
What about my suggestion? I mean, doesn't it deserve a comment?
Yes indeed it does. I have not been following this discussion closely, but I'll comment anyway :-)
On Mon, Jun 24, 2013 at 10:28:31AM -0300, Juan Vuletich (mail lists) wrote:
I recently did something better fo Cuis. The idea is to let Morphic handle that. If Morphic frame rate drops below some threshold, show the wait cursor. This way, there are no 'bad' references to UI from non-UI code, and you only get the wait cursor if appropriate (for instance, not if the very same code is run on a forked process). It is trivial to add protocol to set the "wait cursor" to be used. This allowed me to clean a lot of methods.
It is in update #1704 at https://github.com/jvuletich/Cuis .
This sounds like like a really elegant approach, because it does not require advance knowledge that some operation is likely to take a long time, and it will do the right thing on both slow and fast hardware.
It does however seem to depend on the Morphic update mechanism, so it may not translate well to other UI styles. (I look to MVC to keep us honest in these matters, but you can imagine a SeasideProject in addition to MorphicProject and MVCProject, and the same principle applies.)
On Mon, Jun 24, 2013 at 09:12:08PM -0500, Chris Muller wrote:
After more thought, I should rebut myself for sounding so harsh. Frank, are Cursor showWhile:, et al. the _sole_ cause of dependency on Graphics from many packages? If so, then I do understand the interest in wanting to soften those dependencies. If we're going to extend "UIManager" I think we should call it something generic to a UI that may not even support a cursor:
UIManager default indicateBusyWhile: [ ... ] UIManager default indicateReadingWhile: [ ... ] etc.
This sounds like a promising approach. It is easy to read and the intent is clear. It seems like it would provide a mechinism for using an optimal implementation for various types of projects. For example, an MVCProject might use the traditional "Cursor wait showWhile:" idiom, and a MorphicProject could use the new Cuis approach. Meanwhile if someone was (finally!) implementing SeasideProject, they could figure out an implementation that makes sense for a web app.
Dave
- 1
On 25-06-2013, at 8:52 AM, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
But can we agree that File should not bother with UI things, it's not it's business, be it by direct access to Cursor, or indirect access thru a UIManager?
2013/6/25 Frank Shearar frank.shearar@gmail.com On 25 June 2013 16:35, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
That reminds me the post from Travis Griggs, citing ideas from Vassili Bykov
That's a pile of good comment right there. Using the cursor all the time was easy and effective when you had very little other choice. We had some discussions a while back about making buttons provide some 'temporarily busy' feedback and part of that was about avoiding cursor changing even within UI code. Non-UI code really ought not ever make cursor changes. The best thing to do in my experience is to use a signal of some variety; an actual Exception might be suited to many cases but other notification mechanisms are possible. Why, we even have some good uses as examples - ProgressMorph, which appears to be unused String>displayProgress*, which is doing the right kind of thing whilst still being overly tied to UI details ProgressInitiationException, which is used by String>displayProgress
It seems to me that a slightly more abstract exception would be sensible, so that code might read a bit like this:-
foo: thing "do something that might take a while; alert the UI stuff and keep letting the user know things are ok" self prepareForArmageddon. ProgressNotificationAlert initialNotification. "this part is done in discrete steps" listOfStuff do:[wotsit| wotsit thungummy. ProgressNotificationAlert notifiyStepPercentage: wotsit size]. "this bit may take any amount of time, so use a generic beachball/spinner/ticker thing" ProgressNotificationAlert notifyLongJob. thing peformMagicTricks. ProgressNotificationAlert terminateAlert
There's plenty of scope for debating the details of whether we ought to put the code in handler block like constructs or whatever. How little code could we make the user have to write? Maybe it could work as simply as the current Cursor message:-
foo: thing ProgressNotificationAlert while:[ self prepareForArmageddon. listOfStuff do:[wotsit| wotsit thungummy]. thing peformMagicTricks]
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: NNI: Neglect Next Instruction
On 25 June 2013 18:42, tim Rowledge tim@rowledge.org wrote:
On 25-06-2013, at 8:52 AM, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
But can we agree that File should not bother with UI things, it's not it's business, be it by direct access to Cursor, or indirect access thru a UIManager?
2013/6/25 Frank Shearar frank.shearar@gmail.com On 25 June 2013 16:35, Nicolas Cellier nicolas.cellier.aka.nice@gmail.com wrote:
That reminds me the post from Travis Griggs, citing ideas from Vassili Bykov
That's a pile of good comment right there. Using the cursor all the time was easy and effective when you had very little other choice. We had some discussions a while back about making buttons provide some 'temporarily busy' feedback and part of that was about avoiding cursor changing even within UI code. Non-UI code really ought not ever make cursor changes. The best thing to do in my experience is to use a signal of some variety; an actual Exception might be suited to many cases but other notification mechanisms are possible. Why, we even have some good uses as examples - ProgressMorph, which appears to be unused String>displayProgress*, which is doing the right kind of thing whilst still being overly tied to UI details ProgressInitiationException, which is used by String>displayProgress
It seems to me that a slightly more abstract exception would be sensible, so that code might read a bit like this:-
foo: thing "do something that might take a while; alert the UI stuff and keep letting the user know things are ok" self prepareForArmageddon. ProgressNotificationAlert initialNotification. "this part is done in discrete steps" listOfStuff do:[wotsit| wotsit thungummy. ProgressNotificationAlert notifiyStepPercentage: wotsit size]. "this bit may take any amount of time, so use a generic beachball/spinner/ticker thing" ProgressNotificationAlert notifyLongJob. thing peformMagicTricks. ProgressNotificationAlert terminateAlert
This is kind've what I was thinking when nattering about Cursor being like an undelimited dynamic variable. Using resumable exceptions could conceivably let the code above respond to the UI, not just notify the UI of changes. I just worry about performance, but maybe I should worry about that when it's a problem.
Or: there's plenty of scope for improving Morphic performance _anyway_, so don't worry about this hit.
frank
There's plenty of scope for debating the details of whether we ought to put the code in handler block like constructs or whatever. How little code could we make the user have to write? Maybe it could work as simply as the current Cursor message:-
foo: thing ProgressNotificationAlert while:[ self prepareForArmageddon. listOfStuff do:[wotsit| wotsit thungummy]. thing peformMagicTricks]
tim
tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: NNI: Neglect Next Instruction
squeak-dev@lists.squeakfoundation.org