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:
- Each plot receives the
PlotDelegatein its constructor and requests from it an initial update interval, delay, andPlotScheduler. - UI events should not directly call the delegate, but only plot objects. When a setting is changed through UI, the plot should be invoked, and the plot should call a method on the delegate to set the relevant setting.
- When a setting is changed on the delegate that invalidates the whole time span,
invalidateTimeSpan()should be invoked by the method of the delegate that changes the setting. - The delegate method should also fire an event defined to indicate the setting change to all UI components that reflect its value.
- UI elements should listen for the event by calling a method on the plot that adds the listener to the delegate through
EventProducer.addListener(org.djutils.event.EventListener, org.djutils.event.EventType, int, org.djutils.event.reference.ReferenceType). - When
AbstractPlot.calculatePaintState(org.djunits.value.vdouble.scalar.Duration)is called on a plot that uses a delegate, it can simply callcalculatePaintStateSafe(org.djunits.value.vdouble.scalar.Duration)on the delegate. - If a setting is changed for which the update interval should change, the delegate should invoke
AbstractPlot.offerUpdateInterval(org.djunits.value.vdouble.scalar.Duration)on all plots usinggetPlots(). - To know whether all of the time span needs to be calculated the calculation method can use
getAndResetInvalidTimeSpan(). - To know whether (expensive) calculations can be abandoned as a setting was changed that invalidated the whole time span,
the calculation method can use
isInvalidTimeSpan(). - The delegate should calculate all state(s) and offer them to the relevant plots using
getPlots()andAbstractPlot.offerPaintState(S).
- 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
smoothsetting: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
-
Field Summary
Fields inherited from interface org.djutils.event.EventProducer
FIRST_POSITION, LAST_POSITION -
Constructor Summary
ConstructorsConstructorDescriptionPlotDelegate(org.djunits.value.vdouble.scalar.Duration initialUpdateInterval, org.djunits.value.vdouble.scalar.Duration delay, PlotScheduler plotScheduler) Constructor. -
Method Summary
Modifier and TypeMethodDescriptionvoidAdd plot.voidcalculatePaintStateSafe(org.djunits.value.vdouble.scalar.Duration time) InvokescalculatePaintStateUnsafe(org.djunits.value.vdouble.scalar.Duration)in a thread-safe manner.protected abstract voidcalculatePaintStateUnsafe(org.djunits.value.vdouble.scalar.Duration time) Calculates paint state and offers it to the coupled plots.voidClears all connected plots.booleanReturns whether the whole time span is invalid, and resets this information.org.djunits.value.vdouble.scalar.DurationgetDelay()Returns the delay for a plot using this delegate.org.djunits.value.vdouble.scalar.DurationReturns the update interval for a plot using this delegate.getPlots()Returns the plots.Returns the plot scheduler for the first plot that requests one.voidInvalidates the whole time span.booleanReturns whether the time span is invalid.Methods inherited from class org.djutils.event.LocalEventProducer
getEventListenerMapMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.djutils.event.EventProducer
addListener, addListener, addListener, addListener, fireEvent, fireEvent, fireEvent, fireTimedEvent, fireTimedEvent, fireTimedEvent, fireUnverifiedEvent, fireUnverifiedEvent, fireUnverifiedTimedEvent, fireUnverifiedTimedEvent, getEventTypesWithListeners, getListenerReferences, hasListeners, numberOfListeners, removeAllListeners, removeAllListeners, removeListener
-
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 intervaldelay- delay so critical future events have occurred, e.g. GTU's next move's to extend trajectoriesplotScheduler- 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
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
Add plot. Used to notify plots when data has changed.- Parameters:
plot- plot
-
clearPlots
public void clearPlots()Clears all connected plots. -
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) InvokescalculatePaintStateUnsafe(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 bycalculatePaintStateSafe(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
-