Files
advanced-camera-card/src/conditions/state-manager.ts
T
Dermot Duffy 8d3cf07b43 refactor: Significantly refactor how conditions work internally (#1886)
- Much improved API cleanliness and testability to allow further
extensibility in future
 - Simplified code in `live` view

This technically contains a small change in how overrides work in the
`live` view. Since that change is _closer_ to the documentation, and
since this is likely to be rarely used, this is not considered a
breaking change. Previously, overrides for a given live camera would
always render _as if_ that camera was selected, vs was actually
selected. Now, overrides will only apply in the live view when the
camera is _actually_ selected. If this is an issue for you in practice,
lets discuss.
2025-02-11 20:07:55 -08:00

61 lines
1.6 KiB
TypeScript

import { isEqual } from 'lodash-es';
import {
ConditionState,
ConditionStateChange,
ConditionStateListener,
ConditionStateManagerReadonlyInterface,
} from './types';
/**
* A class to manage state used in the evaluation of conditions.
*/
export class ConditionStateManager implements ConditionStateManagerReadonlyInterface {
protected _listeners: ConditionStateListener[] = [];
protected _state: ConditionState = {};
public addListener(listener: ConditionStateListener): void {
this._listeners.push(listener);
}
public removeListener(listener: ConditionStateListener): void {
this._listeners = this._listeners.filter((l) => l !== listener);
}
public getState(): ConditionState {
return this._state;
}
public setState(state: ConditionState): void {
this._processStateChange(this._calculateTrueChange(state));
}
protected _processStateChange(changeState: ConditionState): void {
if (!Object.keys(changeState).length) {
return;
}
const oldState = this._state;
this._state = {
...oldState,
...changeState,
};
this._callListeners({ old: oldState, change: changeState, new: this._state });
}
protected _calculateTrueChange(change: ConditionState): ConditionState {
const changeState: ConditionState = {};
for (const key of Object.keys(change)) {
if (!isEqual(change[key], this._state[key])) {
changeState[key] = change[key];
}
}
return changeState;
}
protected _callListeners = (stateChange: ConditionStateChange): void => {
this._listeners.forEach((listener) => listener(stateChange));
};
}