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      /** {@inheritDoc} */
55      @Override
56      public EventListenerMap getEventListenerMap() throws RemoteException
57      {
58          return this.eventProducer.getEventListenerMap();
59      }
60  
61      /** {@inheritDoc} */
62      @Override
63      public void initialize()
64      {
65          super.initialize();
66          if (this.eventProducer != null)
67          {
68              try
69              {
70                  this.eventProducer.fireEvent(StatisticsEvents.INITIALIZED_EVENT);
71              }
72              catch (RemoteException exception)
73              {
74                  throw new RuntimeException(exception);
75              }
76          }
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public void notify(final Event event)
82      {
83          long value = 1;
84          if (event.getContent() instanceof Number)
85          {
86              value = Math.round(((Number) event.getContent()).doubleValue());
87          }
88          else
89          {
90              throw new IllegalArgumentException("event content for counter not a number but of type " + event.getClass());
91          }
92          register(value);
93      }
94  
95      /** {@inheritDoc} */
96      @Override
97      public long register(final long value)
98      {
99          super.register(value);
100         try
101         {
102             if (hasListeners())
103             {
104                 this.eventProducer.fireEvent(StatisticsEvents.OBSERVATION_ADDED_EVENT, value);
105                 fireEvents();
106             }
107         }
108         catch (RemoteException exception)
109         {
110             throw new RuntimeException(exception);
111         }
112         return value;
113     }
114 
115     /**
116      * Method that can be overridden to fire own events or additional events when registering an observation.
117      * @throws RemoteException on network error
118      */
119     protected void fireEvents() throws RemoteException
120     {
121         this.eventProducer.fireEvent(StatisticsEvents.N_EVENT, getN());
122         this.eventProducer.fireEvent(StatisticsEvents.COUNT_EVENT, getCount());
123     }
124 
125 }