1 package org.simantics.modeling.ui.diagramEditor;
3 import gnu.trove.map.hash.TObjectLongHashMap;
5 import java.util.ArrayDeque;
7 import org.eclipse.swt.widgets.Display;
10 public class DisposingPolicy {
12 public static final boolean DEBUG = false;
14 public static final int MAX_QUEUE_LENGTH = 8;
15 public static final long DISPOSE_TIME = 30000L; // ms
16 public static final long MIN_DELAY = 200L; // ms
18 private volatile int maxQueueLength;
19 private ArrayDeque<Runnable> disposerQueue;
20 private TObjectLongHashMap<Runnable> disposeTime;
21 private Runnable currentlyScheduled = null;
23 private Runnable disposeOne = () -> {
24 if(!disposerQueue.isEmpty()) {
25 Runnable runnable = disposerQueue.removeFirst();
26 disposeTime.remove(runnable);
27 currentlyScheduled = null;
30 System.out.println("Executed disposer " + runnable);
31 if(!disposerQueue.isEmpty())
36 public DisposingPolicy() {
37 this(MAX_QUEUE_LENGTH);
40 public DisposingPolicy(int maxQueueLength) {
41 this.maxQueueLength = maxQueueLength;
42 this.disposerQueue = new ArrayDeque<>(maxQueueLength);
43 this.disposeTime = new TObjectLongHashMap<>(maxQueueLength);
46 public void setMaxQueueLength(int maxQueueLength) {
47 this.maxQueueLength = maxQueueLength;
50 private void scheduleDispose() {
51 currentlyScheduled = disposerQueue.peekFirst();
52 long delay = Math.max(
53 disposeTime.get(currentlyScheduled) - System.currentTimeMillis(),
55 Display.getCurrent().timerExec((int)delay, disposeOne);
57 System.out.println("Scheduled disposer " + currentlyScheduled + " in " + delay + " ms");
61 * Runs the disposer either after DISPOSE_TIME or when there are
62 * more than {@link #maxQueueLength} disposers active and this is first
63 * of them (by activation order). This method must be called from
66 public void addDisposer(Runnable disposer) {
68 System.out.println("Added disposer " + disposer);
69 if(disposeTime.contains(disposer))
71 if(disposerQueue.size() >= maxQueueLength)
73 disposerQueue.addLast(disposer);
74 disposeTime.put(disposer, System.currentTimeMillis()+DISPOSE_TIME);
75 if(disposerQueue.size() == 1)
80 * Cancels a disposer added before. This method must be called from
83 public void removeDisposer(Runnable disposer) {
85 System.out.println("Removed disposer " + disposer);
86 disposerQueue.remove(disposer);
87 disposeTime.remove(disposer);
88 if(disposer == currentlyScheduled) {
89 currentlyScheduled = null;
90 if(!disposerQueue.isEmpty())