refactor: impl AdbSocket using internal marks

This commit is contained in:
Simon Chan 2022-03-15 15:17:35 +08:00
parent e36de01d39
commit bc9bc49e8c
No known key found for this signature in database
GPG key ID: 8F75717685A974FB
9 changed files with 25 additions and 19 deletions

View file

@ -3,7 +3,6 @@ import { AutoDisposable, EventEmitter } from '@yume-chan/event';
import { AdbCommand, AdbPacket, AdbPacketCore, AdbPacketInit, calculateChecksum } from '../packet'; import { AdbCommand, AdbPacket, AdbPacketCore, AdbPacketInit, calculateChecksum } from '../packet';
import { AbortController, ReadableWritablePair, WritableStream, WritableStreamDefaultWriter } from '../stream'; import { AbortController, ReadableWritablePair, WritableStream, WritableStreamDefaultWriter } from '../stream';
import { decodeUtf8, encodeUtf8 } from '../utils'; import { decodeUtf8, encodeUtf8 } from '../utils';
import { AdbSocketController } from './controller';
import { AdbSocket } from './socket'; import { AdbSocket } from './socket';
export interface AdbIncomingSocketEventArgs { export interface AdbIncomingSocketEventArgs {
@ -22,7 +21,7 @@ export class AdbPacketDispatcher extends AutoDisposable {
// ADB socket id starts from 1 // ADB socket id starts from 1
// (0 means open failed) // (0 means open failed)
private readonly initializers = new AsyncOperationManager(1); private readonly initializers = new AsyncOperationManager(1);
private readonly sockets = new Map<number, AdbSocketController>(); private readonly sockets = new Map<number, AdbSocket>();
private _writer!: WritableStreamDefaultWriter<AdbPacketInit>; private _writer!: WritableStreamDefaultWriter<AdbPacketInit>;
@ -143,14 +142,13 @@ export class AdbPacketDispatcher extends AutoDisposable {
const remoteId = packet.arg0; const remoteId = packet.arg0;
const serviceString = decodeUtf8(packet.payload); const serviceString = decodeUtf8(packet.payload);
const controller = new AdbSocketController({ const socket = new AdbSocket({
dispatcher: this, dispatcher: this,
localId, localId,
remoteId, remoteId,
localCreated: false, localCreated: false,
serviceString, serviceString,
}); });
const socket = new AdbSocket(controller);
const args: AdbIncomingSocketEventArgs = { const args: AdbIncomingSocketEventArgs = {
handled: false, handled: false,
@ -161,7 +159,7 @@ export class AdbPacketDispatcher extends AutoDisposable {
this.incomingSocketEvent.fire(args); this.incomingSocketEvent.fire(args);
if (args.handled) { if (args.handled) {
this.sockets.set(localId, controller); this.sockets.set(localId, socket);
await this.sendPacket(AdbCommand.OK, localId, remoteId); await this.sendPacket(AdbCommand.OK, localId, remoteId);
} else { } else {
await this.sendPacket(AdbCommand.Close, 0, remoteId); await this.sendPacket(AdbCommand.Close, 0, remoteId);
@ -177,16 +175,16 @@ export class AdbPacketDispatcher extends AutoDisposable {
await this.sendPacket(AdbCommand.Open, localId, 0, serviceString); await this.sendPacket(AdbCommand.Open, localId, 0, serviceString);
const remoteId = await initializer; const remoteId = await initializer;
const controller = new AdbSocketController({ const socket = new AdbSocket({
dispatcher: this, dispatcher: this,
localId, localId,
remoteId, remoteId,
localCreated: true, localCreated: true,
serviceString, serviceString,
}); });
this.sockets.set(localId, controller); this.sockets.set(localId, socket);
return new AdbSocket(controller); return socket;
} }
public sendPacket(packet: AdbPacketInit): Promise<void>; public sendPacket(packet: AdbPacketInit): Promise<void>;

View file

@ -1,3 +1,2 @@
export * from './controller';
export * from './dispatcher';
export * from './socket'; export * from './socket';
export * from './dispatcher';

View file

@ -26,7 +26,7 @@ export interface AdbSocketConstructionOptions {
highWaterMark?: number | undefined; highWaterMark?: number | undefined;
} }
export class AdbSocketController implements AdbSocketInfo { export class AdbSocket implements AdbSocketInfo {
private readonly dispatcher!: AdbPacketDispatcher; private readonly dispatcher!: AdbPacketDispatcher;
public readonly localId!: number; public readonly localId!: number;
@ -84,10 +84,16 @@ export class AdbSocketController implements AdbSocketInfo {
); );
} }
/**
* @internal
*/
public async enqueue(packet: Uint8Array) { public async enqueue(packet: Uint8Array) {
await this._readableController.enqueue(packet); await this._readableController.enqueue(packet);
} }
/**
* @internal
*/
public ack() { public ack() {
this._writePromise?.resolve(); this._writePromise?.resolve();
} }
@ -109,6 +115,9 @@ export class AdbSocketController implements AdbSocketInfo {
} }
} }
/**
* @internal
*/
public dispose() { public dispose() {
this._closed = true; this._closed = true;

View file

@ -1,5 +1,5 @@
import { Disposable } from './disposable'; import type { Disposable } from './disposable';
import { EventListener, RemoveEventListener } from './event'; import type { EventListener, RemoveEventListener } from './event';
export interface EventListenerInfo<TEvent, TResult = unknown> { export interface EventListenerInfo<TEvent, TResult = unknown> {
listener: EventListener<TEvent, any, any, TResult>; listener: EventListener<TEvent, any, any, TResult>;

View file

@ -1,4 +1,4 @@
import { Disposable } from './disposable'; import type { Disposable } from './disposable';
export interface EventListener<TEvent, TThis, TArgs extends unknown[], TResult> { export interface EventListener<TEvent, TThis, TArgs extends unknown[], TResult> {
(this: TThis, e: TEvent, ...args: TArgs): TResult; (this: TThis, e: TEvent, ...args: TArgs): TResult;

View file

@ -1,5 +1,5 @@
import { PromiseResolver } from '@yume-chan/async'; import { PromiseResolver } from '@yume-chan/async';
import { Event } from './event'; import type { Event } from './event';
export async function once<T>(event: Event<T, any>): Promise<T> { export async function once<T>(event: Event<T, any>): Promise<T> {
const resolver = new PromiseResolver<T>(); const resolver = new PromiseResolver<T>();

View file

@ -4,7 +4,7 @@ import type { StructAsyncDeserializeStream, StructDeserializeStream, StructField
import { StructDefaultOptions, StructValue } from './basic'; import { StructDefaultOptions, StructValue } from './basic';
import { Syncbird } from "./syncbird"; import { Syncbird } from "./syncbird";
import { BigIntFieldDefinition, BigIntFieldType, BufferFieldSubType, FixedLengthBufferLikeFieldDefinition, FixedLengthBufferLikeFieldOptions, LengthField, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, VariableLengthBufferLikeFieldOptions } from './types'; import { BigIntFieldDefinition, BigIntFieldType, BufferFieldSubType, FixedLengthBufferLikeFieldDefinition, FixedLengthBufferLikeFieldOptions, LengthField, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, VariableLengthBufferLikeFieldOptions } from './types';
import { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils"; import type { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils";
export interface StructLike<TValue> { export interface StructLike<TValue> {
deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>; deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>;
@ -212,7 +212,7 @@ export class Struct<
> { > {
for (const field of this._fields) { for (const field of this._fields) {
if (field[0] === name) { if (field[0] === name) {
throw new Error(`This struct already have a field with name '${name}'`); throw new Error(`This struct already have a field with name '${String(name)}'`);
} }
} }

View file

@ -3,7 +3,7 @@
import { getBigInt64, getBigUint64, setBigInt64, setBigUint64 } from '@yume-chan/dataview-bigint-polyfill/esm/fallback'; import { getBigInt64, getBigUint64, setBigInt64, setBigUint64 } from '@yume-chan/dataview-bigint-polyfill/esm/fallback';
import { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions, StructValue } from "../basic"; import { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions, StructValue } from "../basic";
import { Syncbird } from "../syncbird"; import { Syncbird } from "../syncbird";
import { ValueOrPromise } from "../utils"; import type { ValueOrPromise } from "../utils";
type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint; type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint;

View file

@ -2,7 +2,7 @@
import { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions, StructValue } from '../basic'; import { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions, StructValue } from '../basic';
import { Syncbird } from "../syncbird"; import { Syncbird } from "../syncbird";
import { ValueOrPromise } from "../utils"; import type { ValueOrPromise } from "../utils";
export type DataViewGetters = export type DataViewGetters =
{ [TKey in keyof DataView]: TKey extends `get${string}` ? TKey : never }[keyof DataView]; { [TKey in keyof DataView]: TKey extends `get${string}` ? TKey : never }[keyof DataView];