View Javadoc
1   package org.djutils.stats.summarizers.event;
2   
3   import java.rmi.RemoteException;
4   
5   import org.djutils.event.Event;
6   import org.djutils.event.EventListener;
7   import org.djutils.event.EventListenerMap;
8   import org.djutils.event.EventProducer;
9   import org.djutils.event.LocalEventProducer;
10  import org.djutils.exceptions.Throw;
11  import org.djutils.stats.summarizers.Counter;
12  
13  /**
14   * The Counter class defines a statistics event counter. It embeds an EventProducer so it can keep listeners informed about new
15   * observations, and it listens to external events to be able to receive observations, in addition to the register(...) method.
16   * <p>
17   * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
18   * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
19   * project is distributed under a three-clause BSD-style license, which can be found at
20   * <a href="https://simulation.tudelft.nl/dsol/3.0/license.html" target="_blank">
21   * https://simulation.tudelft.nl/dsol/3.0/license.html</a>. <br>
22   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank"> Alexander Verbraeck</a>
23   * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
24   */
25  public class EventBasedCounter extends Counter implements EventProducer, EventListener
26  {
27      /** */
28      private static final long serialVersionUID = 20200228L;
29  
30      /** The embedded EventProducer. */
31      private EventProducer eventProducer = null;
32  
33      /**
34       * Construct a new EventBasedCounter.
35       * @param description String; the description for this counter
36       */
37      public EventBasedCounter(final String description)
38      {
39          this(description, new LocalEventProducer());
40      }
41  
42      /**
43       * Construct a new EventBasedCounter with a specific EventProducer, e.g. a remote one.
44       * @param description String; the description for this counter
45       * @param eventProducer EventProducer; the EventProducer to embed and use in this statistic
46       */
47      public EventBasedCounter(final String description, final EventProducer eventProducer)
48      {
49          super(description);
50          Throw.whenNull(eventProducer, "eventProducer cannot be null");
51          this.eventProducer = eventProducer;
52      }
53  
54      @Override
55      public EventListenerMap getEventListenerMap() throws RemoteException
56      {
57          return this.eventProducer.getEventListenerMap();
58      }
59  
60      @Override
61      public void initialize()
62      {
63          super.initialize();
64          if (this.eventProducer != null)
65          {
66              try
67              {
68                  this.eventProducer.fireEvent(StatisticsEvents.INITIALIZED_EVENT);
69              }
70              catch (RemoteException exception)
71              {
72                  throw new RuntimeException(exception);
73              }
74          }
75      }
76  
77      @Override
78      public void notify(final Event event)
79      {
80          long value = 1;
81          if (event.getContent() instanceof Number)
82          {
83              value = Math.round(((Number) event.getContent()).doubleValue());
84          }
85          else
86          {
87              throw new IllegalArgumentException("event content for counter not a number but of type " + event.getClass());
88          }
89          register(value);
90      }
91  
92      @Override
93      public long register(final long value)
94      {
95          super.register(value);
96          try
97          {
98              if (hasListeners())
99              {
100                 this.eventProducer.fireEvent(StatisticsEvents.OBSERVATION_ADDED_EVENT, value);
101                 fireEvents();
102             }
103         }
104         catch (RemoteException exception)
105         {
106             throw new RuntimeException(exception);
107         }
108         return value;
109     }
110 
111     /**
112      * Method that can be overridden to fire own events or additional events when registering an observation.
113      * @throws RemoteException on network error
114      */
115     protected void fireEvents() throws RemoteException
116     {
117         this.eventProducer.fireEvent(StatisticsEvents.N_EVENT, getN());
118         this.eventProducer.fireEvent(StatisticsEvents.COUNT_EVENT, getCount());
119     }
120 
121 }