net.groboclown.gui.paintpipe.v1
Class SortingPainter

java.lang.Object
  |
  +--net.groboclown.gui.paintpipe.v1.PainterThread
        |
        +--net.groboclown.gui.paintpipe.v1.OutputPainter
              |
              +--net.groboclown.gui.paintpipe.v1.PipePainter
                    |
                    +--net.groboclown.gui.paintpipe.v1.SortingPainter
Direct Known Subclasses:
SimpleZOrderPainter, ZOrderPainter

public abstract class SortingPainter
extends PipePainter

The SortingPainter works like a PipePainter, but sends the subclass methods waiting on events, the events in correct order.

These are all dependent upon the threads which draw each z-depth. If a lower depth takes longer then a higher depth, then all depths above the slow depth will be idly waiting. But that's the cost of Z-Ordering.

In general, the Sorting Painter cannot send incremental updates to the pipe. Instead, the Sorting Painter spends its time in a thread sorting each paint event. In some cases, this is a complex problem requiring laborious computations.

In this pattern, if the Sorting Painter cannot send incremental updates to the pipe, then the next stage of painting should be done in the same thread as the sorter. This way, the painter has a two-phase life-cycle. Phase one is sorting incoming paint events, and Phase two is taking those sorted events and transforming them into a conglomerate data event for the next process on the pipe. This helps to save precious resources, and synchronization/setup time for the added thread.

In order to implement sorting, the subclass must provide a Collection implementation which inserts each item in order. After all the items have been inserted into the Collection, each item is found and removed via the Collection's Iterator. So the Collection must support addition and removal of elements. After all the events have been removed from the Collection, then passed to processImage(net.groboclown.gui.paintpipe.v1.PaintEvent), then a call to finishPaint() completes the frame rendering process.

In order to support subclasses creating their Collection after their construction time, the method setCollection(java.util.Collection) allows after-construction registration of the Collection instance. However, if this is never called (and, thus, the internal Collection is null), then a NullPointerException will be thrown during run-time.

The only operations performed on the collection are: clear(), add( Object ), and iterator(). Iterator must implement all the methods provided.

So the only thing the subclass needs to support for run-time maintenance of the Collection is creation at initialize() time, and possible deletion at cleanup() time.

Version:
1.0
Author:
Matt Albrecht
See Also:
OutputPainter, PaintQueue

Inner classes inherited from class net.groboclown.gui.paintpipe.v1.PainterThread
PainterThread.PaintRunnable
 
Field Summary
private  Collection sortedEvents
           
 
Fields inherited from class net.groboclown.gui.paintpipe.v1.PipePainter
inQ
 
Fields inherited from class net.groboclown.gui.paintpipe.v1.OutputPainter
outq
 
Fields inherited from class net.groboclown.gui.paintpipe.v1.PainterThread
frameNumber, group, isPainting, METRICS, metricsListeners, name, numberPaintAttempts, numberWaitForEvent, painter, priority, RUN_NEVER_STARTED, RUN_PAUSED, RUN_REQUESTED_PAUSE, RUN_REQUESTED_STOP, RUN_RUNNING, RUN_STOPPED, runState, sentPaintFinishedEvent, startTimeMillis, syncThis, totalPaintTimeMillis, totalWaitForEventTimeMillis
 
Constructor Summary
SortingPainter(PaintQueue in)
          Creates a new SimpleZOrderPainter with the given input PaintQueue, and no output PaintQueue.
SortingPainter(PaintQueue in, PaintQueue out)
          Creates a new SimpleZOrderPainter with the given input and output PaintQueues.
 
Method Summary
protected  boolean areMoreEvents()
          Checks if any more events need to be pulled from the queue.
protected  void finishPaint()
          Completes the painting process at the end of the paint.
protected  void flushEvents()
          If any events or images are in a good enough position to send, fire them all in this event.
 void paintFinished(PaintFinishedEvent pfe)
          Clear up our data structure for the next frame.
protected  void processEvent(PaintEvent pe)
          Processes the next PaintEvent from the input queue.
protected abstract  void processImage(PaintEvent pe)
          Processes a valid image in the correct depth order.
 void setCollection(Collection c)
          Registers a collection as the sorter.
 
Methods inherited from class net.groboclown.gui.paintpipe.v1.PipePainter
getInputQueue, paint
 
Methods inherited from class net.groboclown.gui.paintpipe.v1.OutputPainter
firePaintEvent, getOutputQueue
 
Methods inherited from class net.groboclown.gui.paintpipe.v1.PainterThread
addMetricsListener, canPause, canStop, cleanup, fireMetricsPaint, fireMetricsWait, getFrameNumber, getNumberPaintCalls, getNumberWaitForEventTimes, getStartTimeMillis, getTotalPaintTimeMillis, getTotalWaitForEventTimeMillis, initialize, isAlive, isInterrupted, isRunning, isStopImpending, isStopping, isSuspended, isWaitingForEvent, join, killPainting, removeMetricsListener, resume, start, stop, stopInterrupt, stopInterruptJoin, stopJoin, suspend, suspendInterrupt
 
Methods inherited from class java.lang.Object
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait
 

Field Detail

sortedEvents

private Collection sortedEvents
Constructor Detail

SortingPainter

public SortingPainter(PaintQueue in)
Creates a new SimpleZOrderPainter with the given input PaintQueue, and no output PaintQueue.
Parameters:
in - the input queue, listened to by this thread.

SortingPainter

public SortingPainter(PaintQueue in,
                      PaintQueue out)
Creates a new SimpleZOrderPainter with the given input and output PaintQueues.
Parameters:
in - the input queue, listened to by this thread.
out - the output queue, in which events are fired to. If need be, this output queue can be null.
Method Detail

paintFinished

public void paintFinished(PaintFinishedEvent pfe)
                   throws InterruptedException
Clear up our data structure for the next frame.
Overrides:
paintFinished in class PipePainter

setCollection

public void setCollection(Collection c)
Registers a collection as the sorter.
Throws:
IllegalArgumentException - thrown if the Collection is null.
IllegalStateException - thrown if the internal Collection has already been set.

processEvent

protected final void processEvent(PaintEvent pe)
Processes the next PaintEvent from the input queue. It doesn't have to post any output events, but it can.

This puts the event into the proper location, depending on the Z-Depth. Unknown events are ignored. When a Z-depth is ready for outputting to the pipe, processImage is called. Events to a to-be fired event depth are overridden, and previously fired depth events are ignored.

Overrides:
processEvent in class PipePainter
Parameters:
pe - the event which is to be processed.

areMoreEvents

protected boolean areMoreEvents()
Checks if any more events need to be pulled from the queue. This always returns true. A subclass may wish to override this functionality if it believes differently.
Overrides:
areMoreEvents in class PipePainter
Returns:
true if it is believed that more PaintEvents are going to be used in the current frame creation.

flushEvents

protected final void flushEvents()
If any events or images are in a good enough position to send, fire them all in this event. You should not fire a FlushPaintingEvent here, since it is done for you in the PipePainter.paint() method above.
Overrides:
flushEvents in class PipePainter

processImage

protected abstract void processImage(PaintEvent pe)
Processes a valid image in the correct depth order.

finishPaint

protected void finishPaint()
Completes the painting process at the end of the paint. Only called by the flushEvents() method, so it is guaranteed (except under InterruptedExceptions) to be the last method called.


Written under the LGPL