Prevent ConcurrentModificationException in StyledRouteGraphRenderer 38/2238/2
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 25 Sep 2018 21:03:39 +0000 (00:03 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 25 Sep 2018 21:04:06 +0000 (21:04 +0000)
Fixed via ThreadLocal-based caching of reused data structures.

gitlab #132

Change-Id: I42a3d3a160f1f7a9ed30d10cca84e1dc5b6488fa

bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java

index b084e5875714938026400e5a8b6c938659e3ca71..dd9473042152d0c3af43244d9549d63e4c649e4b 100644 (file)
@@ -36,9 +36,13 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab
 
        protected final ConnectionStyle style;
 
+       private static class Cache {
+               Path2D path = new Path2D.Double();
+               THashSet<RoutePoint> branchPoints = new THashSet<>();
+       }
+
        // Caches to avoid creating new objects all the time during rendering
-       protected transient Path2D path;
-       protected transient THashSet<RoutePoint> branchPoints;
+       protected static ThreadLocal<Cache> caches = ThreadLocal.withInitial(() -> new Cache());
 
        public StyledRouteGraphRenderer(ConnectionStyle style) {
                if (style == null)
@@ -52,14 +56,14 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab
 
        @Override
        public void render(Graphics2D g, RouteGraph rg) {
-               if (path == null)
-                       path = new Path2D.Double();
+               Cache cache = caches.get();
+               Path2D path = cache.path;
+               THashSet<RoutePoint> branchPoints = cache.branchPoints;
+
                path.reset();
                rg.getPath2D(path);
                style.drawPath(g, path, false);
 
-               if (branchPoints == null)
-                       branchPoints = new THashSet<RoutePoint>();
                branchPoints.clear();
                for(RouteLine line : rg.getLines()) {
                    renderLine(g, line, false);