ParameterFactoryOneShot.java
package org.opentrafficsim.core.parameters;
import java.util.Map;
import org.djunits.unit.Unit;
import org.djunits.value.vdouble.scalar.base.DoubleScalarRel;
import org.opentrafficsim.base.parameters.ParameterException;
import org.opentrafficsim.base.parameters.ParameterType;
import org.opentrafficsim.base.parameters.ParameterTypeDouble;
import org.opentrafficsim.base.parameters.ParameterTypeNumeric;
import org.opentrafficsim.base.parameters.Parameters;
import org.opentrafficsim.core.gtu.GtuType;
import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar.Rel;
import nl.tudelft.simulation.jstats.distributions.DistContinuous;
import nl.tudelft.simulation.jstats.distributions.DistDiscrete;
/**
* Extends {@link ParameterFactoryByType} with a one-shot mode. By calling {@link #setOneShotMode()} all parameters and
* correlations added between a call to said method and to {@link #setValues(Parameters, GtuType) setValues()} are removed from
* the factory after the call to {@link #setValues(Parameters, GtuType) setValues()}.
* <p>
* Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
* </p>
* @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
*/
public class ParameterFactoryOneShot extends ParameterFactoryByType
{
/** Whether the parameter factory is in one-shot mode. */
private boolean oneShot = false;
/** Temporary parameters and correlations for the next one-shot. */
// The tempParameters is of the same class such that its getBaseValues() and getCorrelations() methods can be accessed. */
private ParameterFactoryOneShot tempParameters;
/**
* Constructor.
*/
public ParameterFactoryOneShot()
{
this(true);
}
/**
* Constructor.
* @param initTempParameters initiates temporary parameters
*/
private ParameterFactoryOneShot(final boolean initTempParameters)
{
if (initTempParameters)
{
this.tempParameters = new ParameterFactoryOneShot(false);
}
}
/**
* Sets the factory to one-shot mode. All parameters and correlations added between a call to this method and to
* {@link #setValues(Parameters, GtuType) setValues()} are removed from the factory after the call to
* {@link #setValues(Parameters, GtuType) setValues()}.
*/
public void setOneShotMode()
{
this.oneShot = true;
}
/**
* {@inheritDoc} Removes any parameters or correlations that were set in one-shot mode. One-shot mode is disabled.
*/
@Override
public void setValues(final Parameters parameters, final GtuType gtuType) throws ParameterException
{
Map<ParameterType<?>, Object> values = getBaseValues(gtuType);
values.putAll(this.tempParameters.getBaseValues(gtuType));
Map<ParameterType<?>, Map<ParameterType<?>, Correlation<?, ?>>> correls = getCorrelations(gtuType);
correls.putAll(this.tempParameters.getCorrelations(gtuType));
applyCorrelationsAndSetValues(parameters, values, correls);
this.tempParameters = new ParameterFactoryOneShot(false);
this.oneShot = false;
}
/**
* Executes either the fixed or temporary parameter/correlation setting depending on normal or one-shot mode.
* @param fixed execution to set fixed parameter value
* @param temporary execution to set temporary parameter value
*/
private void fixedOrTemporary(final Runnable fixed, final Runnable temporary)
{
(this.oneShot ? temporary : fixed).run();
}
@Override
public <V> void addParameter(final GtuType gtuType, final ParameterType<V> parameterType, final V value)
{
fixedOrTemporary(() -> super.addParameter(gtuType, parameterType, value),
() -> this.tempParameters.addParameter(gtuType, parameterType, value));
}
@Override
public <U extends Unit<U>, V extends DoubleScalarRel<U, V>> void addParameter(final GtuType gtuType,
final ParameterTypeNumeric<V> parameterType, final Rel<V, U> distribution)
{
fixedOrTemporary(() -> super.addParameter(gtuType, parameterType, distribution),
() -> this.tempParameters.addParameter(gtuType, parameterType, distribution));
}
@Override
public void addParameter(final GtuType gtuType, final ParameterType<Integer> parameterType, final DistDiscrete distribution)
{
fixedOrTemporary(() -> super.addParameter(gtuType, parameterType, distribution),
() -> this.tempParameters.addParameter(gtuType, parameterType, distribution));
}
@Override
public void addParameter(final GtuType gtuType, final ParameterType<Double> parameterType,
final DistContinuous distribution)
{
fixedOrTemporary(() -> super.addParameter(gtuType, parameterType, distribution),
() -> this.tempParameters.addParameter(gtuType, parameterType, distribution));
}
@Override
public <V> void addParameter(final ParameterType<V> parameterType, final V value)
{
fixedOrTemporary(() -> super.addParameter(parameterType, value),
() -> this.tempParameters.addParameter(parameterType, value));
}
@Override
public void addParameter(final ParameterTypeDouble parameterType, final double value)
{
fixedOrTemporary(() -> super.addParameter(parameterType, value),
() -> this.tempParameters.addParameter(parameterType, value));
}
@Override
public <U extends Unit<U>, V extends DoubleScalarRel<U, V>> void addParameter(final ParameterTypeNumeric<V> parameterType,
final Rel<V, U> distribution)
{
fixedOrTemporary(() -> super.addParameter(parameterType, distribution),
() -> this.tempParameters.addParameter(parameterType, distribution));
}
@Override
public void addParameter(final ParameterTypeDouble parameterType, final DistContinuous distribution)
{
fixedOrTemporary(() -> super.addParameter(parameterType, distribution),
() -> this.tempParameters.addParameter(parameterType, distribution));
}
@Override
public <C, V> void addCorrelation(final GtuType gtuType, final ParameterType<C> first, final ParameterType<V> then,
final Correlation<C, V> correlation)
{
fixedOrTemporary(() -> super.addCorrelation(gtuType, first, then, correlation),
() -> this.tempParameters.addCorrelation(gtuType, first, then, correlation));
}
@Override
public <C, V> void addCorrelation(final ParameterType<C> first, final ParameterType<V> then,
final Correlation<C, V> correlation)
{
fixedOrTemporary(() -> super.addCorrelation(first, then, correlation),
() -> this.tempParameters.addCorrelation(first, then, correlation));
}
}