View Javadoc
1   package org.opentrafficsim.draw.graphs;
2   
3   import java.util.concurrent.BlockingQueue;
4   import java.util.concurrent.LinkedBlockingQueue;
5   import java.util.concurrent.TimeUnit;
6   
7   import org.djutils.logger.CategoryLogger;
8   
9   /**
10   * The GraphUpdater can be used to repeatedly offer a value that is automatically processed in order of offering in a parallel
11   * Thread.
12   * <p>
13   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
15   * </p>
16   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
18   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
19   * @param <T> type of value in queue
20   */
21  public class GraphUpdater<T>
22  {
23  
24      /** Queue of update times for executing Thread. */
25      private final BlockingQueue<T> queue = new LinkedBlockingQueue<>();
26  
27      /**
28       * Constructs and starts a thread that performs each given task from a queue.
29       * @param workerName name for the working thread
30       * @param invokingThread invoking thread, the worker will stop when this thread is interrupted
31       * @param updater updater to perform with the queued value
32       */
33      public GraphUpdater(final String workerName, final Thread invokingThread, final Updater<T> updater)
34      {
35          new Thread(new Runnable()
36          {
37              @SuppressWarnings({"synthetic-access"})
38              @Override
39              public void run()
40              {
41                  while (!invokingThread.isInterrupted())
42                  {
43                      try
44                      {
45                          T t = GraphUpdater.this.queue.poll(5, TimeUnit.SECONDS);
46                          if (t != null)
47                          {
48                              updater.update(t);
49                          }
50                      }
51                      catch (InterruptedException exception)
52                      {
53                          CategoryLogger.always().error(exception, "Worker {} thread stopped.", workerName);
54                          break;
55                      }
56                  }
57              }
58          }, workerName).start();
59      }
60  
61      /**
62       * Offer a next value to the queue.
63       * @param t next value to offer to the queue
64       */
65      public final void offer(final T t)
66      {
67          this.queue.offer(t);
68      }
69  
70      /**
71       * Functional interface for updates to perform.
72       * <p>
73       * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
74       * <br>
75       * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
76       * </p>
77       * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
78       * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
79       * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
80       * @param <T> type of value in queue
81       */
82      @FunctionalInterface
83      interface Updater<T>
84      {
85          /**
86           * Perform an update.
87           * @param t value to update by
88           */
89          void update(T t);
90      }
91  
92      @Override
93      public String toString()
94      {
95          return "GraphUpdater [queue=" + this.queue + "]";
96      }
97  
98  }