From b6c2e04db2ddd4b0064bd804f68fa0c8e718f3c3 Mon Sep 17 00:00:00 2001 From: velvettear Date: Thu, 24 Feb 2022 14:42:30 +0100 Subject: [PATCH] fixed starting and stopping of animations --- libs/blinkstick.js | 72 ++++++++++++++++++++++++++++++---------------- libs/parser.js | 21 ++------------ 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/libs/blinkstick.js b/libs/blinkstick.js index 8e8d2fa..6124c80 100644 --- a/libs/blinkstick.js +++ b/libs/blinkstick.js @@ -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(() => { diff --git a/libs/parser.js b/libs/parser.js index 188f382..179d9d3 100644 --- a/libs/parser.js +++ b/libs/parser.js @@ -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;