blob: fd8f39efc30551327258e06dfeb248bd34521562 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
type KeyValueStoreCallback<T> = (value: T) => void;
interface IKeyValueStoreParam<T> {
value: T;
valueRange?: T[];
callbacks?: KeyValueStoreCallback<T>[];
}
type KeyValueStoreData<T> = { [K in keyof T]: IKeyValueStoreParam<T[K]> };
class KeyValueStore<T> {
constructor(private data: KeyValueStoreData<T>) {
for (const id of Object.keys(data)) {
const props = data[id as keyof typeof data];
if (props.valueRange && props.valueRange.indexOf(props.value) === -1) {
throw new Error(`Invalid value "${props.value}" for ID "${id}"`);
}
}
}
public getValue(id: keyof T) {
return this.data[id].value;
}
public setValue<K extends keyof T>(id: K, value: T[K]) {
const props = this.data[id];
if (props.valueRange) {
const valueIndex = props.valueRange.indexOf(value);
if (valueIndex === -1) {
throw new Error(`Invalid value "${value}" for ID "${id}"`);
}
}
props.value = value;
if (props.callbacks) {
props.callbacks.forEach(callback => {
callback(value);
});
}
}
public cycleValue<K extends keyof T>(id: K, dir: -1 | 1 = 1) {
const props = this.data[id];
if (!props) {
throw new Error(`Invalid ID "${id}"`);
}
let value = props.value;
if (props.valueRange) {
let valueIndex = props.valueRange.indexOf(value) + dir;
if (valueIndex >= props.valueRange.length) {
valueIndex = 0;
} else if (valueIndex < 0) {
valueIndex = props.valueRange.length - 1;
}
value = props.value = props.valueRange[valueIndex];
} else if (typeof value === "number") {
(value as number) += dir;
props.value = value;
} else {
throw new Error(`Can't cycle "${id}"`);
}
if (props.callbacks) {
props.callbacks.forEach(callback => {
callback(value);
});
}
return value;
}
public addCallback<K extends keyof T>(id: K, callback: KeyValueStoreCallback<T[K]>) {
const props = this.data[id];
if (!props.callbacks) {
props.callbacks = [];
}
props.callbacks.push(callback);
}
}
|