[jira] [Created] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread JIRA
Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered


 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor


We are writing sort of a game, which continually calls Component.repaint 
method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
of painting done by our component (actually in an overriden Panel.paint) is 
ridiculously small. The profiler pointed us to the paintVolatileBuffered method 
in the DisplayHost. What you are doing there is:

1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix x 
4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
region (not in the L2 cache)
2. then you call actual paint on that buffered image (this is touching at least 
5.2 MB again)
3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
another time)
4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
memory to compact young generation (= touching 5.2 MB fourth time)

The whole process means allocating from cold memory 5.2 MB per each frame and 
touching about 20 MB per frame.
For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
It also makes the GC go crazy.

We have found that caching the buffer between the subsequent paint calls 
improves performance a lot:

code
/** Stores the prepared offscreen buffer */
private BufferedImage bufferedImage;

/**
 * Attempts to paint the display using an offscreen buffer.
 *
 * @param graphics
 * The source graphics context.
 *
 * @return
 * tttrue/tt if the display was painted using the offscreen
 * buffer; ttfalse/tt, otherwise.
 */
private boolean paintBuffered(Graphics2D graphics) {
boolean painted = false;

// Paint the display into an offscreen buffer
GraphicsConfiguration gc = graphics.getDeviceConfiguration();
java.awt.Rectangle clipBounds = graphics.getClipBounds();
if (bufferedImage == null ||
bufferedImage.getWidth()  clipBounds.width ||
bufferedImage.getHeight()  clipBounds.height)

bufferedImage = gc.createCompatibleImage(clipBounds.width, 
clipBounds.height,
Transparency.OPAQUE);

if (bufferedImage != null) {
Graphics2D bufferedImageGraphics = 
(Graphics2D)bufferedImage.getGraphics();
bufferedImageGraphics.setClip(0, 0, clipBounds.width,
...
/code 

Advantages:
1. it saves from costly allocation of a large object from possibly not-cached 
memory region
2. after a few repaints the GC moves this object to the tenured generation, so 
that the young generation collector is much more efficient (longer times 
between runs)
3. the image probably stays most of the time in the L2 or L3 cache, which saves 
on memory bandwidth and speeds up painting

Disadvantages:
1. uses some memory that is probably not required all the time, when the app 
doesn't need to repaint anything large, however this is almost completely 
shadowed by the excessive GC overhead due to continuous recreation of the 
offscreen buffered image

Anyway, we observed about 2-4x performance increase by this simple change - now 
when running at 60 FPS it uses only about 25% of CPU for painting, and the rest 
can be used by the application logic (AI, etc.). Previously 60 FPS was probably 
the most we could achieve from Core2Duo 2.2 GHz. Of course, this change won't 
affect any business applications that don't do animations etc.




--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Updated] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Sandro Martini (JIRA)

 [ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sandro Martini updated PIVOT-778:
-

Fix Version/s: 2.0.1

Comments ?

 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Chris Bartlett (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071651#comment-13071651
 ] 

Chris Bartlett commented on PIVOT-778:
--

Piotr - This looks interesting, but it would really help if you could supply an 
example that can be used as a simple benchmark.  Something that paints with the 
current method and then with the optimised method.

 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-776) Additional support for mouse wheel adjustments of Component values

2011-07-27 Thread Chris Bartlett (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-776?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071658#comment-13071658
 ] 

Chris Bartlett commented on PIVOT-776:
--

For this ticket, I will just go with whatever approach is preferred.

The concensus seems to be that the target Component should be focused, but what 
about mouse positioning?
Should the mouse when only work when the mouse is over the focused Component?   
 

For my own purposes, I think that I will probably end up using a 
'MouseWheelPolicy' of some kind to allow a change in the way that the mouse 
wheel is handled.  This will allow a 'simple' mode that requires focus and an 
'advanced' mode that doesn't.  This will probably be set at the application 
level and apply to all Component within an app.  


 Additional support for mouse wheel adjustments of Component values
 --

 Key: PIVOT-776
 URL: https://issues.apache.org/jira/browse/PIVOT-776
 Project: Pivot
  Issue Type: Improvement
  Components: wtk, wtk-terra
 Environment: n/a
Reporter: Chris Bartlett
Assignee: Chris Bartlett
Priority: Minor
 Fix For: 2.1


 I imagine that mouse wheel events would be ignored unless the Component was 
 focused *and* the mouse was over the Component.
 Spinner - Equivalent to an UP/DOWN arrow key press when 'circular' property 
 is true
 Slider - Equivalent to an UP/DOWN/LEFT/RIGHT arrow key press
 ListButton - Equivalent to an UP/DOWN arrow key press
 CalendarButton - No current UP/DOWN/LEFT/RIGHT arrow key press functionality 
 to change date by a single day, but would be equivalent to this.  Support for 
 these key presses could be added at the same time. 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-700) SplashScreen control

2011-07-27 Thread Chris Bartlett (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-700?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071659#comment-13071659
 ] 

Chris Bartlett commented on PIVOT-700:
--

I do intend to attach a simple test app, but haven't had time yet.

 SplashScreen control
 

 Key: PIVOT-700
 URL: https://issues.apache.org/jira/browse/PIVOT-700
 Project: Pivot
  Issue Type: New Feature
Affects Versions: 2.0
Reporter: Bojan Vucinic
 Fix For: 2.1

 Attachments: splash_screen.patch


 I've tried to get hold of the SplashScreen that I've defined in my 
 manifest.mf file:
 Manifest-Version: 1.0
 X-COMMENT: Main-Class will be added automatically by build
 SplashScreen-Image: com/macad/enbal/resources/welcome.jpg
 But once the DesktopApplicationContext takes over, it is impossible to get 
 the SplashScreen (null pointer exception is thrown).
 Could you extend the API so that we can show the SplashScreen, and close it 
 once all the init actions have been finished just before we open the 
 application window as the nameless gray pivot window is displayed quite a 
 long time.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
Hi Chris,

 I wasted too much time yesterday realizing that TaskGroup 
 TaskSequence don't use the java.util.concurrent.ExecutorService that
 might be passed to their constructors.

If I understand the issue, I think you mean that these classes are not 
guaranteed to execute their subtasks using the same ExecutorService that they 
were given. Is that correct?

 I can't really work out the intent of the classes from the javadocs or
 decide if they are still required (at least in their current forms).
 Neither is used within Pivot itself.

They are just utility classes for executing a set of tasks in sequence or in 
parallel. Even though they are not used by the platform, I believe there is a 
unit test for these classes.

 Are they supposed to use a provided ExecutorService or is the
 constructor just a copy  paste mistake?

Not sure what you mean by this. TaskGroup(ExecutorService) and 
TaskSequence(ExecutorService) do appear to pass the given executor service to 
the base class. Am I missing something?

 If the former, then it is probably worth adding a
 setExecutorService(ExecutorService) method to
 org.apache.pivot.util.concurrent.Task so that TaskGroup  TaskSequence
 can control the ExecutorService to use when running the individual
 tasks.

Is the question whether we should enforce that subtasks are executed by the 
same executor service as their parent? If so, why might we want to do that?

G




[jira] [Commented] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Greg Brown (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071664#comment-13071664
 ] 

Greg Brown commented on PIVOT-778:
--

Way back, I believe we were doing something like this but switched to the 
current approach to save on memory. It may be reasonable to offer a switch to 
toggle this behavior.

But I'm wondering why you need to repaint the entire 1280x1024 frame every 
time. Is it not possible for you to only update the dirty region of your frame 
during your animation?


 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-656) FileBrowserSheet seems frozen while browsing network folders

2011-07-27 Thread Chris Bartlett (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-656?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071665#comment-13071665
 ] 

Chris Bartlett commented on PIVOT-656:
--

I wrote a custom DirectoryChooser component which shows the file system roots 
as a tree and retains a MRU list (most recently used) of chosen directories 
among other things.

The cleanest solution I came up with was to record the time taken to enumerate 
the drives/mount points and special directories, and then store a flag in the 
application preferences to identify the ones that loaded slowly.  The next time 
the DirectoryChooser is used, those slow nodes would be populated on separate 
threads, but could just as easily lazy loaded when/if they were accessed

 FileBrowserSheet seems frozen while browsing network folders
 

 Key: PIVOT-656
 URL: https://issues.apache.org/jira/browse/PIVOT-656
 Project: Pivot
  Issue Type: Improvement
Affects Versions: 1.5.1
Reporter: A.J.
 Fix For: 2.1


 Our customer complains about the FileBrowserSheet being unresponsive while 
 browsing network folders.
 I haven't been able to reproduce this in my development environment but I saw 
 this in 'action' (or inaction in this case).
 They click a folder then ... nothing happens, they wait, then wait. They are 
 free to try other folders (I guess this is asynchronous task) but nothing 
 happens.
 I've asked them to navigate the same network path with the Windows explorer 
 which has no apparent problem (some slowdowns at worst).
 So, it's hard to say where the problems is (no stack trace) but there is a 
 problem.
 One first improvement that could be done would be to display an hourglass 
 (busy cursor) while the current I/O operation is pending.
 Another one could be also to set a timer after which the I/O operation would 
 be canceled (or abandonned) and give back hand to the calling code.
 That's all I'm thinking fo r now.
 As soon as I can get some more info on the origin of the problem, I'll update 
 this issue.
 Cheers, 
 A.J.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
Hi Greg.  Answers in line.

On 27 July 2011 18:37, Greg Brown gk_br...@verizon.net wrote:
 I wasted too much time yesterday realizing that TaskGroup 
 TaskSequence don't use the java.util.concurrent.ExecutorService that
 might be passed to their constructors.

 If I understand the issue, I think you mean that these classes are not 
 guaranteed to execute their subtasks using the same ExecutorService that they 
 were given. Is that correct?

No it is a little more than that.  When a standard Task is created, it
either uses a default ExecutorService or the one provided to it.  This
cannot be changed later.

TaskGroup  TaskSequence extend Task and also accept an
ExecutorService, but this is never used (no call to
getExecutorService())

In their execute() methods, they both just iterate over the added
Tasks and call
((TaskObject)task).execute(taskListener);
on each Tasks.

This will execute each Task using its internal ExecutorService, and
not the one supplied to the TaskGroup/TaskSequence.


 I can't really work out the intent of the classes from the javadocs or
 decide if they are still required (at least in their current forms).
 Neither is used within Pivot itself.

 They are just utility classes for executing a set of tasks in sequence or in 
 parallel. Even though they are not used by the platform, I believe there is a 
 unit test for these classes.

There is a 'unit test', but it has no assertions, comments or coverage
of the constructors that take an ExecutorService, so doesn't clarify
anything.


 Are they supposed to use a provided ExecutorService or is the
 constructor just a copy  paste mistake?

 Not sure what you mean by this. TaskGroup(ExecutorService) and 
 TaskSequence(ExecutorService) do appear to pass the given executor service to 
 the base class. Am I missing something?

They pass it to the base class, but it is never accessed.  That is why
I am not sure of the intent.  Is the supplied ExecutorService supposed
to be used?


 If the former, then it is probably worth adding a
 setExecutorService(ExecutorService) method to
 org.apache.pivot.util.concurrent.Task so that TaskGroup  TaskSequence
 can control the ExecutorService to use when running the individual
 tasks.

 Is the question whether we should enforce that subtasks are executed by the 
 same executor service as their parent?
Yes, that is what I thought would happen if I supply an ExecutorService.

 If so, why might we want to do that?
I thought that I would be able to do something like this to execute an
arbitrary group of Tasks in parallel, but limited to only 3 being
started at any given moment.

TaskGroup taskGroup = new TaskGroup(Executors.newFixedThreadPool(3));

Chris


Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 If I understand the issue, I think you mean that these classes are not 
 guaranteed to execute their subtasks using the same ExecutorService that 
 they were given. Is that correct?
 
 No it is a little more than that.  When a standard Task is created, it
 either uses a default ExecutorService or the one provided to it.  This
 cannot be changed later.
 
 TaskGroup  TaskSequence extend Task and also accept an
 ExecutorService, but this is never used (no call to
 getExecutorService())
 
 In their execute() methods, they both just iterate over the added
 Tasks and call
 ((TaskObject)task).execute(taskListener);
 on each Tasks.
 
 This will execute each Task using its internal ExecutorService, and
 not the one supplied to the TaskGroup/TaskSequence.

Right. That's what I said.  ;-)

The ExecutorService given to TaskGroup and TaskSequence is used to execute the 
root task (the group or sequence). It just isn't used to execute the sub-tasks. 
If you want the sub-tasks to use the same executor service, you can just pass 
that service instance to the sub-task constructor.

 I thought that I would be able to do something like this to execute an
 arbitrary group of Tasks in parallel, but limited to only 3 being
 started at any given moment.
 
 TaskGroup taskGroup = new TaskGroup(Executors.newFixedThreadPool(3));

If you pass the fixed thread pool service to each of your individual tasks, you 
will get the behavior you want. You probably don't want to use the same service 
for the root task, since that would require a fourth thread.

G



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
On 27 July 2011 19:21, Greg Brown gk_br...@verizon.net wrote:
 The ExecutorService given to TaskGroup and TaskSequence is used to execute 
 the root task (the group or sequence). It just isn't used to execute the 
 sub-tasks.

Fair enough, but as I said, the intent is far from clear, even with
access to the source.

IMHO this fails the often quoted 'might confuse users' test miserably.
(Partly because I am a user, and this left me miserable after
confusing me!)

If you want the sub-tasks to use the same executor service, you can just pass 
that service instance to the sub-task constructor.  If you pass the fixed 
thread pool service to each of your individual tasks, you will get the 
behavior you want.

Yes, that is what I discovered.  I end up having to tell the task how
it will be executed when it is created.  Or wrapping one task in
another task just to be able to specify the ExecutorService at a later
point.

But by then I couldn't really see what these classes offer.


[jira] [Commented] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Sandro Martini (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071706#comment-13071706
 ] 

Sandro Martini commented on PIVOT-694:
--

Hi Greg, thanks for the help ... you have reason, I was more focused only on a 
clearSelection but probably for this there is already the 
setSelectedIndex(-1) method in many components ... but I'm guessing if this 
could be useful in ButtonGroup/RadioButtonGroup for example but this is another 
story.
Maybe in my new Pivot694, add button for Clear Selection in all components, 
and another for Clear Data, to test both behaviors.

I'll try to reproduce the condition where clear means delete all data inside 
the element, and see what happens.
Then in other components, to see what happens.

Bye


 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Sandro Martini
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 If you want the sub-tasks to use the same executor service, you can just 
 pass that service instance to the sub-task constructor.  If you pass the 
 fixed thread pool service to each of your individual tasks, you will get the 
 behavior you want.
 
 Yes, that is what I discovered.  I end up having to tell the task how
 it will be executed when it is created.

The same is true of any task - you provide the executor service to the 
constructor. A TaskGroup or TaskSequence is just a task that executes other 
tasks.

Might it make more sense to pass the executor service to the execute() method, 
rather than the constructor? That way, the service can easily be propagated to 
the sub-tasks.

 But by then I couldn't really see what these classes offer.

They offer exactly what was described earlier in the thread - a means for 
executing a set of tasks in sequence or in parallel.



[jira] [Resolved] (PIVOT-772) Exceptions thrown when calling getCharacterBounds of TextArea when incomplete lines exist

2011-07-27 Thread Noel Grandin (JIRA)

 [ 
https://issues.apache.org/jira/browse/PIVOT-772?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Noel Grandin resolved PIVOT-772.


Resolution: Fixed

Fixed in rev 1151471

Note that your code needs to change slightly: 

Bounds bounds = logTextArea.getCharacterBounds(textarea.getCharacterCount());
textarea.scrollAreaToVisible(bounds);

Note the absence of the -1 factor, since we actually want the position of the 
piece just past the end.


 Exceptions thrown when calling getCharacterBounds of TextArea when incomplete 
 lines exist
 -

 Key: PIVOT-772
 URL: https://issues.apache.org/jira/browse/PIVOT-772
 Project: Pivot
  Issue Type: Bug
  Components: wtk
Affects Versions: 2.0.1
 Environment: Windows XP SP3, JRE 1.6_25 or JRE 1.7 (beta)
Reporter: Roger Whitcomb
Assignee: Noel Grandin
Priority: Minor
 Fix For: 2.0.1

 Attachments: Scroll.java, Scroll2.java, scroll.bxml, scroll.log, 
 scroll2.log

   Original Estimate: 48h
  Remaining Estimate: 48h

 If partial lines are appended to a TextArea and then getCharacterBounds 
 followed by scrollAreaToVisible is called, Pivot throws 
 java.lang.IndexOutOfBoundsException from 
 TextAreaSkinParagraphView.getCharacterBounds:
 java.lang.IndexOutOfBoundsException: ix = 38
 at sun.font.StandardGlyphVector.getGlyphLogicalBounds(Unknown Source)
 at 
 org.apache.pivot.wtk.skin.TextAreaSkinParagraphView.getCharacterBounds(TextAreaSkinParagraphView.java:393)
 at 
 org.apache.pivot.wtk.skin.TextAreaSkin.getCharacterBounds(TextAreaSkin.java:442)
 at 
 org.apache.pivot.wtk.TextArea.getCharacterBounds(TextArea.java:1243)

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Resolved] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Greg Brown (JIRA)

 [ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Greg Brown resolved PIVOT-694.
--

Resolution: Fixed

I just checked in what should be a fix for this. Please re-open if the problem 
persists.


 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Sandro Martini
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Assigned] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Greg Brown (JIRA)

 [ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Greg Brown reassigned PIVOT-694:


Assignee: Greg Brown  (was: Sandro Martini)

 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Greg Brown
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Sandro Martini (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071758#comment-13071758
 ] 

Sandro Martini commented on PIVOT-694:
--

Hi Greg, thank you very much for the fix, I'll try during next days ... and 
I'll try even on other components to verify the same behavior.

On the clearSelection on ButtonGroup/RadioButtonGroup what do you think ? 
I could put this in a dedicated ticket (maybe for the 2.1) if you think could 
be useful to have.

Bye


 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Greg Brown
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
On 27 July 2011 20:37, Greg Brown gk_br...@verizon.net wrote:
 If you want the sub-tasks to use the same executor service, you can just 
 pass that service instance to the sub-task constructor.  If you pass the 
 fixed thread pool service to each of your individual tasks, you will get 
 the behavior you want.

 Yes, that is what I discovered.  I end up having to tell the task how
 it will be executed when it is created.

 The same is true of any task - you provide the executor service to the 
 constructor. A TaskGroup or TaskSequence is just a task that executes other 
 tasks.

Yeah, I understand that, and it is part of the reason that I thought
these classes would do something a bit different and that is where
their value would come from.

 Might it make more sense to pass the executor service to the execute() 
 method, rather than the constructor? That way, the service can easily be 
 propagated to the sub-tasks.

I think that would certainly add value.
For now though, I think I'll end up rolling my own rather than use
these, especially as they are not used elsewhere within Pivot.

 But by then I couldn't really see what these classes offer.

 They offer exactly what was described earlier in the thread - a means for 
 executing a set of tasks in sequence or in parallel.

Unfortunately this thread is not referenced in the javadocs :)
As this thread's existence proves, the javadocs still left me with questions.

I just didn't (and still don't) see much difference between these
classes and other utility methods or classes that have been
rejected/declined as not offering much that an individual developer
couldn't quickly knock up themselves, to their exact specifications.

So rightly or wrongly, I was essentially judging these classes with my
preconceived notions gained from reading the mailing lists.


[jira] [Commented] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Noel Grandin (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071762#comment-13071762
 ] 

Noel Grandin commented on PIVOT-778:


We could always use a WeakReference to allow the GC to collect it if necessary.

But yes, it sounds like Piotr's application should be using partial repaints.

 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Greg Brown (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071761#comment-13071761
 ] 

Greg Brown commented on PIVOT-694:
--

I'll try even on other components to verify the same behavior.

This fix only applies to ListButton.


 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Greg Brown
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Greg Brown (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071776#comment-13071776
 ] 

Greg Brown commented on PIVOT-778:
--

Actually, since it is a volatile image, a weak reference might not even be 
necessary. The graphics system will reclaim any memory consumed by a volatile 
image buffer if it needs to.


 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Commented] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Sandro Martini (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-694?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071785#comment-13071785
 ] 

Sandro Martini commented on PIVOT-694:
--

This fix only applies to ListButton. 
I understand this, I'm thinking to make similar tests on other components that 
contains some data and could be selected, and see after something has been 
selected, if clear reset even the selection ... for example in 
ListView/TableView/TreeView/etc.

On the clearSelection on ButtonGroup/RadioButtonGroup what do you think ?
For example in for example ListView/TableView/TreeView it is present, so why 
not even there ...
I could put this in a dedicated ticket (maybe for the 2.1) if you think could 
be useful to have. 
Sorry, but you didn't give me a comment on this ... what do you think ?

Thanks again.



 Improvement in ListButton clear() method
 

 Key: PIVOT-694
 URL: https://issues.apache.org/jira/browse/PIVOT-694
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
 Environment: Pivot 2.0
 Win 7
Reporter: Luiz Gustavo Stábile de Souza
Assignee: Greg Brown
Priority: Minor
 Fix For: 2.0.1

 Attachments: listButton problem.png


 I'm having problems with ListButton.
 When I try to clean a ListButton the last text selected before remains 
 selected, even with no item in the ListData of the ListButton.
 I tried listButton.clear() and listButton.getListData().clear(), but with 
 none of this I can scape the problem.
 I debugged the application, and the listData of the ListButton is clear after 
 getListData().clear(), but the last selected text remains showing.
 See attached image.
 Perhaps listButton.setButtonData(null)  should be performed in 
 ListButton#clear().
 Cheers

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




[jira] [Updated] (PIVOT-778) Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered

2011-07-27 Thread Sandro Martini (JIRA)

 [ 
https://issues.apache.org/jira/browse/PIVOT-778?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sandro Martini updated PIVOT-778:
-

Comment: was deleted

(was: Comments ?)

 Optimise DisplayHost.paintBuffered and DisplayHost.paintVolatileBuffered
 

 Key: PIVOT-778
 URL: https://issues.apache.org/jira/browse/PIVOT-778
 Project: Pivot
  Issue Type: Improvement
  Components: wtk
Affects Versions: 2.0
Reporter: Piotr Kołaczkowski
Priority: Minor
  Labels: DisplayHost, caching, gc, paint, performance, repaint
 Fix For: 2.0.1


 We are writing sort of a game, which continually calls Component.repaint 
 method, at 60 FPS. We noticed excessive CPU usage, although the actual amount 
 of painting done by our component (actually in an overriden Panel.paint) is 
 ridiculously small. The profiler pointed us to the paintVolatileBuffered 
 method in the DisplayHost. What you are doing there is:
 1. obtain a new, fresh BufferedImage of size equal to the actual clip region, 
 let's say for a full screen game it can be about 1280x1024. This is 1.3 Mpix 
 x 4 bytes/pixel = 5.2 MB of raw data, allocated from a probably cold memory 
 region (not in the L2 cache)
 2. then you call actual paint on that buffered image (this is touching at 
 least 5.2 MB again)
 3. then you copy that to the onscreen buffer (which means copying 5.2 MB for 
 another time)
 4. in case GC kicks in after 1 and 3. it has to move the BufferedImage in 
 memory to compact young generation (= touching 5.2 MB fourth time)
 The whole process means allocating from cold memory 5.2 MB per each frame and 
 touching about 20 MB per frame.
 For 60 FPS it makes up ~300 MB/s allocation rate and 1.2GB memory throughput. 
 It also makes the GC go crazy.
 We have found that caching the buffer between the subsequent paint calls 
 improves performance a lot:
 code
 /** Stores the prepared offscreen buffer */
 private BufferedImage bufferedImage;
 /**
  * Attempts to paint the display using an offscreen buffer.
  *
  * @param graphics
  * The source graphics context.
  *
  * @return
  * tttrue/tt if the display was painted using the offscreen
  * buffer; ttfalse/tt, otherwise.
  */
 private boolean paintBuffered(Graphics2D graphics) {
 boolean painted = false;
 // Paint the display into an offscreen buffer
 GraphicsConfiguration gc = graphics.getDeviceConfiguration();
 java.awt.Rectangle clipBounds = graphics.getClipBounds();
 if (bufferedImage == null ||
 bufferedImage.getWidth()  clipBounds.width ||
 bufferedImage.getHeight()  clipBounds.height)
 bufferedImage = gc.createCompatibleImage(clipBounds.width, 
 clipBounds.height,
 Transparency.OPAQUE);
 if (bufferedImage != null) {
 Graphics2D bufferedImageGraphics = 
 (Graphics2D)bufferedImage.getGraphics();
 bufferedImageGraphics.setClip(0, 0, clipBounds.width,
 ...
 /code 
 Advantages:
 1. it saves from costly allocation of a large object from possibly not-cached 
 memory region
 2. after a few repaints the GC moves this object to the tenured generation, 
 so that the young generation collector is much more efficient (longer times 
 between runs)
 3. the image probably stays most of the time in the L2 or L3 cache, which 
 saves on memory bandwidth and speeds up painting
 Disadvantages:
 1. uses some memory that is probably not required all the time, when the app 
 doesn't need to repaint anything large, however this is almost completely 
 shadowed by the excessive GC overhead due to continuous recreation of the 
 offscreen buffered image
 Anyway, we observed about 2-4x performance increase by this simple change - 
 now when running at 60 FPS it uses only about 25% of CPU for painting, and 
 the rest can be used by the application logic (AI, etc.). Previously 60 FPS 
 was probably the most we could achieve from Core2Duo 2.2 GHz. Of course, this 
 change won't affect any business applications that don't do animations etc.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira




Re: [jira] [Commented] (PIVOT-694) Improvement in ListButton clear() method

2011-07-27 Thread Greg Brown
 This fix only applies to ListButton. 
 I understand this, I'm thinking to make similar tests on other components 
 that contains some data and could be selected, and see after something has 
 been selected, if clear reset even the selection ... for example in 
 ListView/TableView/TreeView/etc.

Good point.

 On the clearSelection on ButtonGroup/RadioButtonGroup what do you think ?
 For example in for example ListView/TableView/TreeView it is present, so why 
 not even there ...

I thought this was already supported, but I haven't verified.




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
On 27 July 2011 21:51, Greg Brown gk_br...@verizon.net wrote:
 Unfortunately this thread is not referenced in the javadocs :)
 As this thread's existence proves, the javadocs still left me with questions.

 The Javadoc says pretty much the same thing as I wrote above:

With the crucial exception of how they accomplish what they
accomplish, and in particular, the use of a supplied ExecutorService.

This is a bit of a weird discussion to be having, because if the
javadocs included more information (such as the info in this thread),
then the thread would probably not exist.  But they don't, so it does
:)

 TaskSequence - Class that runs a sequence of tasks in series and notifies 
 listeners when all tasks are complete.

 TaskGroup - Class that runs a group of tasks in parallel and notifies 
 listeners when all tasks are complete.

I think you would agree that those single statements and the others in
the javadocs are not sufficient to understand how the tasks are
executed and therefore when it might be appropriate to use these
classes ...

 I just didn't (and still don't) see much difference between these
 classes and other utility methods or classes that have been
 rejected/declined as not offering much that an individual developer
 couldn't quickly knock up themselves, to their exact specifications.

 These classes add value because they address a common requirement for 
 application developers. They are non-trivial and aren't likely to vary from 
 application to application, so there's no need to force developers to write 
 them themselves.

... especially if their implementations are considered non-trivial.

I see this primarily as a case of missing/lacking javadocs.  The
purpose of the classes was not sufficiently clear to me as a consumer,
hence the original post.

More detail in the javadocs might save others the time that I lost.

Chris


Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 The Javadoc says pretty much the same thing as I wrote above:
 
 With the crucial exception of how they accomplish what they
 accomplish, and in particular, the use of a supplied ExecutorService.

I agree that the Javadoc could provide more detail. But the fact that TaskGroup 
and TaskSequence might use a different executor service honestly never occurred 
to me, so I didn't mention it.

 TaskSequence - Class that runs a sequence of tasks in series and notifies 
 listeners when all tasks are complete.
 
 TaskGroup - Class that runs a group of tasks in parallel and notifies 
 listeners when all tasks are complete.
 
 I think you would agree that those single statements and the others in
 the javadocs are not sufficient to understand how the tasks are
 executed and therefore when it might be appropriate to use these
 classes ...

Actually, I think they are sufficient. The only subtlety is which executor 
service runs the tasks. Otherwise, the classes do exactly what the Javadoc says.

I think this may be more of an API design question than a documentation issue. 
The question is - do you want to allow callers to execute sub-tasks in a 
different executor service from the parent or not? Or, put another way, is a 
developer likely to expect that sub-tasks are executed in the same executor as 
the parent or not?

If the former is true, then I think the existing API and documentation is 
sufficient (though admittedly sparse). If the latter is true, then moving the 
ExecutorService to the execute() method and adding more detail to the docs 
would definitely be appropriate.



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
(I'm not ignoring your points/questions - I will get back to them in a
separate reply)

The name TaskGroup, in combination with the javadocs, made me think of
a Group of Tasks that will be executed in parallel using the (default
or optionally supplied) ExecutorService.

I suppose I saw it as a ParallelTaskExecutor or TaskGroupExecutor, and
not a ParallelTask or TaskGroupTask.  This is probably where the
initial confusion came from.

Once you think of TaskGroup a just another Task, it follows that the
ExecutorService provided in the constructor would be used to just run
the execute() method of TaskGroup, as would happen with any other
Task.

So I might have approached it differently if the class names had an
extra 'Task' appended to them (TaskGroupTask/TaskSequenceTask), and/or
the javadocs said 'Task that runs...' rather than 'Class that runs
...'

Chris

On 27 July 2011 23:09, Greg Brown gk_br...@verizon.net wrote:
 The Javadoc says pretty much the same thing as I wrote above:

 With the crucial exception of how they accomplish what they
 accomplish, and in particular, the use of a supplied ExecutorService.

 I agree that the Javadoc could provide more detail. But the fact that 
 TaskGroup and TaskSequence might use a different executor service honestly 
 never occurred to me, so I didn't mention it.

 TaskSequence - Class that runs a sequence of tasks in series and notifies 
 listeners when all tasks are complete.

 TaskGroup - Class that runs a group of tasks in parallel and notifies 
 listeners when all tasks are complete.

 I think you would agree that those single statements and the others in
 the javadocs are not sufficient to understand how the tasks are
 executed and therefore when it might be appropriate to use these
 classes ...

 Actually, I think they are sufficient. The only subtlety is which executor 
 service runs the tasks. Otherwise, the classes do exactly what the Javadoc 
 says.

 I think this may be more of an API design question than a documentation 
 issue. The question is - do you want to allow callers to execute sub-tasks in 
 a different executor service from the parent or not? Or, put another way, is 
 a developer likely to expect that sub-tasks are executed in the same executor 
 as the parent or not?

 If the former is true, then I think the existing API and documentation is 
 sufficient (though admittedly sparse). If the latter is true, then moving the 
 ExecutorService to the execute() method and adding more detail to the docs 
 would definitely be appropriate.




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 I suppose I saw it as a ParallelTaskExecutor or TaskGroupExecutor, and
 not a ParallelTask or TaskGroupTask.  This is probably where the
 initial confusion came from.

I can understand that. OTOH, TaskGroupTask (or ParallelTaskGroupTask) is sort 
of verbose and arguably redundant, and as you noted, once you recognize that 
TaskGroup and TaskSequence extend Task, the existing behavior makes more sense.

G



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
In hindsight I could have rolled this into the last email if I had
read it more thoroughly first - sorry about that!

Responses below...

On 27 July 2011 23:09, Greg Brown gk_br...@verizon.net wrote:
 The Javadoc says pretty much the same thing as I wrote above:

 With the crucial exception of how they accomplish what they
 accomplish, and in particular, the use of a supplied ExecutorService.

 I agree that the Javadoc could provide more detail. But the fact that 
 TaskGroup and TaskSequence might use a different executor service honestly 
 never occurred to me, so I didn't mention it.

 TaskSequence - Class that runs a sequence of tasks in series and notifies 
 listeners when all tasks are complete.

 TaskGroup - Class that runs a group of tasks in parallel and notifies 
 listeners when all tasks are complete.

 I think you would agree that those single statements and the others in
 the javadocs are not sufficient to understand how the tasks are
 executed and therefore when it might be appropriate to use these
 classes ...

 Actually, I think they are sufficient. The only subtlety is which executor 
 service runs the tasks. Otherwise, the classes do exactly what the Javadoc 
 says.

Again, that was the crucial, missing part for me.  See the other email
I just sent for why.


 I think this may be more of an API design question than a documentation 
 issue. The question is - do you want to allow callers to execute sub-tasks in 
 a different executor service from the parent or not? Or, put another way, is 
 a developer likely to expect that sub-tasks are executed in the same executor 
 as the parent or not?

 If the former is true, then I think the existing API and documentation is 
 sufficient (though admittedly sparse). If the latter is true, then moving the 
 ExecutorService to the execute() method and adding more detail to the docs 
 would definitely be appropriate.


This is kind of why it didn't seem to me to belong in Pivot - having
to second guess how it will be used, and making it flexible enough to
justify its existence.

Looking at this from the point of view that these classes are
primarily Tasks with an in built listener (which seems to be how they
were designed), I can see how they could be useful to others.  That is
not how it looked from the perspective of these classes being some
kind of TaskExecutors, without them using a supplied ExecutorService.
(Refer to my other mail if you have not already)

Chris


Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
On 27 July 2011 23:43, Greg Brown gk_br...@verizon.net wrote:
 I suppose I saw it as a ParallelTaskExecutor or TaskGroupExecutor, and
 not a ParallelTask or TaskGroupTask.  This is probably where the
 initial confusion came from.

 I can understand that. OTOH, TaskGroupTask (or ParallelTaskGroupTask) is sort 
 of verbose and arguably redundant, and as you noted, once you recognize that 
 TaskGroup and TaskSequence extend Task, the existing behavior makes more 
 sense.


(I was/am not pushing to change the names - just explaining how I came
to the conclusions I did)

Long, but I wouldn't say verbose.  Especially in the world of (pre
1.7) java generics!

The name 'TaskGroupTask' captures something that is lost when the last
'Task' is removed.  That information is obviously available in the
javadocs themselves, source code or your IDE of choice, but it clearly
passed me by.  Arguably, a total lack of javadocs might have helped me
pick up on the fact that it is just a Task.

While TaskGroupTask initially looks redundant, I think it is easily
justifiable simply because it is a Task that does something with a
Group of Tasks (which in Pivot would be called a TaskGroup)

GroupedTask is shorter and makes it clear that it is a Task but loses
something along the way.  What is it that is grouped?
GroupedTasksTask is just hideous ;)


Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
By that logic, we'd need to qualify every class in the frame work. E.g. we 
wouldn't just have a Button, we'd have a ButtonComponent. That is obviously 
overkill, and I think it would be overkill here as well.

On Jul 27, 2011, at 1:11 PM, Chris Bartlett wrote:

 On 27 July 2011 23:43, Greg Brown gk_br...@verizon.net wrote:
 I suppose I saw it as a ParallelTaskExecutor or TaskGroupExecutor, and
 not a ParallelTask or TaskGroupTask.  This is probably where the
 initial confusion came from.
 
 I can understand that. OTOH, TaskGroupTask (or ParallelTaskGroupTask) is 
 sort of verbose and arguably redundant, and as you noted, once you recognize 
 that TaskGroup and TaskSequence extend Task, the existing behavior makes 
 more sense.
 
 
 (I was/am not pushing to change the names - just explaining how I came
 to the conclusions I did)
 
 Long, but I wouldn't say verbose.  Especially in the world of (pre
 1.7) java generics!
 
 The name 'TaskGroupTask' captures something that is lost when the last
 'Task' is removed.  That information is obviously available in the
 javadocs themselves, source code or your IDE of choice, but it clearly
 passed me by.  Arguably, a total lack of javadocs might have helped me
 pick up on the fact that it is just a Task.
 
 While TaskGroupTask initially looks redundant, I think it is easily
 justifiable simply because it is a Task that does something with a
 Group of Tasks (which in Pivot would be called a TaskGroup)
 
 GroupedTask is shorter and makes it clear that it is a Task but loses
 something along the way.  What is it that is grouped?
 GroupedTasksTask is just hideous ;)



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
Yes, that absolutely makes sense. The fact that it says class draws attention 
away from the fact that it is actually a Task.

On Jul 27, 2011, at 1:13 PM, Chris Bartlett wrote:

 On 27 July 2011 23:37, Chris Bartlett cbartlet...@gmail.com wrote:
 So I might have approached it differently if ...
 the javadocs said 'Task that runs...' rather than 'Class that runs
 
 If nobody has any objections I will make that small change today.



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
 (I was/am not pushing to change the names - just explaining how I came
 to the conclusions I did)


Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
Right - and I'm just explaining why they are not named that way.  :-)

On Jul 27, 2011, at 1:22 PM, Chris Bartlett wrote:

 (I was/am not pushing to change the names - just explaining how I came
 to the conclusions I did)



[jira] [Commented] (PIVOT-772) Exceptions thrown when calling getCharacterBounds of TextArea when incomplete lines exist

2011-07-27 Thread Roger Whitcomb (JIRA)

[ 
https://issues.apache.org/jira/browse/PIVOT-772?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13071898#comment-13071898
 ] 

Roger Whitcomb commented on PIVOT-772:
--

Hi Noel,
Just tried it and it seems to work for the normal cases, but if I do a paste 
into a TextArea the code goes into an infinite loop, eventually leading to 
StackOverflowError:
Exception in thread AWT-EventQueue-0 java.lang.StackOverflowError
at java.awt.Component.repaint(Unknown Source)
at java.awt.Component.repaint(Unknown Source)
at 
org.apache.pivot.wtk.ApplicationContext$DisplayHost.repaint(ApplicationContext.java:414)
at org.apache.pivot.wtk.Display.repaint(Display.java:97)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Component.repaint(Component.java:2041)
at org.apache.pivot.wtk.Viewport.repaint(Viewport.java:174)
at org.apache.pivot.wtk.Component.repaint(Component.java:2000)
at org.apache.pivot.wtk.Component.repaint(Component.java:1985)
at org.apache.pivot.wtk.Component.setSize(Component.java:935)
at 
org.apache.pivot.wtk.skin.ScrollPaneSkin.layoutHelper(ScrollPaneSkin.java:730)
at 
org.apache.pivot.wtk.skin.ScrollPaneSkin.layout(ScrollPaneSkin.java:585)
at org.apache.pivot.wtk.Component.layout(Component.java:1960)
at org.apache.pivot.wtk.Container.layout(Container.java:348)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at 
org.apache.pivot.wtk.Component.scrollAreaToVisible(Component.java:1831)
at 
org.apache.pivot.wtk.skin.TextAreaSkin.scrollCharacterToVisible(TextAreaSkin.java:462)
at org.apache.pivot.wtk.skin.TextAreaSkin.layout(TextAreaSkin.java:238)
at org.apache.pivot.wtk.Component.layout(Component.java:1960)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at org.apache.pivot.wtk.Component.validate(Component.java:1951)
at org.apache.pivot.wtk.Container.layout(Container.java:352)
at 

Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
Actually, I'm not sure that logic does follow.  Obviously the
Component suffix is (sanely) not used, but plenty of others are.

The 'TaskGroupTask' does actually capture something extra and the
'Task' suffix is certainly not without precedent.  In fact, as far as
I can see, TaskGroup and TaskSequence are actually the only named
subclasses of Task that *do not* have the 'Task' suffix.

(IOTask, LoadTask, LoadDataTask, RefreshFileListTask, SampleTask 
SleepTask x 2)
(DeleteQuery, GetQuery, PostQuery  PutQuery are all subclasses of
org.apache.pivot.web.Query so understandably have the 'Query' suffix
instead.)


TaskGroup implements a GroupTask and extends Task, but its name
doesn't reflect that it is a Task, perhaps just because the word
'Task' would be included twice.

ButtonGroup is a GroupButton so by the same logic, TaskGroup is fine
for GroupTask, but it just seems to (choose to) forget about the
Task part.

What if TaskGroup had a companion class that also extended Task and
implemented GroupRunnable?  It might wrap each Runnable in a Task
and delegate to TaskGroup for execution.  (Kind of a parallel Runnable
- Task adapter).

Should that be named RunnableGroup or RunnableGroupTask?


This is not a big deal, but the more I think about it, the more I
think it might have saved me a lot of time (and maybe even the thread)
if these classes did have the 'Task' suffix,


On 28 July 2011 00:20, Greg Brown gk_br...@verizon.net wrote:
 By that logic, we'd need to qualify every class in the frame work. E.g. we 
 wouldn't just have a Button, we'd have a ButtonComponent. That is 
 obviously overkill, and I think it would be overkill here as well.

 On Jul 27, 2011, at 1:11 PM, Chris Bartlett wrote:

 On 27 July 2011 23:43, Greg Brown gk_br...@verizon.net wrote:
 I suppose I saw it as a ParallelTaskExecutor or TaskGroupExecutor, and
 not a ParallelTask or TaskGroupTask.  This is probably where the
 initial confusion came from.

 I can understand that. OTOH, TaskGroupTask (or ParallelTaskGroupTask) is 
 sort of verbose and arguably redundant, and as you noted, once you 
 recognize that TaskGroup and TaskSequence extend Task, the existing 
 behavior makes more sense.


 (I was/am not pushing to change the names - just explaining how I came
 to the conclusions I did)

 Long, but I wouldn't say verbose.  Especially in the world of (pre
 1.7) java generics!

 The name 'TaskGroupTask' captures something that is lost when the last
 'Task' is removed.  That information is obviously available in the
 javadocs themselves, source code or your IDE of choice, but it clearly
 passed me by.  Arguably, a total lack of javadocs might have helped me
 pick up on the fact that it is just a Task.

 While TaskGroupTask initially looks redundant, I think it is easily
 justifiable simply because it is a Task that does something with a
 Group of Tasks (which in Pivot would be called a TaskGroup)

 GroupedTask is shorter and makes it clear that it is a Task but loses
 something along the way.  What is it that is grouped?
 GroupedTasksTask is just hideous ;)




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 Actually, I'm not sure that logic does follow.  Obviously the
 Component suffix is (sanely) not used, but plenty of others are.

We have used suffixes where there is no common alternative. For example, we 
have TabPane but not AccordionPane. Similarly, we have 
org.apache.pivot.web.Query, not QueryTask.

 TaskGroup implements a GroupTask and extends Task, but its name
 doesn't reflect that it is a Task, perhaps just because the word
 'Task' would be included twice.

Correct - it is redundant. You only need to qualify things if their meaning is 
ambiguous. Since a task group is defined as a task that is a group of 
tasks, the there is no ambiguity and the Task suffix is unnecessary. Same 
for task sequence.

 What if TaskGroup had a companion class that also extended Task and
 implemented GroupRunnable?  It might wrap each Runnable in a Task
 and delegate to TaskGroup for execution.  (Kind of a parallel Runnable
 - Task adapter).
 
 Should that be named RunnableGroup or RunnableGroupTask?

Difficult to answer since the question is somewhat contrived. We tend to focus 
heavily on real use cases since that also helps us come up with the most 
accurate names for the things that are being modeled.




Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 Thanks for bearing with me.  I assure you these are genuine
 questions asked because I get the impression you have studied API
 design quite a bit, or at the very least have an interest in it, and
 some strong opinions. (What other kind are worth a damn?)

:-)

 We have used suffixes where there is no common alternative. For example, we 
 have TabPane but not AccordionPane. Similarly, we have 
 org.apache.pivot.web.Query, not QueryTask.
 
 Yes, and then there are DeleteQuery, GetQuery, PostQuery  PutQuery.

That's because these names need to be qualified. You wouldn't know what a 
Delete is, so we need to make it explicit.

 a task group is defined as a task that is a group of tasks, the there is 
 no ambiguity and the Task suffix is unnecessary. Same for task sequence.
 
 Where is task group defined like that?   

In the API. That's what the TaskGroup class represents (though the Javadoc 
obviously does not make this clear).  ;-)

 That does make perfect sense but only with the knowledge of
 the class itself...

Right - some classes are just like that. You can't always bake everything you 
need to know about a class into the name.

 Both parts seem equally important to me. The 'TaskGroup' part to know
 that the Group interface is used to provide  manipulate the Tasks,

I think that making TaskGroup a Group was a mistake on my part. There is no 
need to ensure uniqueness here. 

In retrospect, I think these classes should have been called ParallelTaskGroup 
and SerialTaskGroup (no association with the Group interface). They should 
extend an abstract base class called TaskGroup that defines a sequence of tasks 
(i.e. getTasks():TaskSequence). TaskGroup would itself extend Task. I think 
that API helps makes it clear what each of these classes does.

 and the 'Task' suffix to know that it is a Task and can be executed
 and used as such.

Not to be rude, but...RTFM?  :-)  It is pretty clear from the Javadoc that 
TaskGroup extends Task. 

 If all of the other examples of classes that extend Task have a suffix
 (be it 'Task' or 'Query', with org.apache.pivot.web.Query itself being
 a special case) then I see a discrepancy which could lead to thinking
 that TaskGroup and TaskSequence are not Tasks until they are more
 closely examined.  

This comes back to my Accordion example. Did you assume that an Accordion was 
not a component because it was not called AccordionComponent? Probably not. 
Accordion is a natural name for this type of control, so a suffix is not 
necessary. Also, Accordion lives in the org.apache.pivot.wtk package, which you 
know primarily contains user interface components. Similarly, TaskGroup and 
TaskSequence live in org.apache.pivot.util.concurrent along with a handful of 
other classes, all of which are used to support the Task class. So that's a 
pretty strong clue as to what these classes do.

 If...other classes have a suffix, and are instantly identifiable
 as a Task just by class name, then why not these?  Or should the
 others not have them either? Or is it just personal preference and
 readability?

It is readability. We don't design class names for machine parsing. We design 
them for use by people, and the English language does not always map perfectly 
to things we want to model in code.

 It is a genuine question asked in an attempt to understand the naming
 of these two classes.  My logic (understandably) makes sense to me,
 but I just can't see where/why we differ regarding the suffix.
 
 Here is a quick dump of how my brain works...
 
 We both seem to agree on the Group naming
 GroupFoo == FooGroup  // Group of Foos
 GroupTask == TaskGroup  // Group of Tasks
 GroupRunnable == RunnableGroup  // Group of Runnables
 
 So the above question was intended to ask if you would consider the
 'Task' prefix to be redundant on things like this...

Again, I think part of the problem is that TaskGroup shouldn't actually *be* a 
Group. It should *have* a sequence of sub-tasks. I think that would help 
alleviate some confusion.



Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Chris Bartlett
On 28 July 2011 06:06, Greg Brown gk_br...@verizon.net wrote:
 We have used suffixes where there is no common alternative. For example, we 
 have TabPane but not AccordionPane. Similarly, we have 
 org.apache.pivot.web.Query, not QueryTask.

 Yes, and then there are DeleteQuery, GetQuery, PostQuery  PutQuery.

 That's because these names need to be qualified. You wouldn't know what a 
 Delete is, so we need to make it explicit.

Yeah, I agree they wouldn't mean much on their own, but that brings me
back to the 'TaskGroup == GroupTask' thing.  Without a suffix, some
meaning is also lost.  Without the 'Task' I don't know what a
TaskGroup is, just the data type  structure that it probably
represents.  Adding the Task suffix won't tell me everything, but it
would help.

My main point here was more the value that the qualifying suffix can
give, regardless of whether it is strictly required.

This kind of thing can certainly be taken to extremes though.  For
instance some organizations have arcane database naming rules that
prefix a kind of Hungarian Notation into the names of everything.  It
gets worse when they also choose to abbreviate by removing vowels and
the like.  In the end the only people who can decipher them at a
glance are the DBAs with tools that make the naming redundant.


 a task group is defined as a task that is a group of tasks, the there 
 is no ambiguity and the Task suffix is unnecessary. Same for task 
 sequence.

 Where is task group defined like that?

 In the API. That's what the TaskGroup class represents (though the Javadoc 
 obviously does not make this clear).  ;-)

That makes me feel a little less stupid.
It is a bit of a stretch to get to 'is defined as' from 'what it
represents', and expect users to  fill in the gaps.  If I know of a
class and its intent, then the name could be seen as having little
consequence other than aesthetics.

My original questions were about the intent of the classes, so that
side of things could certainly be improved to help the slower users
like myself.


 That does make perfect sense but only with the knowledge of
 the class itself...

 Right - some classes are just like that. You can't always bake everything you 
 need to know about a class into the name.

Yes, unless you are fond of 2 page wide class names, a class is
unlikely to capture every bit of pertinent information, but with these
classes, it seems like more of an over eager pruning of information
has occurred just to make the class names sound a little more natural.

They could easily have the Task suffix 'baked in' to indicate that
they are Tasks, but they don't because it was deemed redundant (or
just ugly).  I don't see Task bit as redundant, but do see its 'loss'
as a missed opportunity.

If there is a problem with the readability of a class name such
'TaskGroupTask' for instance, it suggests that the name is not right
and perhaps there is a better way to express it (maybe by looking at
it from the another angle such as how it will be used as opposed to
what it is).  Discarding part of it so that it reads better seems like
a hack for want of a better word and only addresses part of the
problem.
(Your suggestion in an upcoming paragraph is much better IMO)


 Both parts seem equally important to me. The 'TaskGroup' part to know
 that the Group interface is used to provide  manipulate the Tasks,

 I think that making TaskGroup a Group was a mistake on my part. There is no 
 need to ensure uniqueness here.

 In retrospect, I think these classes should have been called 
 ParallelTaskGroup and SerialTaskGroup (no association with the Group 
 interface). They should extend an abstract base class called TaskGroup that 
 defines a sequence of tasks (i.e. getTasks():TaskSequence). TaskGroup would 
 itself extend Task. I think that API helps makes it clear what each of these 
 classes does.

Yes that would certainly be clearer in my eyes.  The reuse of 'Group'
is unfortunate but understandable.

The name ParallelTaskGroup would certainly raise a few questions in my
mind and drive me to investigate further, unlike the 'camouflaged'
TaskGroup.


 and the 'Task' suffix to know that it is a Task and can be executed
 and used as such.

 Not to be rude, but...RTFM?  :-)  It is pretty clear from the Javadoc that 
 TaskGroup extends Task.

Yes, it is perfectly clear, but only once you get that far.  The point
there is obviously that if the suffix existed in the name, then it
might direct someone to the javadocs in the first place.  It is not as
if it is supposed to be a hidden implementation detail after all.  It
is how you make it do the one thing it does.

If TaskGroup was named ParallelTaskGroup, ParallelTaskExecutor or
something similarly far removed from its current name, I wouldn't be
stressing the 'Task' suffix.  I'm mainly doing it now because without
it, it just sounds like a GroupTasks, and it is used in the other
named Task subclasses.

'TaskGroupTask' is undoubtedly clunkly, but at least is 

Re: TaskGroup, TaskSequence ExecutorService

2011-07-27 Thread Greg Brown
 I think that making TaskGroup a Group was a mistake on my part. There is no 
 need to ensure uniqueness here.

Actually, it just occurred to me that uniqueness, while not strictly required, 
should certainly be encouraged. If you added the same task to a 
ParallelTaskGroup's task sequence more than once, you'd basically get 
serialized behavior, since only one thread could run the task at a time. So 
perhaps a Group is actually appropriate.

Further, it occurred to me that TaskSequence (or SerialTaskGroup) is not really 
all that useful, since it effectively executes the tasks synchronously. The 
main value of a Task (or more generally, a thread) is concurrency. Any old 
procedural code can run tasks in series.

Worse, TaskSequence executes sub-tasks by creating (or at least obtaining) a 
new thread per task, which isn't really necessary. The same results could be 
achieved by simply calling the synchronous version of execute() (the one that 
doesn't take a listener argument) on each task in the list.

So, I'm actually thinking that:

a) TaskSequence should be deprecated/removed

b) TaskGroup is actually an appropriate name  :-)

G