]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/EventHandlerStack.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / events / EventHandlerStack.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 /*
13  *
14  * @author Toni Kalajainen
15  */
16 package org.simantics.scenegraph.g2d.events;
17
18 import java.util.concurrent.atomic.AtomicBoolean;
19
20 import org.simantics.utils.datastructures.prioritystack.PriorityStack;
21 import org.simantics.utils.threads.CurrentThread;
22 import org.simantics.utils.threads.IThreadWorkQueue;
23 import org.simantics.utils.threads.ThreadUtils;
24
25 /**
26  * @see IEventHandlerStack
27  * 
28  * @author Toni Kalajainen
29  */
30 public class EventHandlerStack extends PriorityStack<IEventHandler> implements IEventHandlerStack {
31
32     IThreadWorkQueue thread;
33
34     /**
35      * Creates a new event handler stack.
36      * 
37      * Any event handled with this stack is handled in current thread.
38      */
39     public EventHandlerStack() {
40         super(IEventHandler.class);
41         this.thread = CurrentThread.getThreadAccess();
42     }
43
44     /**
45      * Creates a new event handler stack. Any event handled with this stack is
46      * handled in the given thread.
47      * 
48      * @param eventHandlingThread
49      */
50     public EventHandlerStack(IThreadWorkQueue eventHandlingThread) {
51         super(IEventHandler.class);
52         this.thread = eventHandlingThread;
53     }
54
55     @Override
56     public int getEventMask() {
57         return EventTypes.AnyMask;
58     }
59
60     @Override
61     public boolean handleEvent(final Event e) {
62         final int eventType = EventTypes.toTypeMask(e);
63         if (thread.currentThreadAccess()) {
64             // Send event through interactor stack
65             IEventHandler list[] = toArray();
66             for (int i = list.length - 1; i >= 0; i--)
67                 if (EventTypes.passes(list[i], eventType) && list[i].handleEvent(e))
68                     return true;
69             return false;
70         } else {
71             final AtomicBoolean result = new AtomicBoolean(false);
72             Runnable run = new Runnable() {
73                 @Override
74                 public void run() {
75                     // Send event through interactor stack
76                     IEventHandler list[] = toArray();
77                     for (int i = list.length - 1; i >= 0; i--)
78                         if (EventTypes.passes(list[i], eventType) && list[i].handleEvent(e)) {
79                             result.set(true);
80                             return;
81                         }
82                 }
83             };
84             ThreadUtils.syncExec(thread, run);
85             return result.get();
86         }
87     }
88
89 }