View Javadoc
1   package org.opentrafficsim.core.perception.collections;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.List;
6   import java.util.ListIterator;
7   
8   import org.opentrafficsim.core.perception.HistoryManager;
9   
10  /**
11   * List-valued historical state. The current list is always maintained, and past states of the list are obtained by applying the
12   * events between now and the requested time in reverse.<br>
13   * <br>
14   * The {@code Iterator} returned by this class does not support the {@code remove()}, {@code add()} and {@code set()} methods.
15   * Any returned sublist is unmodifiable.
16   * <p>
17   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
18   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
19   * <p>
20   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 2 jan. 2018 <br>
21   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
23   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
24   * @param <E> element type
25   * @param <L> list type
26   */
27  public abstract class AbstractHistoricalList<E, L extends List<E>> extends AbstractHistoricalCollection<E, L>
28          implements HistoricalList<E>
29  {
30  
31      /**
32       * Constructor.
33       * @param historyManager HistoryManager; history manager
34       * @param list L; initial list
35       */
36      protected AbstractHistoricalList(final HistoryManager historyManager, final L list)
37      {
38          super(historyManager, list);
39      }
40  
41      // Altering List methods
42  
43      /** {@inheritDoc} */
44      @Override
45      public synchronized void add(final int index, final E value)
46      {
47          addEvent(new AddEvent<>(now().si, value, index));
48          getCollection().add(index, value);
49      }
50  
51      /** {@inheritDoc} */
52      @Override
53      public synchronized boolean add(final E value)
54      {
55          addEvent(new AddEvent<>(now().si, value, getCollection().size()));
56          return getCollection().add(value);
57      }
58  
59      /** {@inheritDoc} */
60      @Override
61      public synchronized E remove(final int index)
62      {
63          addEvent(new RemoveEvent<>(now().si, getCollection().get(index), index));
64          return getCollection().remove(index);
65      }
66  
67      /** {@inheritDoc} */
68      @Override
69      @SuppressWarnings("unchecked")
70      public synchronized boolean remove(final Object value)
71      {
72          int index = getCollection().indexOf(value);
73          if (index >= 0)
74          {
75              addEvent(new RemoveEvent<>(now().si, (E) value, index)); // contains, so safe cast
76              getCollection().remove(index);
77              return true;
78          }
79          return false;
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public synchronized E set(final int index, final E value)
85      {
86          E previousValue = getCollection().get(index);
87          if (!getCollection().get(index).equals(value))
88          {
89              remove(index);
90              add(index, value);
91          }
92          return previousValue;
93      }
94  
95      /** {@inheritDoc} */
96      @Override
97      public boolean addAll(final int index, final Collection<? extends E> c)
98      {
99          int ind = index;
100         for (E e : c)
101         {
102             add(ind, e);
103             ind++;
104         }
105         return !c.isEmpty();
106     }
107 
108     // Non-altering List methods
109 
110     /** {@inheritDoc} */
111     @Override
112     public E get(final int index)
113     {
114         return getCollection().get(index);
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public int indexOf(final Object o)
120     {
121         return getCollection().indexOf(o);
122     }
123 
124     /** {@inheritDoc} */
125     @Override
126     public int lastIndexOf(final Object o)
127     {
128         return getCollection().lastIndexOf(o);
129     }
130 
131     /** {@inheritDoc} */
132     @Override
133     public ListIterator<E> listIterator()
134     {
135         return listIterator(0);
136     }
137 
138     /** {@inheritDoc} */
139     @Override
140     public ListIterator<E> listIterator(final int index)
141     {
142         return Collections.unmodifiableList(getCollection()).listIterator(index);
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     public List<E> subList(final int fromIndex, final int toIndex)
148     {
149         return Collections.unmodifiableList(getCollection().subList(fromIndex, toIndex));
150     }
151 
152     // Events
153 
154     /**
155      * Abstract super class for events that add or remove a value from the list.
156      * <p>
157      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
158      * <br>
159      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
160      * <p>
161      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
162      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
163      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
164      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
165      * @param <E> element type
166      * @param <L> list type
167      */
168     public abstract static class EventList<E, L extends List<E>> extends EventCollection<E, L>
169     {
170 
171         /** Index of the value. */
172         private final int index;
173 
174         /**
175          * Constructor.
176          * @param time double; time of event
177          * @param value E; value of event
178          * @param index int; index
179          */
180         public EventList(final double time, final E value, final int index)
181         {
182             super(time, value);
183             this.index = index;
184         }
185 
186         /**
187          * Returns the index.
188          * @return index
189          */
190         final int getIndex()
191         {
192             return this.index;
193         }
194 
195     }
196 
197     /**
198      * Class for events that add a value to the list.
199      * <p>
200      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
201      * <br>
202      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
203      * <p>
204      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
205      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
206      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
207      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
208      * @param <E> element type
209      * @param <L> list type
210      */
211     public static class AddEvent<E, L extends List<E>> extends EventList<E, L>
212     {
213 
214         /**
215          * Constructor.
216          * @param time double; time of event
217          * @param value E; value of event
218          * @param index int; index
219          */
220         public AddEvent(final double time, final E value, final int index)
221         {
222             super(time, value, index);
223         }
224 
225         /** {@inheritDoc} */
226         @Override
227         public void restore(final L list)
228         {
229             list.remove(getIndex());
230         }
231 
232         /** {@inheritDoc} */
233         @Override
234         public String toString()
235         {
236             return "AddEvent [time=" + getTime() + ", value=" + getValue() + ", index=" + getIndex() + "]";
237         }
238 
239     }
240 
241     /**
242      * Class for events that remove a value from the list.
243      * <p>
244      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
245      * <br>
246      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
247      * <p>
248      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
249      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
250      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
251      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
252      * @param <E> element type
253      * @param <L> list type
254      */
255     public static class RemoveEvent<E, L extends List<E>> extends EventList<E, L>
256     {
257 
258         /**
259          * Constructor.
260          * @param time double; time of event
261          * @param value E; value of event
262          * @param index int; index the value is at
263          */
264         public RemoveEvent(final double time, final E value, final int index)
265         {
266             super(time, value, index);
267         }
268 
269         /** {@inheritDoc} */
270         @Override
271         public void restore(final L list)
272         {
273             list.add(getIndex(), getValue());
274         }
275 
276         /** {@inheritDoc} */
277         @Override
278         public String toString()
279         {
280             return "RemoveEvent [time=" + getTime() + ", value=" + getValue() + ", index=" + getIndex() + "]";
281         }
282 
283     }
284 
285 }