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://tudelft.nl/staff/p.knoppers-1">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 String; name for the working thread
30       * @param invokingThread Thread; invoking thread, the worker will stop when this thread is interrupted
31       * @param updater Updater&lt;T&gt;; 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              /** {@inheritDoc} */
38              @SuppressWarnings({"synthetic-access"})
39              @Override
40              public void run()
41              {
42                  while (!invokingThread.isInterrupted())
43                  {
44                      try
45                      {
46                          T t = GraphUpdater.this.queue.poll(5, TimeUnit.SECONDS);
47                          if (t != null)
48                          {
49                              updater.update(t);
50                          }
51                      }
52                      catch (InterruptedException exception)
53                      {
54                          CategoryLogger.always().error(exception, "Worker {} thread stopped.", workerName);
55                          break;
56                      }
57                  }
58              }
59          }, workerName).start();
60      }
61  
62      /**
63       * Offer a next value to the queue.
64       * @param t T; next value to offer to the queue
65       */
66      public final void offer(final T t)
67      {
68          this.queue.offer(t);
69      }
70  
71      /**
72       * Functional interface for updates to perform.
73       * <p>
74       * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
75       * <br>
76       * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
77       * </p>
78       * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
79       * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
80       * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
81       * @param <T> type of value in queue
82       */
83      @FunctionalInterface
84      interface Updater<T>
85      {
86          /**
87           * Perform an update.
88           * @param t T; value to update by
89           */
90          void update(T t);
91      }
92  
93      /** {@inheritDoc} */
94      @Override
95      public String toString()
96      {
97          return "GraphUpdater [queue=" + this.queue + "]";
98      }
99  
100 }