Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 90cc63ee authored by Simon Chan's avatar Simon Chan
Browse files

feat(adb): use sticky event emitter for...

feat(adb): use sticky event emitter for `AdbServerClient.DeviceObserver.prototype.onListChange` event
parent 4deb890b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
import type { DeviceObserver } from "@yume-chan/adb";
import { EventEmitter } from "@yume-chan/event";
import { EventEmitter, StickyEventEmitter } from "@yume-chan/event";

import {
    AdbDaemonWebUsbDevice,
@@ -34,7 +34,7 @@ export class AdbDaemonWebUsbDeviceObserver
    #onDeviceRemove = new EventEmitter<AdbDaemonWebUsbDevice[]>();
    onDeviceRemove = this.#onDeviceRemove.event;

    #onListChange = new EventEmitter<AdbDaemonWebUsbDevice[]>();
    #onListChange = new StickyEventEmitter<AdbDaemonWebUsbDevice[]>();
    onListChange = this.#onListChange.event;

    current: AdbDaemonWebUsbDevice[] = [];
+12 −9
Original line number Diff line number Diff line
import { EventEmitter } from "@yume-chan/event";
import { EventEmitter, StickyEventEmitter } from "@yume-chan/event";

import { Ref } from "../utils/index.js";

@@ -95,6 +95,17 @@ export class AdbServerDeviceObserverOwner {
            throw options.signal.reason;
        }

        const onDeviceAdd = new EventEmitter<AdbServerClient.Device[]>();
        const onDeviceRemove = new EventEmitter<AdbServerClient.Device[]>();
        const onListChange = new StickyEventEmitter<AdbServerClient.Device[]>();
        const onError = new StickyEventEmitter<Error>();

        const observer = { onDeviceAdd, onDeviceRemove, onListChange, onError };
        // Register `observer` before `#connect`.
        // Because `#connect` might immediately receive some data
        // and want to trigger observers
        this.#observers.push(observer);

        this.#stream ??= this.#connect();
        const stream = await this.#stream;

@@ -103,14 +114,6 @@ export class AdbServerDeviceObserverOwner {
            throw options.signal.reason;
        }

        const onDeviceAdd = new EventEmitter<AdbServerClient.Device[]>();
        const onDeviceRemove = new EventEmitter<AdbServerClient.Device[]>();
        const onListChange = new EventEmitter<AdbServerClient.Device[]>();
        const onError = new EventEmitter<Error>();

        const observer = { onDeviceAdd, onDeviceRemove, onListChange, onError };
        this.#observers.push(observer);

        const ref = new Ref(options);

        const stop = async () => {
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ export class EventEmitter<TEvent, TResult = unknown> implements Disposable {

    fire(e: TEvent) {
        for (const info of this.listeners.slice()) {
            info.listener.apply(info.thisArg, [e, ...info.args]);
            info.listener.call(info.thisArg, e, ...info.args);
        }
    }

+2 −1
Original line number Diff line number Diff line
export * from "./disposable.js";
export * from "./event.js";
export * from "./event-emitter.js";
export * from "./event.js";
export * from "./sticky-event-emitter.js";
export * from "./utils.js";
+23 −0
Original line number Diff line number Diff line
import { EventEmitter, type EventListenerInfo } from "./event-emitter.js";
import type { RemoveEventListener } from "./event.js";

export class StickyEventEmitter<TEvent, TResult = unknown> extends EventEmitter<
    TEvent,
    TResult
> {
    #value: TEvent | undefined;

    protected override addEventListener(
        info: EventListenerInfo<TEvent, TResult>,
    ): RemoveEventListener {
        if (this.#value) {
            info.listener.call(info.thisArg, this.#value, ...info.args);
        }
        return super.addEventListener(info);
    }

    override fire(e: TEvent): void {
        this.#value = e;
        super.fire(e);
    }
}