]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / events / EventQueue.java
diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventQueue.java
new file mode 100644 (file)
index 0000000..c4bfe82
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.scenegraph.g2d.events;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.LinkedList;\r
+\r
+import org.simantics.utils.datastructures.ListenerList;\r
+import org.simantics.utils.threads.IThreadWorkQueue;\r
+import org.simantics.utils.threads.SyncListenerList;\r
+\r
+/**\r
+ * @see IEventQueue\r
+ * @author Toni Kalajainen\r
+ */\r
+public class EventQueue implements IEventQueue, IEventHandler {\r
+\r
+    ListenerList<IEventQueueListener>     listeners    = new ListenerList<IEventQueueListener>(IEventQueueListener.class);\r
+    SyncListenerList<IEventQueueListener> listeners2   = new SyncListenerList<IEventQueueListener>(IEventQueueListener.class);\r
+    ListenerList<EventCoalescer>          coalescers = new ListenerList<EventCoalescer>(EventCoalescer.class);\r
+    LinkedList<Event>                     queue        = new LinkedList<Event>();\r
+\r
+    IEventHandler                         handler;\r
+\r
+    public EventQueue(IEventHandler handler) {\r
+        assert (handler != null);\r
+        this.handler = handler;\r
+    }\r
+\r
+    @Override\r
+    public int getEventMask() {\r
+        return EventTypes.AnyMask;\r
+    }\r
+\r
+    @Override\r
+    public synchronized void queueEvent(Event e) {\r
+        // coalesce with last\r
+        EventCoalescer[] css = coalescers.getListeners();\r
+        if (css.length > 0 && !queue.isEmpty()) {\r
+            Event last = queue.get(queue.size() - 1);\r
+            Event coalesced = null;\r
+            for (EventCoalescer ecs : css) {\r
+                coalesced = ecs.coalesce(last, e);\r
+                if (coalesced != null)\r
+                    break;\r
+            }\r
+            if (coalesced == last)\r
+                return;\r
+            if (coalesced != null) {\r
+                // replace last with coalesced\r
+                queue.remove(queue.size() - 1);\r
+                queue.addLast(coalesced);\r
+                int index = queue.size() - 1;\r
+                fireEventAdded(coalesced, index);\r
+                return;\r
+            }\r
+        }\r
+\r
+        queue.addLast(e);\r
+        int index = queue.size() - 1;\r
+        fireEventAdded(e, index);\r
+    }\r
+\r
+    @Override\r
+    public synchronized void queueFirst(Event e) {\r
+        // coalescale with first\r
+        EventCoalescer[] css = coalescers.getListeners();\r
+        if (css.length > 0 && !queue.isEmpty()) {\r
+            Event first = queue.get(0);\r
+            Event coalesced = null;\r
+            for (EventCoalescer ecs : css) {\r
+                coalesced = ecs.coalesce(e, first);\r
+                if (coalesced != null)\r
+                    break;\r
+            }\r
+            if (coalesced == first)\r
+                return;\r
+            if (coalesced != null) {\r
+                // replace last with coalesced\r
+                queue.remove(0);\r
+                queue.addFirst(coalesced);\r
+                fireEventAdded(coalesced, 0);\r
+                return;\r
+            }\r
+        }\r
+\r
+        queue.addFirst(e);\r
+        fireEventAdded(e, 0);\r
+    }\r
+\r
+    public void handleEvents() {\r
+        int eventsHandled = 0;\r
+        Event[] events = null;\r
+        do {\r
+            synchronized (this) {\r
+                events = queue.toArray(new Event[queue.size()]);\r
+                queue.clear();\r
+            }\r
+            for (Event e : events) {\r
+                if (EventTypes.passes(handler, e))\r
+                    handler.handleEvent(e);\r
+                eventsHandled++;\r
+            }\r
+        } while (events.length > 0);\r
+        if (eventsHandled > 0)\r
+            fireQueueEmpty();\r
+    }\r
+\r
+    @Override\r
+    public void addEventCoalesceler(EventCoalescer coalescaler) {\r
+        coalescers.add(coalescaler);\r
+    }\r
+\r
+    @Override\r
+    public void removeEventCoalesceler(EventCoalescer coalescaler) {\r
+        coalescers.remove(coalescaler);\r
+    }\r
+\r
+    @Override\r
+    public boolean handleEvent(Event e) {\r
+        handleEvents();\r
+        return EventTypes.passes(handler, e) ? handler.handleEvent(e) : false;\r
+    }\r
+\r
+    @Override\r
+    public void addQueueListener(IEventQueueListener listener) {\r
+        listeners.add(listener);\r
+    }\r
+\r
+    @Override\r
+    public synchronized int size() {\r
+        return queue.size();\r
+    }\r
+\r
+    @Override\r
+    public synchronized boolean isEmpty() {\r
+        return queue.isEmpty();\r
+    }\r
+\r
+    @Override\r
+    public void removeQueueListener(IEventQueueListener listener) {\r
+        listeners.remove(listener);\r
+    }\r
+\r
+    Method onEventAdded = SyncListenerList.getMethod(IEventQueueListener.class, "onEventAdded");\r
+\r
+    protected void fireEventAdded(Event e, int index) {\r
+        for (IEventQueueListener eql : listeners.getListeners())\r
+            eql.onEventAdded(this, e, index);\r
+        listeners2.fireEventSync(onEventAdded, this, e, index);\r
+    }\r
+\r
+    Method onQueueEmpty = SyncListenerList.getMethod(IEventQueueListener.class, "onQueueEmpty");\r
+\r
+    protected void fireQueueEmpty() {\r
+        for (IEventQueueListener eql : listeners.getListeners())\r
+            eql.onQueueEmpty(this);\r
+        listeners2.fireEventSync(onQueueEmpty, this);\r
+    }\r
+\r
+    @Override\r
+    public void addQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {\r
+        listeners2.add(thread, listener);\r
+    }\r
+\r
+    @Override\r
+    public void removeQueueListener(IEventQueueListener listener, IThreadWorkQueue thread) {\r
+        listeners2.remove(thread, listener);\r
+    }\r
+\r
+}\r