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