AbstractPerception.java

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

  2. import java.util.LinkedHashMap;
  3. import java.util.Map;

  4. import org.opentrafficsim.base.parameters.ParameterException;
  5. import org.opentrafficsim.core.gtu.GTU;
  6. import org.opentrafficsim.core.gtu.GTUException;
  7. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  8. import org.opentrafficsim.core.network.NetworkException;

  9. /**
  10.  * <p>
  11.  * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  12.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
  13.  * <p>
  14.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version Jul 29, 2016 <br>
  15.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  16.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  17.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  18.  * @param <G> GTU type
  19.  */
  20. public abstract class AbstractPerception<G extends GTU> implements Perception<G>
  21. {

  22.     /** */
  23.     private static final long serialVersionUID = 20160729L;

  24.     /** Set of available perception categories. */
  25.     private final Map<Class<? extends PerceptionCategory<?, ?>>, PerceptionCategory<?, ?>> perceptionCategories =
  26.             new LinkedHashMap<>();

  27.     /** Cache, avoiding loop and isAssignableFrom. */
  28.     private final Map<Class<? extends PerceptionCategory<?, ?>>, PerceptionCategory<?, ?>> cachedCategories =
  29.             new LinkedHashMap<>();

  30.     /** GTU. */
  31.     private G gtu;

  32.     /**
  33.      * Construct perception.
  34.      * @param gtu G; GTU
  35.      */
  36.     public AbstractPerception(final G gtu)
  37.     {
  38.         this.gtu = gtu;
  39.     }

  40.     /** {@inheritDoc} */
  41.     @Override
  42.     @SuppressWarnings("checkstyle:designforextension")
  43.     public G getGtu()
  44.     {
  45.         return this.gtu;
  46.     }

  47.     /** {@inheritDoc} */
  48.     @SuppressWarnings("unchecked")
  49.     @Override
  50.     public final <T extends PerceptionCategory<?, ?>> void addPerceptionCategory(final T perceptionCategory)
  51.     {
  52.         // guarantees correct combination of class and perception category
  53.         this.perceptionCategories.put((Class<T>) perceptionCategory.getClass(), perceptionCategory);
  54.         this.cachedCategories.clear();
  55.     }

  56.     /** {@inheritDoc} */
  57.     @Override
  58.     public final <T extends PerceptionCategory<?, ?>> boolean contains(final Class<T> category)
  59.     {
  60.         if (this.cachedCategories.containsKey(category))
  61.         {
  62.             return true;
  63.         }
  64.         for (Class<?> clazz : this.perceptionCategories.keySet())
  65.         {
  66.             if (category.isAssignableFrom(clazz))
  67.             {
  68.                 // isAssignableFrom takes care of implementation of the category
  69.                 this.cachedCategories.put(category, this.perceptionCategories.get(clazz));
  70.                 return true;
  71.             }
  72.         }
  73.         return false;
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public final <T extends PerceptionCategory<?, ?>> T getPerceptionCategory(final Class<T> category)
  78.             throws OperationalPlanException
  79.     {
  80.         T cat = getPerceptionCategoryOrNull(category);
  81.         if (cat != null)
  82.         {
  83.             return cat;
  84.         }
  85.         throw new OperationalPlanException("Perception category" + category + " is not present.");
  86.     }

  87.     /** {@inheritDoc} */
  88.     @Override
  89.     @SuppressWarnings("unchecked")
  90.     public final <T extends PerceptionCategory<?, ?>> T getPerceptionCategoryOrNull(final Class<T> category)
  91.     {
  92.         T implementation = (T) this.cachedCategories.get(category);
  93.         if (implementation != null)
  94.         {
  95.             return implementation;
  96.         }
  97.         for (Class<?> clazz : this.perceptionCategories.keySet())
  98.         {
  99.             if (category.isAssignableFrom(clazz))
  100.             {
  101.                 // addPerceptionCategory guarantees correct combination of class and perception category
  102.                 // isAssignableFrom takes care of implementation of the category
  103.                 implementation = (T) this.perceptionCategories.get(clazz);
  104.                 this.cachedCategories.put(category, implementation);
  105.                 return implementation;
  106.             }
  107.         }
  108.         return null;
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public final void removePerceptionCategory(final PerceptionCategory<?, ?> perceptionCategory)
  113.     {
  114.         for (Class<?> category : this.perceptionCategories.keySet())
  115.         {
  116.             if (perceptionCategory.getClass().isAssignableFrom(category))
  117.             {
  118.                 // addPerceptionCategory guarantees correct combination of class and perception category
  119.                 // isAssignableFrom takes care of implementation of the category
  120.                 this.perceptionCategories.remove(perceptionCategory.getClass());
  121.                 this.cachedCategories.clear();
  122.                 return;
  123.             }
  124.         }
  125.     }

  126.     /** {@inheritDoc} */
  127.     @Override
  128.     @SuppressWarnings("checkstyle:designforextension")
  129.     public void perceive() throws GTUException, NetworkException, ParameterException
  130.     {
  131.         for (PerceptionCategory<?, ?> category : this.perceptionCategories.values())
  132.         {
  133.             category.updateAll();
  134.         }
  135.     }

  136.     /** {@inheritDoc} */
  137.     @Override
  138.     @SuppressWarnings("checkstyle:designforextension")
  139.     public String toString()
  140.     {
  141.         StringBuilder s = new StringBuilder("Perception [");
  142.         String sep = "";
  143.         for (PerceptionCategory<?, ?> cat : this.perceptionCategories.values())
  144.         {
  145.             s.append(sep);
  146.             s.append(cat);
  147.             sep = ", ";
  148.         }
  149.         s.append("]");
  150.         return s.toString();
  151.     }

  152. }