RepaintEventProducerpublic class RepaintEventProducer extends Object implements com.sun.midp.events.EventListenerThis class performs all of the repaint event handling. |
Fields Summary |
---|
private com.sun.midp.events.EventQueue | eventQueueCached reference to the MIDP event queue. | private RepaintEvent | pooledEvent1Repaint event free for reuse. | private RepaintEvent | pooledEvent2Repaint event free for reuse. | private RepaintEvent | pooledEvent3Repaint event free for reuse. | private RepaintEvent | queuedEventRepaint event in the queue or waiting to be moved to the processed
slot. Events are rotated to different slots in
preprocessRepaints . | private RepaintEvent | eventInProcessRepaint event being processed (queue has event also) or
has been processed (no event in the queue). |
Constructors Summary |
---|
public RepaintEventProducer(com.sun.midp.events.EventQueue theEventQueue)The constructor LCDUI repaint events handler.
eventQueue = theEventQueue;
pooledEvent1 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);
pooledEvent2 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);
pooledEvent3 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);
eventQueue.registerEventListener(EventTypes.REPAINT_EVENT, this);
|
Methods Summary |
---|
public boolean | preprocess(com.sun.midp.events.Event event, com.sun.midp.events.Event waitingEvent)Preprocess an event that is being posted to the event queue.
/*
* Because of the needs of serviceRepaints the preprocessing
* is done in scheduleRepaint.
*/
return true;
| public void | process(com.sun.midp.events.Event genericEvent)Process an event.
RepaintEvent event = (RepaintEvent)genericEvent;
synchronized (this) {
queuedEvent = null;
eventInProcess = event;
}
/*
* Target DisplayEventConsumer is obtained directly from event field.
* Assumed that target consumer is not null.
*/
event.display.handleRepaintEvent(
event.paintX1, event.paintY1,
event.paintX2, event.paintY2,
event.paintTarget);
synchronized (this) {
/* Change the ID here to signal waitForRepaint. */
eventInProcess.perUseID++;
eventInProcess = null;
// ServiceRepaints may be blocking.
notifyAll();
}
| public void | scheduleRepaint(DisplayEventConsumer d, int x, int y, int w, int h, java.lang.Object target)Called to schedule a repaint of the current Displayable
as soon as possible.
RepaintEvent freeEvent;
synchronized (this) {
freeEvent = pooledEvent1;
freeEvent.setRepaintFields(d, x, y, w, h, target);
if (queuedEvent == null) {
/*
* Since the queue does not lock posting during event
* processing, we need to rotate 3 repaint events for reuse.
*
* 1 for the queued event, 1 for the event begin processed
* and 1 for temporary use when merging a new event with
* a queued event.
*
* Event pooling is done because game can generate upto 15
* repaints a second and cause a lot garbage collection if
* we created new repaint every time.
*/
pooledEvent1 = pooledEvent2;
pooledEvent2 = pooledEvent3;
pooledEvent3 = freeEvent;
queuedEvent = freeEvent;
eventQueue.post(queuedEvent);
} else if (queuedEvent.display != d) {
/*
* A new display has come to the foreground so don't
* bother paint the display in the queued event.
*
* Overwrite this fields in queue event with new values.
*/
queuedEvent.setRepaintFields(d, x, y, w, h, target);
} else {
/*
* When there is a pending repaint
* union the dirty regions into one event
*/
if (queuedEvent.paintX1 > freeEvent.paintX1) {
queuedEvent.paintX1 = freeEvent.paintX1;
}
if (queuedEvent.paintY1 > freeEvent.paintY1) {
queuedEvent.paintY1 = freeEvent.paintY1;
}
if (queuedEvent.paintX2 < freeEvent.paintX2) {
queuedEvent.paintX2 = freeEvent.paintX2;
}
if (queuedEvent.paintY2 < freeEvent.paintY2) {
queuedEvent.paintY2 = freeEvent.paintY2;
}
queuedEvent.paintTarget = null;
}
}
| public void | serviceRepaints()Called to block the calling MIDlet until the the pending repaint
operation is performed.
Does not return until the pending repaint (if any)
has been processed.
if (EventQueue.isDispatchThread()) {
Event event;
if (eventInProcess != null) {
/*
* We are in the midst of a calling the application's
* paint method, avoid recursion, simply return
*/
return;
}
/*
* Since we are in the dispatch thread, at this point
* there can only one repaint in the queue so remove it
* from the queue and process it.
*/
event = eventQueue.remove(EventTypes.REPAINT_EVENT);
/* Do not hold a lock when calling out to the application */
if (event != null) {
process(event);
}
} else {
/*
* We only want paint events to be process in the dispatch
* to avoid deadlocks. So wait for the repaint event to occur.
*/
waitForCurrentRepaintEvents();
}
| private void | waitForCurrentRepaintEvents()Wait for the event queue to process all of the events currently
in the queue but not any new ones after the start of this
method.
RepaintEvent eventToWaitFor = null;
int currentEventUseID;
synchronized (this) {
if (queuedEvent != null) {
eventToWaitFor = queuedEvent;
} else if (eventInProcess != null) {
eventToWaitFor = eventInProcess;
} else {
/* Nothing to wait for, done. */
return;
}
currentEventUseID = eventToWaitFor.perUseID;
while (eventToWaitFor.perUseID == currentEventUseID) {
try {
wait();
} catch (InterruptedException ie) {
/* The application wants this thread to unblock */
break;
}
}
}
|
|