I have this code block:
EventBus.on('pfio.inputs.changed', function(state, prev_state) {
var changed = prev_state ^ state;
for (var pin = 0; pin < 8; pin++) {
if ((changed & (1 << pin)) === (1 << pin)) {
EventBus.emit('pfio.input.changed', pin, ((state & (1 << pin)) === (1 << pin)));
}
}
});
state will be an 8 bit number: 00000000
prev_state will be an 8 bit number: 11001110
These numbers relate to switch states, so the first in state means pin 1 is off. In prev_state the first 1 means the switch 8 is on.
I understand the simple code execution, its these bits I can't get my head round:
(changed & (1 << pin)) === (1 << pin))
((state & (1 << pin)) === (1 << pin)));
prev_state ^ state;
Any explanation on this matter would help immensely!
^
is the XOR
operator - given two numbers it "lines up" their places and flips the place only if only one of the two numbers has that place:
// All of these are binary
111 ^ 111 === 000
110 ^ 111 === 001
110 ^ 110 === 000
This means that changed
will be a number with only those places set that are set in prev_state
or state
but not both.
As for <<
that is the left-shift operator - it is effectively raising the left-hand side number by the power of two that is the right hand side number:
// Decimal numbers on the left, binary numbers on the right
1 << 1 === 10 // 2
1 << 2 === 100 // 4
1 << 3 === 1000 // 8
// You can use any number on the LHS
2 << 1 === 100 // 4
3 << 2 === 1100 // 12
// Remember, 3 in decimal is equal to 11 in binary
Lastly, &
is the binary and operator - it returns a number where the place is only set if both numbers have 1
in that place:
// Both sides binary
1 & 1 === 1
11 & 10 === 10
010 & 100 === 0
So, in your loop, the first 8 bits of changed are being checked to see if any of them are set - if any of them are set, something changed and an event is fired. It may be easier to see if we break it down for two steps:
// All numbers in binary save for 8 ;-)
prev_state = 11111111;
state = 11011111;
changed = 00100000;
Iteration #1:
mask = 1 << 0 // 0
changeAtPower = changed & mask // 0
// 0 0 0
mask === changedAtPower // false
Iteration #2:
mask = 1 << 1 // 10
changeAtPower = changed & mask // 0
// 00 00 01
mask === changedAtPower // false
Skipping iterations #3 through #5, which all look the same, let's look at #6:
mask = 1 << 5 // 100000
changedAtPower = changed & mask // 100000
// 100000 100000 100000
mask === changedAtPower // true
// Event triggered
And then it continues on for the remaining iterations (#7 and #8) and since nothing has changed, fires no more events.
prev_state ^ state
makes a mask of bits that is 1 wherever a bit in the prev_state
disagrees with the corresponding bit in state
, see xor.
(changed & (1 << pin)) === (1 << pin))
tests whether the bit with index pin
is set, which would mean that that pin at position has changed.
((state & (1 << pin)) === (1 << pin)))
also tests whether the bit with index pin
is set, which in this case means that the pin at that position is now 1/set/true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With