From: Jay Freeman (saurik) Date: Tue, 24 Oct 2017 06:40:42 +0000 (-0700) Subject: Fold FutureSet into ResourceSet and add FutureSet. X-Git-Tag: v0.9.2~2 X-Git-Url: https://git.saurik.com/logizomai.git/commitdiff_plain/5a14f261a1ddcb3e06283059e747b7c33102bf09?ds=sidebyside;hp=f33c5d5cac0ce7dbcf978a9d028691c581d5c223 Fold FutureSet into ResourceSet and add FutureSet. --- diff --git a/lib/index.ts b/lib/index.ts index 4b875d4..d19a05a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -99,14 +99,42 @@ export function using(resource: Type, code: (resou } } +interface Waitable { + size: number; + values(): IterableIterator; + waiters: Set<(value: Value | null) => void> | null; +} + +function Get(set: Waitable, code?: () => void): Promise { + return new Promise((resolve, reject) => { + if (set.size !== 0) + resolve(set.values().next().value); + else { + if (set.waiters === null) + set.waiters = new Set<(value: Value | null) => void>(); + set.waiters.add((value: Value | null) => { + if (value === null) + reject(); + else + resolve(value); + }); + if (code !== undefined) + code(); + } + }); +} + export class ResourceSet extends Resource { private readonly set: Set; + public waiters: Set<(value: Value | null) => void> | null; constructor() { super(); this.set = new Set(); + this.waiters = null; } protected finalize(): void { + this.cancel(); this.clear(); super.finalize(); } @@ -117,10 +145,22 @@ export class ResourceSet extends Resource { return this.set.clear(); } + public cancel(): void { + const waiters = this.waiters; + this.waiters = null; + if (waiters !== null) + for (const waiter of waiters) + waiter(null); + } + public has(value: Value): boolean { return this.set.has(value); } + public get(code?: () => void): Promise { + return Get(this, code); + } + public add(value: Value): this { // .add() should return a boolean // this is simply incompetence :/ @@ -128,6 +168,13 @@ export class ResourceSet extends Resource { value.retain(); this.set.add(value); } + + const waiters = this.waiters; + this.waiters = null; + if (waiters !== null) + for (const waiter of waiters) + waiter(value); + return this; } @@ -151,18 +198,25 @@ export class ResourceSet extends Resource { } } -export class FutureSet extends ResourceSet { - private waiters: Set<(value: Value | null) => void> | null; +export class FutureSet extends Resource { + private readonly set: Set; + public waiters: Set<(value: Value | null) => void> | null; constructor() { super(); + this.set = new Set(); this.waiters = null; } protected finalize(): void { this.cancel(); + this.clear(); super.finalize(); } + public clear(): void { + return this.set.clear(); + } + public cancel(): void { const waiters = this.waiters; this.waiters = null; @@ -171,33 +225,33 @@ export class FutureSet extends ResourceSet { waiter(null); } + public has(value: Value): boolean { + return this.set.has(value); + } + public get(code?: () => void): Promise { - return new Promise((resolve, reject) => { - if (this.size !== 0) - resolve(this.values().next().value); - else { - if (this.waiters === null) - this.waiters = new Set<(value: Value | null) => void>(); - this.waiters.add((value: Value | null) => { - if (value === null) - reject(); - else - resolve(value); - }); - if (code !== undefined) - code(); - } - }); + return Get(this, code); } public add(value: Value): this { - const result = super.add(value); - const waiters = this.waiters; - this.waiters = null; - if (waiters !== null) - for (const waiter of waiters) - waiter(value); - return result; + this.set.add(value); + return this; + } + + public delete(value: Value): boolean { + return this.set.delete(value); + } + + public values(): IterableIterator { + return this.set.values(); + } + + public get size(): number { + return this.set.size; + } + + public [Symbol.iterator](): IterableIterator { + return this.set[Symbol.iterator](); } }