fixed starting and stopping of animations
This commit is contained in:
parent
9ceb501265
commit
b6c2e04db2
2 changed files with 51 additions and 42 deletions
|
@ -1,8 +1,6 @@
|
|||
const logger = require('./logger');
|
||||
const blinkstick = require('blinkstick');
|
||||
|
||||
const LED_ANIMATED = 0;
|
||||
|
||||
const LEDS_ALL = 'all';
|
||||
|
||||
const MODE_SET = 'set';
|
||||
|
@ -11,9 +9,9 @@ const MODE_BLINK = 'blink';
|
|||
const MODE_PULSE = 'pulse';
|
||||
const MODE_POWEROFF = 'poweroff';
|
||||
|
||||
const LEDS = new Map();
|
||||
const LEDS_ANIMATED = [];
|
||||
const LEDS_STOP = [];
|
||||
|
||||
let stop = false;
|
||||
|
||||
// find connected blinkstick(s)
|
||||
async function findBlinkstick(index) {
|
||||
|
@ -31,12 +29,12 @@ async function findBlinkstick(index) {
|
|||
|
||||
// simple animation (set the color / morph to color)
|
||||
async function simple(config) {
|
||||
await forceStop();
|
||||
await stopLedsAccordingly(config);
|
||||
config.timestamp = new Date().getTime();
|
||||
let indices = getIndices(config);
|
||||
for (let index = 0; index < indices.length; index++) {
|
||||
try {
|
||||
await setLedState(indices[index], LED_ANIMATED);
|
||||
await setLedAnimated(indices[index]);
|
||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||
} finally {
|
||||
await clearLedState(indices[index]);
|
||||
|
@ -53,7 +51,7 @@ async function simple(config) {
|
|||
// complex animation (pulse / blink)
|
||||
async function complex(config) {
|
||||
if (config.timestamp === undefined) {
|
||||
await powerOff({id: Math.random(), mode: MODE_POWEROFF, color: '#000000', options: {index: LEDS_ALL}});
|
||||
await stopLedsAccordingly(config);
|
||||
config.timestamp = new Date().getTime();
|
||||
}
|
||||
let indices = getIndices(config);
|
||||
|
@ -62,7 +60,7 @@ async function complex(config) {
|
|||
if (shouldLedFinish(config)) {
|
||||
return {status: 'ok', time: (new Date().getTime() - config.timestamp) + 'ms'};
|
||||
}
|
||||
await setLedState(indices[index], LED_ANIMATED);
|
||||
await setLedAnimated(indices[index]);
|
||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||
config.repetitions.done++;
|
||||
} finally {
|
||||
|
@ -74,9 +72,9 @@ async function complex(config) {
|
|||
|
||||
// power the blinkstick (or just a specific led) off
|
||||
async function powerOff(config) {
|
||||
await forceStop();
|
||||
config.timestamp = new Date().getTime();
|
||||
let indices = getIndices(config);
|
||||
await forceStop(indices);
|
||||
for (let index = 0; index < indices.length; index++) {
|
||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||
logger.info('led \'' + indices[index] + '\' powered off');
|
||||
|
@ -121,22 +119,28 @@ async function singleAnimation(config, index) {
|
|||
});
|
||||
}
|
||||
|
||||
async function stopLedsAccordingly(config) {
|
||||
if (config.options.index === LEDS_ALL) {
|
||||
return await powerOff({id: Math.random(), mode: MODE_POWEROFF, color: '#000000', options: {index: LEDS_ALL}});
|
||||
}
|
||||
return stopLedAnimation(config.options.index);
|
||||
}
|
||||
|
||||
async function forceStop() {
|
||||
return new Promise((resolve, reject) => {
|
||||
stop = true;
|
||||
LEDS_STOP.push(LEDS_ALL);
|
||||
return await new Promise((resolve, reject) => {
|
||||
waitForAllAnimationsEnd(() => {
|
||||
stop = false;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function shouldLedFinish(config) {
|
||||
if (stop) {
|
||||
if (isLedStopping(config.options.index)) {
|
||||
return true;
|
||||
}
|
||||
if (config.mode === MODE_BLINK && config.mode === MODE_PULSE) {
|
||||
return config.repetitions.max !== 0 && config.repetitions.done >= config.repetitions.max
|
||||
if (config.mode === MODE_BLINK || config.mode === MODE_PULSE) {
|
||||
return config.repetitions.max !== 0 && config.repetitions.done >= config.repetitions.max;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -149,23 +153,41 @@ function getIndices(blinkstickConfig) {
|
|||
return [blinkstickConfig.options.index];
|
||||
}
|
||||
|
||||
async function setLedState(index, state) {
|
||||
await stopLedAnimation(index);
|
||||
LEDS.set(index, state);
|
||||
function setLedAnimated(index) {
|
||||
if (isLedAnimated(index)) {
|
||||
return;
|
||||
}
|
||||
LEDS_ANIMATED.push(index);
|
||||
}
|
||||
|
||||
function setLedStopping(index) {
|
||||
if (!isLedAnimated(index) || isLedStopping(index)) {
|
||||
return;
|
||||
}
|
||||
LEDS_STOP.push(index);
|
||||
}
|
||||
|
||||
function clearLedState(index) {
|
||||
return new Promise((resolve, reject) => {
|
||||
LEDS.delete(index);
|
||||
resolve();
|
||||
});
|
||||
if (index === LEDS_ALL) {
|
||||
LEDS_ANIMATED.length = 0;
|
||||
return;
|
||||
}
|
||||
LEDS_ANIMATED.splice(LEDS_ANIMATED.indexOf(index), 1);
|
||||
}
|
||||
|
||||
function isLedAnimated(index) {
|
||||
return (LEDS.get(index) || LEDS.get(LEDS_ALL)) !== undefined;
|
||||
return LEDS_ANIMATED.includes(index);
|
||||
}
|
||||
|
||||
function isLedStopping(index) {
|
||||
if (LEDS_STOP.includes(LEDS_ALL)) {
|
||||
return true;
|
||||
}
|
||||
return LEDS_STOP.includes(index);
|
||||
}
|
||||
|
||||
function stopLedAnimation(index) {
|
||||
setLedStopping(index);
|
||||
return new Promise((resolve, reject) => {
|
||||
waitForAnimationEnd(index, () => {
|
||||
resolve();
|
||||
|
@ -175,6 +197,7 @@ function stopLedAnimation(index) {
|
|||
|
||||
function waitForAnimationEnd(index, callback) {
|
||||
if (!isLedAnimated(index)) {
|
||||
LEDS_STOP.splice(LEDS_STOP.indexOf(index), 1);
|
||||
return callback();
|
||||
}
|
||||
setTimeout(() => {
|
||||
|
@ -183,7 +206,8 @@ function waitForAnimationEnd(index, callback) {
|
|||
}
|
||||
|
||||
function waitForAllAnimationsEnd(callback) {
|
||||
if (LEDS.size === 0) {
|
||||
if (LEDS_ANIMATED.length === 0) {
|
||||
LEDS_STOP.length = 0;
|
||||
return callback();
|
||||
}
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -37,15 +37,15 @@ function parseRequest(requestBody, mode) {
|
|||
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
||||
break;
|
||||
case MODE_BLINK:
|
||||
config.options.repeats = parseRepeats(requestBody.repeats, config.options.index);
|
||||
config.options.repeats = 1;
|
||||
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
||||
config.options.delay = parseDelay(requestBody.delay);
|
||||
break;
|
||||
case MODE_PULSE:
|
||||
config.options.repeats = 1;
|
||||
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
||||
config.options.duration = parseDuration(requestBody.duration, config.options.index, MODE_PULSE);
|
||||
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
||||
config.options.repeats = parseRepeats(requestBody.repeats, config.options.index);
|
||||
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
||||
break;
|
||||
}
|
||||
return config;
|
||||
|
@ -93,23 +93,8 @@ function parseSteps(steps, duration) {
|
|||
return steps;
|
||||
}
|
||||
|
||||
// parse the repeats
|
||||
function parseRepeats(repeats, index) {
|
||||
if (index === LEDS_ALL) {
|
||||
return 1;
|
||||
}
|
||||
repeats = parseInt(repeats);
|
||||
if (repeats !== repeats) {
|
||||
return 0;
|
||||
}
|
||||
return repeats;
|
||||
}
|
||||
|
||||
// parse the repetitions
|
||||
function parseRepetitions(repeats, index) {
|
||||
if (index !== LEDS_ALL) {
|
||||
return {done: 0, max: 1};
|
||||
}
|
||||
repeats = parseInt(repeats);
|
||||
if (repeats !== repeats) {
|
||||
repeats = 0;
|
||||
|
|
Loading…
Reference in a new issue