]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Updater.java
Replace scheduleAtFixedRate with scheduleWithFixedDelay
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / profile / Updater.java
1 package org.simantics.diagram.profile;
2
3 import java.util.HashMap;
4 import java.util.HashSet;
5 import java.util.Map;
6 import java.util.concurrent.TimeUnit;
7 import java.util.concurrent.atomic.AtomicBoolean;
8
9 import org.simantics.diagram.elements.DiagramNodeUtil;
10 import org.simantics.g2d.canvas.ICanvasContext;
11 import org.simantics.scenegraph.INode;
12 import org.simantics.scenegraph.g2d.G2DNode;
13 import org.simantics.utils.threads.ThreadUtils;
14
15 class Updater implements Runnable {
16
17         private static Updater INSTANCE;
18         
19         Map<INode, ICanvasContext> requesters = new HashMap<INode, ICanvasContext>();
20         
21         AtomicBoolean state = new AtomicBoolean(false);
22         
23         private static long time = System.nanoTime();
24         
25         private Updater() {
26         }
27         
28         @Override
29         public void run() {
30
31                 // Stop this if nothing is to be done, need synchonization since this is not AWT
32                 synchronized(requesters) {
33                         if(requesters.isEmpty()) {
34                                 state.set(false);
35                                 throw new RuntimeException();
36                         }
37                 }
38                 
39                 // TODO: in unit tests this should not be AWT
40                 ThreadUtils.AWT_EDT.execute(new Runnable() {
41
42                         @Override
43                         public void run() {
44                                 
45                                 time = System.nanoTime();
46                                 
47                                 synchronized(requesters) {
48                                         HashSet<ICanvasContext> ctxSet = new HashSet<ICanvasContext>();
49                                         for(ICanvasContext ctx : requesters.values()) {
50                                                 if(ctx != null) {
51                                                         if(ctxSet.add(ctx)) ctx.getContentContext().setDirty();
52                                                 }
53                                         }
54                                 }
55                                                 
56                         }
57                         
58                 });
59                 
60         }
61         
62         public void register(INode node) {
63                 // We use the size of this map to determine whether updates are needed, this is done in AWT thread
64                 synchronized(requesters) {
65                         if(requesters.size() == 0) {
66                                 if(state.compareAndSet(false, true)) {
67                                         ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(this, 0, 500, TimeUnit.MILLISECONDS);
68                                 }
69                         }
70                         ICanvasContext context = DiagramNodeUtil.getPossibleCanvasContext((G2DNode)node);
71                         requesters.put(node, context);
72                 }
73         }
74         
75         public void unregister(INode node) {
76                 synchronized(requesters) {
77                         requesters.remove(node);
78                 }
79         }
80         
81         public long getTime() {
82                 return time;
83         }
84         
85         public static Updater getInstance() {
86                 if(INSTANCE == null) {
87                         INSTANCE = new Updater();
88                 }
89                 return INSTANCE;
90         }
91         
92 }