21
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
* THE SOFTWARE.
23
23
*/
24
-
25
24
package org .firmata4j .firmata ;
26
25
27
26
import java .io .IOException ;
28
- import java .util .*;
27
+ import java .util .Map ;
28
+ import java .util .Set ;
29
+ import java .util .concurrent .ConcurrentHashMap ;
30
+ import java .util .concurrent .ConcurrentSkipListSet ;
29
31
import java .util .concurrent .atomic .AtomicBoolean ;
30
-
31
32
import org .firmata4j .I2CDevice ;
32
33
import org .firmata4j .I2CEvent ;
33
34
import org .firmata4j .I2CListener ;
39
40
* @author Oleg Kurbatov <[email protected] >
40
41
*/
41
42
public class FirmataI2CDevice implements I2CDevice {
42
- public static final int REGISTER_NOT_SET = -1 ;
43
+
44
+ public static final int REGISTER_NOT_SET = -1 ;
43
45
44
46
private final FirmataDevice masterDevice ;
45
47
46
48
private final byte address ;
47
49
48
50
private final AtomicBoolean receivingUpdates = new AtomicBoolean (false );
49
51
50
- private final Map <Integer , I2CListener > callbacks = new HashMap <>();
52
+ private final Map <Integer , I2CListener > callbacks = new ConcurrentHashMap <>();
51
53
52
- private final Set <I2CListener > subscribers = Collections . synchronizedSet ( new HashSet < I2CListener >() );
54
+ private final Set <I2CListener > subscribers = new ConcurrentSkipListSet <>( );
53
55
54
56
FirmataI2CDevice (FirmataDevice masterDevice , byte address ) {
55
57
this .masterDevice = masterDevice ;
@@ -73,12 +75,12 @@ public void tell(byte... data) throws IOException {
73
75
74
76
@ Override
75
77
public void ask (byte responseLength , I2CListener listener ) throws IOException {
76
- ask (- 1 , responseLength , listener );
78
+ ask (REGISTER_NOT_SET , responseLength , listener );
77
79
}
78
-
80
+
79
81
@ Override
80
- public void ask (int register , byte responseLength , I2CListener listener ) throws IOException {
81
- callbacks .put (Integer . valueOf ( register ) , listener );
82
+ public void ask (int register , byte responseLength , I2CListener listener ) throws IOException {
83
+ callbacks .put (register , listener );
82
84
masterDevice .sendMessage (FirmataMessageFactory .i2cReadRequest (address , register , responseLength , false ));
83
85
}
84
86
@@ -106,29 +108,28 @@ public void stopReceivingUpdates() throws IOException {
106
108
}
107
109
}
108
110
109
- /**
110
- * {@link FirmataDevice} calls this method when receives a message from I2C
111
- * device.
112
- *
113
- * @param register The device register read from.
114
- * @param message actual data from I2C device
115
- */
111
+ /**
112
+ * {@link FirmataDevice} calls this method when receives a message from I2C
113
+ * device.
114
+ *
115
+ * @param register The device register read from.
116
+ * @param message actual data from I2C device
117
+ */
116
118
void onReceive (int register , byte [] message ) {
117
119
I2CEvent evt = new I2CEvent (this , register , message );
118
- I2CListener cb_listener = callbacks .get (Integer .valueOf (register ));
119
- if (cb_listener != null ) {
120
- cb_listener .onReceive (evt );
121
- } else {
122
- Set <I2CListener > notificationSet = new HashSet <>(subscribers );
123
- for (I2CListener listener : notificationSet ) {
124
- listener .onReceive (evt );
120
+ I2CListener listener = callbacks .remove (register );
121
+ if (listener == null ) {
122
+ for (I2CListener subscriber : subscribers ) {
123
+ subscriber .onReceive (evt );
125
124
}
125
+ } else {
126
+ listener .onReceive (evt );
126
127
}
127
128
}
128
129
129
- @ Override
130
- public String toString () {
131
- return "FirmataI2CDevice [address=0x" + Integer . toHexString ( address ) + "]" ;
132
- }
130
+ @ Override
131
+ public String toString () {
132
+ return String . format ( "FirmataI2CDevice [address=0x%02X]" , address );
133
+ }
133
134
134
135
}
0 commit comments