Skip to content

Instantly share code, notes, and snippets.

@rozek
Last active January 14, 2020 19:47
Show Gist options
  • Save rozek/158dbc5244c2aea6dc1aa8728e1f16e0 to your computer and use it in GitHub Desktop.
Save rozek/158dbc5244c2aea6dc1aa8728e1f16e0 to your computer and use it in GitHub Desktop.
Bangle.js: watches buttons and invokes methods on state transitions
//------------------------------------------------------------------------------
//-- ButtonWatcher --
//------------------------------------------------------------------------------
(function () {
let _AutoRepeatDelay = 800; // start auto repeat after 800ms
let _AutoRepeatInterval = 200; // send "ButtonPressed" every 200ms
const ButtonList = [BTN1, BTN2, BTN3, BTN4, BTN5];
const TakerList = [[], [], [], [], []];
const TimerIdList = [null, null, null, null, null];
const IntervalIdList = [null, null, null, null, null];
/**** setWatchFor ****/
function setWatchFor (Button, Taker) {
let ButtonId = ButtonList.indexOf(Button);
if (ButtonId < 0) { throw new TypeError('button expected') }
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex < 0) { TakerList[ButtonId].push(Taker) }
return this;
}
/**** clearWatchFor ****/
function clearWatchFor (Button, Taker) {
let ButtonId = ButtonList.indexOf(Button);
if (ButtonId < 0) { throw new TypeError('button expected') }
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex >= 0) { TakerList[ButtonId].splice(TakerIndex,1) }
return this;
}
/**** clearWatchesFor ****/
function clearWatchesFor (Taker) {
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
for (let ButtonId = 0; ButtonId < 5; ButtonId++) {
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex >= 0) { TakerList[ButtonId].splice(TakerIndex,1) }
}
return this;
}
/**** clearWatches ****/
function clearWatches () {
for (let ButtonId = 0; ButtonId < 5; ButtonId++) {
TakerList[ButtonId] = [];
}
return this;
}
/**** handleTimeout ****/
function handleTimeout (ButtonId) {
clearTimeout(TimerIdList[ButtonId]);
TimerIdList[ButtonId] = null;
if (_AutoRepeatInterval != null) {
IntervalIdList[ButtonId] = setInterval(handleInterval,_AutoRepeatInterval,ButtonId);
}
informTakers(ButtonId,'onButtonPress');
}
/**** handleInterval ****/
function handleInterval (ButtonId) {
informTakers(ButtonId,'onButtonPress');
}
/**** informTakers ****/
function informTakers (ButtonId, MethodName) {
let Takers = TakerList[ButtonId];
for (let i = 0, l = Takers.length; i < l; i++) {
let Method = Takers[i][MethodName];
if (typeof Method === 'function') {
try {
Method.call(Takers[i],ButtonId+1);
} catch (Signal) { /* nop */ }
}
}
}
/**** ButtonWatcher object ****/
ButtonWatcher = {
get AutoRepeatDelay () { return _AutoRepeatDelay },
set AutoRepeatDelay (Value) {
switch (true) {
case (Value == null):
_AutoRepeatDelay = undefined;
break;
case (typeof Value === 'number') || (Value instanceof Number):
_AutoRepeatDelay = (Value <= 0 ? undefined : Value);
break;
default:
throw new TypeError('number expected');
}
},
get AutoRepeatInterval () { return _AutoRepeatInterval },
set AutoRepeatInterval (Value) {
switch (true) {
case (Value == null):
_AutoRepeatInterval = undefined;
break;
case (typeof Value === 'number') || (Value instanceof Number):
_AutoRepeatInterval = (Value <= 0 ? undefined : Value);
break;
default:
throw new TypeError('number expected');
}
},
setWatchFor:setWatchFor, clearWatchFor:clearWatchFor,
clearWatchesFor:clearWatchesFor, clearWatches:clearWatches
};
/**** let ButtonWatcher actually watch all buttons ****/
function handleButton (Button, Details) {
let ButtonId = ButtonList.indexOf(Button);
if (Details.state == true) {
if (_AutoRepeatDelay != null) {
TimerIdList[ButtonId] = setTimeout(handleTimeout,_AutoRepeatDelay,ButtonId);
informTakers(ButtonId,'onButtonDown');
}
} else {
if (TimerIdList[ButtonId] != null) {
clearTimeout(TimerIdList[ButtonId]);
TimerIdList[ButtonId] = null;
}
if (IntervalIdList[ButtonId] != null) {
clearInterval(IntervalIdList[ButtonId]);
IntervalIdList[ButtonId] = null;
}
informTakers(ButtonId,'onButtonUp');
}
}
let Options = { edge:'both', debounce:50, repeat:true };
setWatch(handleButton.bind(ButtonWatcher,BTN1), BTN1, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN2), BTN2, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN3), BTN3, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN4), BTN4, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN5), BTN5, Options);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment