- 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.
61 lines
1.6 KiB
TypeScript
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));
|
|
};
|
|
}
|