Class PlotDelegate<S extends org.opentrafficsim.animation.graphs.AbstractPlot.PaintState,P extends AbstractPlot<S>>

java.lang.Object
org.djutils.event.LocalEventProducer
org.opentrafficsim.animation.graphs.PlotDelegate<S,P>
Type Parameters:
S - paint state for the plot(s)
P - plot type
All Implemented Interfaces:
EventProducer
Direct Known Subclasses:
ContourDataSource, FdDataSource

public abstract class PlotDelegate<S extends org.opentrafficsim.animation.graphs.AbstractPlot.PaintState,P extends AbstractPlot<S>> extends LocalEventProducer
Plot delegate. This class functions as a template for a data source that is shared among different plots. To keep logic local the delegate is intended as an internal state of a plot. Any changes to settings should occur through the plots, and not directly on the delegate. Typical usage is: Notes on synchronization:
  • Implementations need to synchronize parts that read and write settings, as different threads may access them.
  • Synchronization should be otherwise minimized to prevent a slow UI or delayed calculations. For example when setting the smooth setting:
     public void setSmooth(final boolean smooth)
     {
         synchronized (this)
         {
             this.smooth = smooth;
             invalidateTimeSpan();
         }
         fireEvent(SMOOTH, smooth);
     }
     
  • Calculation of the paint state should not be class-level synchronized; that would make the UI have to wait on calculations. Method calculatePaintStateSafe(org.djunits.value.vdouble.scalar.Duration) makes sure a separate lock prevents parallel calculations.
  • Calculations are based on settings. These settings need to be gathered at class-level synchronization, which then needs to be released for the actual calculations. This should occur in calculatePaintStateUnsafe(org.djunits.value.vdouble.scalar.Duration). For example:
     public void calculatePaintStateUnsafe(final Duration time)
     {
         boolean smooth0;
         synchronized (this) // obtain settings safely
         {
             smooth0 = this.smooth;
         }
    
         // do calculations ...
    
         for (FundamentalDiagram plot : getPlots())
         {
             plot.offerPaintState(paintState);
         }
     }
     

Copyright (c) 2026-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
BSD-style license. See OpenTrafficSim License.

Author:
Wouter Schakel
  • Constructor Details

    • PlotDelegate

      public PlotDelegate(org.djunits.value.vdouble.scalar.Duration initialUpdateInterval, org.djunits.value.vdouble.scalar.Duration delay, PlotScheduler plotScheduler)
      Constructor.
      Parameters:
      initialUpdateInterval - initial update interval
      delay - delay so critical future events have occurred, e.g. GTU's next move's to extend trajectories
      plotScheduler - plot scheduler
  • Method Details

    • getInitialUpdateInterval

      public org.djunits.value.vdouble.scalar.Duration getInitialUpdateInterval()
      Returns the update interval for a plot using this delegate.
      Returns:
      update interval
    • getDelay

      public org.djunits.value.vdouble.scalar.Duration getDelay()
      Returns the delay for a plot using this delegate.
      Returns:
      delay
    • getPlotScheduler

      public PlotScheduler getPlotScheduler()
      Returns the plot scheduler for the first plot that requests one. This plot will be in charge of the updates. All other plots will receive a plot scheduler that will ignore the scheduling of update events.
      Returns:
      plot scheduler
    • addPlot

      public void addPlot(P plot)
      Add plot. Used to notify plots when data has changed.
      Parameters:
      plot - plot
    • clearPlots

      public void clearPlots()
      Clears all connected plots.
    • getPlots

      public ImmutableSet<P> getPlots()
      Returns the plots.
      Returns:
      plots
    • invalidateTimeSpan

      public void invalidateTimeSpan()
      Invalidates the whole time span.
    • isInvalidTimeSpan

      public boolean isInvalidTimeSpan()
      Returns whether the time span is invalid. This can indicate that calculations can be stopped as some setting was changed that invalidated the time span.
      Returns:
      whether the time span is invalid
    • getAndResetInvalidTimeSpan

      public boolean getAndResetInvalidTimeSpan()
      Returns whether the whole time span is invalid, and resets this information.
      Returns:
      whether the whole time span is invalid
    • calculatePaintStateSafe

      public void calculatePaintStateSafe(org.djunits.value.vdouble.scalar.Duration time)
      Invokes calculatePaintStateUnsafe(org.djunits.value.vdouble.scalar.Duration) in a thread-safe manner. This method should be invoked by plots that use a delegate when the plot is asked to calculate the paint state.
      Parameters:
      time - current time
    • calculatePaintStateUnsafe

      protected abstract void calculatePaintStateUnsafe(org.djunits.value.vdouble.scalar.Duration time)
      Calculates paint state and offers it to the coupled plots. This method should only be invoked by calculatePaintStateSafe(org.djunits.value.vdouble.scalar.Duration) which makes sure that setting changes from different plots (with different working threads) do not cause parallel calculations on the same delegate. This makes sure that internal data gathering can occur consistently.
      Parameters:
      time - current time