magichome-platform
Version:
discover, control, and receive status for magichome devices
99 lines (98 loc) • 4.82 kB
JavaScript
"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;