1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.g2d.events;
\r
14 import java.lang.reflect.Method;
\r
15 import java.util.LinkedList;
\r
17 import org.simantics.utils.datastructures.ListenerList;
\r
18 import org.simantics.utils.threads.IThreadWorkQueue;
\r
19 import org.simantics.utils.threads.SyncListenerList;
\r
23 * @author Toni Kalajainen
\r
25 public class EventQueue implements IEventQueue, IEventHandler {
\r
27 ListenerList<IEventQueueListener> listeners = new ListenerList<IEventQueueListener>(IEventQueueListener.class);
\r
28 SyncListenerList<IEventQueueListener> listeners2 = new SyncListenerList<IEventQueueListener>(IEventQueueListener.class);
\r
29 ListenerList<EventCoalescer> coalescers = new ListenerList<EventCoalescer>(EventCoalescer.class);
\r
30 LinkedList<Event> queue = new LinkedList<Event>();
\r
32 IEventHandler handler;
\r
34 public EventQueue(IEventHandler handler) {
\r
35 assert (handler != null);
\r
36 this.handler = handler;
\r
40 public int getEventMask() {
\r
41 return EventTypes.AnyMask;
\r
45 public synchronized void queueEvent(Event e) {
\r
46 // coalesce with last
\r
47 EventCoalescer[] css = coalescers.getListeners();
\r
48 if (css.length > 0 && !queue.isEmpty()) {
\r
49 Event last = queue.get(queue.size() - 1);
\r
50 Event coalesced = null;
\r
51 for (EventCoalescer ecs : css) {
\r
52 coalesced = ecs.coalesce(last, e);
\r
53 if (coalesced != null)
\r
56 if (coalesced == last)
\r
58 if (coalesced != null) {
\r
59 // replace last with coalesced
\r
60 queue.remove(queue.size() - 1);
\r
61 queue.addLast(coalesced);
\r
62 int index = queue.size() - 1;
\r
63 fireEventAdded(coalesced, index);
\r
69 int index = queue.size() - 1;
\r
70 fireEventAdded(e, index);
\r
74 public synchronized void queueFirst(Event e) {
\r
75 // coalescale with first
\r
76 EventCoalescer[] css = coalescers.getListeners();
\r
77 if (css.length > 0 && !queue.isEmpty()) {
\r
78 Event first = queue.get(0);
\r
79 Event coalesced = null;
\r
80 for (EventCoalescer ecs : css) {
\r
81 coalesced = ecs.coalesce(e, first);
\r
82 if (coalesced != null)
\r
85 if (coalesced == first)
\r
87 if (coalesced != null) {
\r
88 // replace last with coalesced
\r
90 queue.addFirst(coalesced);
\r
91 fireEventAdded(coalesced, 0);
\r
97 fireEventAdded(e, 0);
\r
100 public void handleEvents() {
\r
101 int eventsHandled = 0;
\r
102 Event[] events = null;
\r
104 synchronized (this) {
\r
105 events = queue.toArray(new Event[queue.size()]);
\r
108 for (Event e : events) {
\r
109 if (EventTypes.passes(handler, e))
\r
110 handler.handleEvent(e);
\r
113 } while (events.length > 0);
\r
114 if (eventsHandled > 0)
\r
119 public void addEventCoalesceler(EventCoalescer coalescaler) {
\r
120 coalescers.add(coalescaler);
\r
124 public void removeEventCoalesceler(EventCoalescer coalescaler) {
\r
125 coalescers.remove(coalescaler);
\r
129 public boolean handleEvent(Event e) {
\r
131 return EventTypes.passes(handler, e) ? handler.handleEvent(e) : false;
\r
135 public void addQueueListener(IEventQueueListener listener) {
\r
136 listeners.add(listener);
\r
140 public synchronized int size() {
\r
141 return queue.size();
\r
145 public synchronized boolean isEmpty() {
\r
146 return queue.isEmpty();
\r
150 public void removeQueueListener(IEventQueueListener listener) {
\r
151 listeners.remove(listener);
\r
154 Method onEventAdded = SyncListenerList.getMethod(IEventQueueListener.class, "onEventAdded");
\r
156 protected void fireEventAdded(Event e, int index) {
\r
157 for (IEventQueueListener eql : listeners.getListeners())
\r
158 eql.onEventAdded(this, e, index);
\r
159 listeners2.fireEventSync(onEventAdded, this, e, index);
\r
162 Method onQueueEmpty = SyncListenerList.getMethod(IEventQueueListener.class, "onQueueEmpty");
\r
164 protected void fireQueueEmpty() {
\r
165 for (IEventQueueListener eql : listeners.getListeners())
\r
166 eql.onQueueEmpty(this);
\r
167 listeners2.fireEventSync(onQueueEmpty, this);
\r
171 public void addQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {
\r
172 listeners2.add(thread, listener);
\r
176 public void removeQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {
\r
177 listeners2.remove(thread, listener);
\r