AbstractHistoricalList.java

  1. package org.opentrafficsim.core.perception.collections;

  2. import java.util.Collection;
  3. import java.util.Collections;
  4. import java.util.List;
  5. import java.util.ListIterator;

  6. import org.opentrafficsim.core.perception.HistoryManager;

  7. /**
  8.  * List-valued historical state. The current list is always maintained, and past states of the list are obtained by applying the
  9.  * events between now and the requested time in reverse.<br>
  10.  * <br>
  11.  * The {@code Iterator} returned by this class does not support the {@code remove()}, {@code add()} and {@code set()} methods.
  12.  * Any returned sublist is unmodifiable.
  13.  * <p>
  14.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  15.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  16.  * </p>
  17.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  18.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  19.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  20.  * @param <E> element type
  21.  * @param <L> list type
  22.  */
  23. public abstract class AbstractHistoricalList<E, L extends List<E>> extends AbstractHistoricalCollection<E, L>
  24.         implements HistoricalList<E>
  25. {

  26.     /**
  27.      * Constructor.
  28.      * @param historyManager HistoryManager; history manager
  29.      * @param list L; initial list
  30.      */
  31.     protected AbstractHistoricalList(final HistoryManager historyManager, final L list)
  32.     {
  33.         super(historyManager, list);
  34.     }

  35.     // Altering List methods

  36.     /** {@inheritDoc} */
  37.     @Override
  38.     public synchronized void add(final int index, final E value)
  39.     {
  40.         addEvent(new AddEvent<>(now().si, value, index));
  41.         getCollection().add(index, value);
  42.     }

  43.     /** {@inheritDoc} */
  44.     @Override
  45.     public synchronized boolean add(final E value)
  46.     {
  47.         addEvent(new AddEvent<>(now().si, value, getCollection().size()));
  48.         return getCollection().add(value);
  49.     }

  50.     /** {@inheritDoc} */
  51.     @Override
  52.     public synchronized E remove(final int index)
  53.     {
  54.         addEvent(new RemoveEvent<>(now().si, getCollection().get(index), index));
  55.         return getCollection().remove(index);
  56.     }

  57.     /** {@inheritDoc} */
  58.     @Override
  59.     @SuppressWarnings("unchecked")
  60.     public synchronized boolean remove(final Object value)
  61.     {
  62.         int index = getCollection().indexOf(value);
  63.         if (index >= 0)
  64.         {
  65.             addEvent(new RemoveEvent<>(now().si, (E) value, index)); // contains, so safe cast
  66.             getCollection().remove(index);
  67.             return true;
  68.         }
  69.         return false;
  70.     }

  71.     /** {@inheritDoc} */
  72.     @Override
  73.     public synchronized E set(final int index, final E value)
  74.     {
  75.         E previousValue = getCollection().get(index);
  76.         if (!getCollection().get(index).equals(value))
  77.         {
  78.             remove(index);
  79.             add(index, value);
  80.         }
  81.         return previousValue;
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     public boolean addAll(final int index, final Collection<? extends E> c)
  86.     {
  87.         int ind = index;
  88.         for (E e : c)
  89.         {
  90.             add(ind, e);
  91.             ind++;
  92.         }
  93.         return !c.isEmpty();
  94.     }

  95.     // Non-altering List methods

  96.     /** {@inheritDoc} */
  97.     @Override
  98.     public E get(final int index)
  99.     {
  100.         return getCollection().get(index);
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public int indexOf(final Object o)
  105.     {
  106.         return getCollection().indexOf(o);
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     public int lastIndexOf(final Object o)
  111.     {
  112.         return getCollection().lastIndexOf(o);
  113.     }

  114.     /** {@inheritDoc} */
  115.     @Override
  116.     public ListIterator<E> listIterator()
  117.     {
  118.         return listIterator(0);
  119.     }

  120.     /** {@inheritDoc} */
  121.     @Override
  122.     public ListIterator<E> listIterator(final int index)
  123.     {
  124.         return Collections.unmodifiableList(getCollection()).listIterator(index);
  125.     }

  126.     /** {@inheritDoc} */
  127.     @Override
  128.     public List<E> subList(final int fromIndex, final int toIndex)
  129.     {
  130.         return Collections.unmodifiableList(getCollection().subList(fromIndex, toIndex));
  131.     }

  132.     // Events

  133.     /**
  134.      * Abstract super class for events that add or remove a value from the list.
  135.      * <p>
  136.      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  137.      * <br>
  138.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  139.      * </p>
  140.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  141.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  142.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  143.      * @param <E> element type
  144.      * @param <L> list type
  145.      */
  146.     public abstract static class EventList<E, L extends List<E>> extends EventCollection<E, L>
  147.     {

  148.         /** Index of the value. */
  149.         private final int index;

  150.         /**
  151.          * Constructor.
  152.          * @param time double; time of event
  153.          * @param value E; value of event
  154.          * @param index int; index
  155.          */
  156.         public EventList(final double time, final E value, final int index)
  157.         {
  158.             super(time, value);
  159.             this.index = index;
  160.         }

  161.         /**
  162.          * Returns the index.
  163.          * @return index
  164.          */
  165.         final int getIndex()
  166.         {
  167.             return this.index;
  168.         }

  169.     }

  170.     /**
  171.      * Class for events that add a value to the list.
  172.      * <p>
  173.      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  174.      * <br>
  175.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  176.      * </p>
  177.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  178.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  179.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  180.      * @param <E> element type
  181.      * @param <L> list type
  182.      */
  183.     public static class AddEvent<E, L extends List<E>> extends EventList<E, L>
  184.     {

  185.         /**
  186.          * Constructor.
  187.          * @param time double; time of event
  188.          * @param value E; value of event
  189.          * @param index int; index
  190.          */
  191.         public AddEvent(final double time, final E value, final int index)
  192.         {
  193.             super(time, value, index);
  194.         }

  195.         /** {@inheritDoc} */
  196.         @Override
  197.         public void restore(final L list)
  198.         {
  199.             list.remove(getIndex());
  200.         }

  201.         /** {@inheritDoc} */
  202.         @Override
  203.         public String toString()
  204.         {
  205.             return "AddEvent [time=" + getTime() + ", value=" + getValue() + ", index=" + getIndex() + "]";
  206.         }

  207.     }

  208.     /**
  209.      * Class for events that remove a value from the list.
  210.      * <p>
  211.      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  212.      * <br>
  213.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  214.      * </p>
  215.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  216.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  217.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  218.      * @param <E> element type
  219.      * @param <L> list type
  220.      */
  221.     public static class RemoveEvent<E, L extends List<E>> extends EventList<E, L>
  222.     {

  223.         /**
  224.          * Constructor.
  225.          * @param time double; time of event
  226.          * @param value E; value of event
  227.          * @param index int; index the value is at
  228.          */
  229.         public RemoveEvent(final double time, final E value, final int index)
  230.         {
  231.             super(time, value, index);
  232.         }

  233.         /** {@inheritDoc} */
  234.         @Override
  235.         public void restore(final L list)
  236.         {
  237.             list.add(getIndex(), getValue());
  238.         }

  239.         /** {@inheritDoc} */
  240.         @Override
  241.         public String toString()
  242.         {
  243.             return "RemoveEvent [time=" + getTime() + ", value=" + getValue() + ", index=" + getIndex() + "]";
  244.         }

  245.     }

  246. }