View Javadoc
1   /*
2    * Copyright © 2016 Greg Chabala
3    *
4    * This file is part of brick-control-lab.
5    *
6    * brick-control-lab is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   *
11   * brick-control-lab is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public License
17   * along with brick-control-lab.  If not, see http://www.gnu.org/licenses/.
18   */
19  package org.chabala.brick.controllab.sensor;
20  
21  import org.chabala.brick.controllab.InputId;
22  
23  import java.util.EventObject;
24  import java.util.function.Function;
25  
26  import static org.chabala.brick.controllab.sensor.BinaryStringFormatter.printInBinary;
27  
28  /**
29   * The event triggered by receiving a {@link SensorValue} from an {@link InputId}.
30   * @param <T> specific {@link SensorValue} subclass contained in this event
31   */
32  public class SensorEvent<T extends SensorValue> extends EventObject {
33  
34      private final byte[] oldValue;
35      private final byte[] newValue;
36      private final T value;
37  
38      /**
39       * Constructs a SensorEvent.
40       *
41       * @param input    The input port that triggered this event.
42       * @param oldValue The last known value from this input, as a two byte array.
43       * @param newValue The new value from this input, as a two byte array.
44       * @param value    The new value wrapped in the SensorValue class.
45       */
46      public SensorEvent(InputId input, byte[] oldValue, byte[] newValue, T value) {
47          super(input);
48          this.oldValue = oldValue;
49          this.newValue = newValue;
50          this.value = value;
51      }
52  
53      /**
54       * A copy constructor for subclasses, to easily wrap the {@link SensorValue} in a
55       * more specific subclass.
56       * @param sensorEvent   The SensorEvent to be copied
57       * @param sensorWrapper The constructor method reference for a SensorValue subclass
58       */
59      public SensorEvent(SensorEvent<SensorValue> sensorEvent, Function<SensorValue, T> sensorWrapper) {
60          this(sensorEvent.getInput(),
61               sensorEvent.getOldValue(),
62               sensorEvent.getNewValue(),
63               sensorWrapper.apply(sensorEvent.getValue()));
64      }
65  
66      /**
67       * The input port that triggered this event.
68       * @return the input port that triggered this event.
69       */
70      public InputId getInput() {
71          return (InputId) getSource();
72      }
73  
74      /**
75       * The last known value from this input, prior to the event, as a two byte array.
76       * @return the last known value from this input as a two byte array
77       */
78      public byte[] getOldValue() {
79          return oldValue;
80      }
81  
82      /**
83       * The new value from this input, as a two byte array.
84       * @return the new value from this input as a two byte array
85       */
86      public byte[] getNewValue() {
87          return newValue;
88      }
89  
90      /**
91       * The new value from this input wrapped in the SensorValue class, or sensor specific subclass.
92       * @return SensorValue class, or sensor specific subclass
93       */
94      public T getValue() {
95          return value;
96      }
97  
98      @Override
99      public String toString() {
100         return String.format("%1s value changed: %2s -> %3s aka %4s",
101                 source, printInBinary(oldValue), printInBinary(newValue), value);
102     }
103 }