UNPKG

magichome-platform

Version:

discover, control, and receive status for magichome devices

99 lines (98 loc) 4.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnimationLoop = void 0; const __1 = require(".."); const animationUtils_1 = require("./animationUtils"); class AnimationLoop { constructor(animationBlueprint, lightIDs, STEP_INTERVAL_MS) { this.currentAnimationOffsetDurationMS = 0; this.activeLoops = new Map(); this.name = animationBlueprint.name; this.priority = animationBlueprint.priority; this.syncSequenceTimings = animationBlueprint.syncSequenceTimings; this.syncSequenceColor = animationBlueprint.syncSequenceColor; this.lightOffsetDurationMS = animationBlueprint.lightOffsetDurationMS; this.blueprintAnimationSequences = animationBlueprint.animationSequences; this.isSingularAnimationLoop = this.syncSequenceTimings && this.syncSequenceColor; this.STEP_INTERVAL_MS = STEP_INTERVAL_MS; this.associatedLightCount = 0; this.initialize(lightIDs); this.isActive = false; } initialize(lightIDs) { this.currentAnimationOffsetDurationMS = 0; this.activeLoops = new Map(); lightIDs.forEach(lightID => this.addLightToAnimationLoop(lightID)); this.isActive = false; } getAnimationStep(lightID) { const animationID = this.isSingularAnimationLoop ? __1.AnimationStepKey.ALL : lightID; const activeAnimation = this.activeLoops.get(animationID); if (!activeAnimation) throw new Error(`No active animation found for lightID: ${lightID}`); const offsetIndex = this.calculateOffsetIndex(activeAnimation); return activeAnimation.animationSteps[offsetIndex]; } calculateOffsetIndex(activeAnimation) { let offsetIndex = activeAnimation.currentStepIndex + (activeAnimation.offsetDurationMS / this.STEP_INTERVAL_MS); if (offsetIndex > activeAnimation.animationSteps.length) { offsetIndex = offsetIndex % activeAnimation.animationSteps.length; } return offsetIndex; } addLightToAnimationLoop(lightID) { if (this.activeLoops.has(lightID)) return; this.associatedLightCount++; const animationID = this.isSingularAnimationLoop ? __1.AnimationStepKey.ALL : lightID; this.initializeAnimationID(animationID); } removeLightFromAnimationLoop(lightID) { if (!this.activeLoops.has(lightID)) return; if (this.associatedLightCount > 0) this.associatedLightCount--; this.activeLoops.delete(lightID); } tickAllActiveLoops() { // if (this.associatedLightCount === 0) return false; this.activeLoops.forEach((_, key) => this.tickAnimation(key)); } tickAnimation(animationID) { if (this.associatedLightCount === 0) return; const activeAnimation = this.activeLoops.get(animationID); activeAnimation.currentStepIndex++; if (activeAnimation.currentStepIndex < 0 || activeAnimation.currentStepIndex >= activeAnimation.animationSteps.length) { this.generateAnimationSteps(animationID); } } generateAnimationSteps(animationID) { const activeAnimation = this.activeLoops.get(animationID); activeAnimation.currentStepIndex = 0; let previousSequenceEndStep = activeAnimation.previousLoopEndStep || { red: 0, green: 0, blue: 0, warmWhite: 0, coldWhite: 0 }; const animationSteps = this.blueprintAnimationSequences.reduce((acc, sequence) => { if (Math.random() < sequence.skipChance) return acc; const flatSequence = (0, animationUtils_1.recursiveArrayToInt)(sequence); flatSequence.startColor = flatSequence.startColor || previousSequenceEndStep; const steps = (0, animationUtils_1.calculateSequenceSteps)(flatSequence, this.STEP_INTERVAL_MS); previousSequenceEndStep = steps[steps.length - 1] || previousSequenceEndStep; return [...acc, ...steps]; }, []); activeAnimation.animationSteps = animationSteps; activeAnimation.previousLoopEndStep = previousSequenceEndStep; } initializeAnimationID(animationID) { if (!this.activeLoops.has(animationID)) { this.activeLoops.set(animationID, { currentStepIndex: -2, animationSteps: [], previousLoopEndStep: { red: 0, green: 0, blue: 0, warmWhite: 0, coldWhite: 0 }, offsetDurationMS: this.currentAnimationOffsetDurationMS, }); this.currentAnimationOffsetDurationMS += this.lightOffsetDurationMS; } } } exports.AnimationLoop = AnimationLoop;