78
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2006, 2007 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 *******************************************************************************/
|
|
11 module org.eclipse.jface.internal.databinding.provisional.swt.WorkQueue;
|
|
12
|
|
13 import java.lang.all;
|
|
14
|
|
15 import java.util.HashSet;
|
|
16 import java.util.LinkedList;
|
|
17 import java.util.Set;
|
|
18
|
|
19 import org.eclipse.swt.SWT;
|
|
20 import org.eclipse.swt.widgets.Display;
|
|
21 import org.eclipse.swt.widgets.Event;
|
|
22 import org.eclipse.swt.widgets.Listener;
|
|
23
|
|
24 /**
|
|
25 * NON-API - Helper class to manage a queue of runnables to be posted to the UI thread in a way
|
|
26 * that they are only run once.
|
|
27 * @since 1.1
|
|
28 *
|
|
29 */
|
|
30 public class WorkQueue {
|
|
31
|
|
32 private bool updateScheduled = false;
|
|
33
|
|
34 private bool paintListenerAttached = false;
|
|
35
|
|
36 private LinkedList pendingWork = new LinkedList();
|
|
37
|
|
38 private Display d;
|
|
39
|
|
40 private Set pendingWorkSet = new HashSet();
|
|
41
|
|
42 private Runnable updateJob = new class() Runnable {
|
|
43 public void run() {
|
|
44 doUpdate();
|
|
45 updateScheduled = false;
|
|
46 }
|
|
47 };
|
|
48
|
|
49 private Listener paintListener = new class() Listener {
|
|
50 public void handleEvent(Event event) {
|
|
51 paintListenerAttached = false;
|
|
52 d.removeFilter(SWT.Paint, this);
|
|
53 doUpdate();
|
|
54 }
|
|
55 };
|
|
56
|
|
57 /**
|
|
58 * @param targetDisplay
|
|
59 */
|
|
60 public this(Display targetDisplay) {
|
|
61 d = targetDisplay;
|
|
62 }
|
|
63
|
|
64 private void doUpdate() {
|
|
65 for (;;) {
|
|
66 Runnable next;
|
|
67 synchronized (pendingWork) {
|
|
68 if (pendingWork.isEmpty()) {
|
|
69 break;
|
|
70 }
|
|
71 next = cast(Runnable) pendingWork.removeFirst();
|
|
72 pendingWorkSet.remove(next);
|
|
73 }
|
|
74
|
|
75 next.run();
|
|
76 }
|
|
77 }
|
|
78
|
|
79 /**
|
|
80 * Schedules some work to happen in the UI thread as soon as possible. If
|
|
81 * possible, the work will happen before the next control redraws. The given
|
|
82 * runnable will only be run once. Has no effect if this runnable has
|
|
83 * already been queued for execution.
|
|
84 *
|
|
85 * @param work
|
|
86 * runnable to execute
|
|
87 */
|
|
88 public void runOnce(Runnable work) {
|
|
89 synchronized (pendingWork) {
|
|
90 if (pendingWorkSet.contains(work)) {
|
|
91 return;
|
|
92 }
|
|
93
|
|
94 pendingWorkSet.add(work);
|
|
95
|
|
96 asyncExec(work);
|
|
97 }
|
|
98 }
|
|
99
|
|
100 /**
|
|
101 * Schedules some work to happen in the UI thread as soon as possible. If
|
|
102 * possible, the work will happen before the next control redraws. Unlike
|
|
103 * runOnce, calling asyncExec twice with the same runnable will cause that
|
|
104 * runnable to run twice.
|
|
105 *
|
|
106 * @param work
|
|
107 * runnable to execute
|
|
108 */
|
|
109 public void asyncExec(Runnable work) {
|
|
110 synchronized (pendingWork) {
|
|
111 pendingWork.add(work);
|
|
112 if (!updateScheduled) {
|
|
113 updateScheduled = true;
|
|
114 d.asyncExec(updateJob);
|
|
115 }
|
|
116
|
|
117 // If we're in the UI thread, add an event filter to ensure
|
|
118 // the work happens ASAP
|
|
119 if (Display.getCurrent() is d) {
|
|
120 if (!paintListenerAttached) {
|
|
121 paintListenerAttached = true;
|
|
122 d.addFilter(SWT.Paint, paintListener);
|
|
123 }
|
|
124 }
|
|
125 }
|
|
126 }
|
|
127
|
|
128 /**
|
|
129 * Cancels a previously-scheduled runnable. Has no effect if the given
|
|
130 * runnable was not previously scheduled or has already executed.
|
|
131 *
|
|
132 * @param toCancel
|
|
133 * runnable to cancel
|
|
134 */
|
|
135 public void cancelExec(Runnable toCancel) {
|
|
136 synchronized (pendingWork) {
|
|
137 pendingWork.remove(toCancel);
|
|
138 pendingWorkSet.remove(toCancel);
|
|
139 }
|
|
140 }
|
|
141
|
|
142 /**
|
|
143 * Cancels all pending work.
|
|
144 */
|
|
145 public void cancelAll() {
|
|
146 synchronized (pendingWork) {
|
|
147 pendingWork.clear();
|
|
148 pendingWorkSet.clear();
|
|
149 }
|
|
150 }
|
|
151 }
|