xref: /MusicFree/src/utils/stateMapper.ts (revision 39ac60f7dbc1bdc5845915557793b2147e7a7f36)
1233cafa6S猫头猫import {useEffect, useState} from 'react';
2233cafa6S猫头猫
3233cafa6S猫头猫export default class StateMapper<T> {
4233cafa6S猫头猫    private getFun: () => T;
5233cafa6S猫头猫    private cbs: Set<Function> = new Set([]);
6233cafa6S猫头猫    constructor(getFun: () => T) {
7233cafa6S猫头猫        this.getFun = getFun;
8233cafa6S猫头猫    }
9233cafa6S猫头猫
10233cafa6S猫头猫    notify = () => {
11233cafa6S猫头猫        this.cbs.forEach(_ => _?.());
124060c00aS猫头猫    };
13233cafa6S猫头猫
14233cafa6S猫头猫    useMappedState = () => {
15233cafa6S猫头猫        const [_state, _setState] = useState<T>(this.getFun);
16233cafa6S猫头猫        const updateState = () => {
17233cafa6S猫头猫            _setState(this.getFun());
18233cafa6S猫头猫        };
19233cafa6S猫头猫        useEffect(() => {
20233cafa6S猫头猫            this.cbs.add(updateState);
21233cafa6S猫头猫            return () => {
22233cafa6S猫头猫                this.cbs.delete(updateState);
23233cafa6S猫头猫            };
24233cafa6S猫头猫        }, []);
25233cafa6S猫头猫        return _state;
264060c00aS猫头猫    };
27233cafa6S猫头猫}
2850800d1bS猫头猫
29*39ac60f7S猫头猫type UpdateFunc<T> = (prev: T) => T;
30*39ac60f7S猫头猫
3150800d1bS猫头猫export class GlobalState<T> {
3250800d1bS猫头猫    private value: T;
3350800d1bS猫头猫    private stateMapper: StateMapper<T>;
3450800d1bS猫头猫
3550800d1bS猫头猫    constructor(initValue: T) {
3650800d1bS猫头猫        this.value = initValue;
3750800d1bS猫头猫        this.stateMapper = new StateMapper(this.getValue);
3850800d1bS猫头猫    }
3950800d1bS猫头猫
4050800d1bS猫头猫    public getValue = () => {
4150800d1bS猫头猫        return this.value;
4250800d1bS猫头猫    };
4350800d1bS猫头猫
4491c81973S猫头猫    public useValue = () => {
4550800d1bS猫头猫        return this.stateMapper.useMappedState();
4691c81973S猫头猫    };
4750800d1bS猫头猫
48*39ac60f7S猫头猫    public setValue = (value: T | UpdateFunc<T>) => {
49*39ac60f7S猫头猫        let newValue: T;
50*39ac60f7S猫头猫        if (typeof value === 'function') {
51*39ac60f7S猫头猫            newValue = (value as UpdateFunc<T>)(this.value);
52*39ac60f7S猫头猫        } else {
53*39ac60f7S猫头猫            newValue = value;
54*39ac60f7S猫头猫        }
55*39ac60f7S猫头猫
56*39ac60f7S猫头猫        this.value = newValue;
5750800d1bS猫头猫        this.stateMapper.notify();
5891c81973S猫头猫    };
5950800d1bS猫头猫}
60