import { IObservable, subscribe } from "./Observable.ts"; import { Option, some, value } from "./Option.ts"; import { FSharpChoice$2_$union, Choice_tryValueIfChoice1Of2, Choice_tryValueIfChoice2Of2 } from "./Choice.ts"; export type Handler = (sender: any, x: T) => void; export interface IDelegateEvent { AddHandler(d: Delegate): void; RemoveHandler(d: Delegate): void; } export interface IEvent$2 extends IDelegateEvent, IObservable { } export type IEvent = IEvent$2, T> export class Event$2 { private delegates: Delegate[] = []; private _add(d: Delegate) { this.delegates.push(d); } private _remove(d: Delegate) { const index = this.delegates.indexOf(d); if (index > -1) { this.delegates.splice(index, 1); } } get Publish(): IEvent$2 { return createEvent(h => { this._add(h) }, h => { this._remove(h) }); } public Trigger(value: Args): void; public Trigger(sender: any, value: Args): void public Trigger(senderOrValue: any, valueOrUndefined?: Args): void { let sender: any = null; const value = valueOrUndefined === undefined ? senderOrValue as Args : (sender = senderOrValue, valueOrUndefined); this.delegates.forEach(f => { f(sender, value) }); } } export class Event extends Event$2, T> { } export function add(callback: (x: T) => void, sourceEvent: IEvent$2): void { subscribe(callback, sourceEvent); } export function choose(chooser: (x: T) => Option, sourceEvent: IEvent$2): IEvent { const ev = new Event(); add((t) => { const u = chooser(t); if (u != null) { ev.Trigger(value(u)); } }, sourceEvent); return ev.Publish; } export function filter(predicate: (x: T) => boolean, sourceEvent: IEvent$2): IEvent { return choose((x) => predicate(x) ? some(x) : undefined, sourceEvent); } export function map(mapping: (x: T) => U, sourceEvent: IEvent$2): IEvent { const ev = new Event(); add((t) => ev.Trigger(mapping(t)), sourceEvent); return ev.Publish; } export function merge(event1: IEvent$2, event2: IEvent$2): IEvent { const ev = new Event(); const fn = (x: T) => ev.Trigger(x); add(fn, event1); add(fn, event2); return ev.Publish; } export function pairwise(sourceEvent: IEvent$2): IEvent<[T, T]> { const ev = new Event<[T, T]>(); let last: T; let haveLast = false; add((next) => { if (haveLast) { ev.Trigger([last, next]); } last = next; haveLast = true; }, sourceEvent); return ev.Publish; } export function partition(predicate: (x: T) => boolean, sourceEvent: IEvent$2): [IEvent, IEvent] { return [filter(predicate, sourceEvent), filter((x) => !predicate(x), sourceEvent)]; } export function scan(collector: (u: U, t: T) => U, state: U, sourceEvent: IEvent$2): IEvent { return map((t) => state = collector(state, t), sourceEvent); } export function split(splitter: (x: T) => FSharpChoice$2_$union, sourceEvent: IEvent$2): [IEvent, IEvent] { return [ choose((v) => Choice_tryValueIfChoice1Of2(splitter(v)), sourceEvent), choose((v) => Choice_tryValueIfChoice2Of2(splitter(v)), sourceEvent), ]; } export function createEvent(addHandler: (h: Del) => void, removeHandler: (h: Del) => void): IEvent$2 { return { AddHandler(h) { addHandler(h); }, RemoveHandler(h) { removeHandler(h); }, Subscribe(r) { const h = ((_: any, args: T) => r.OnNext(args)) as unknown as Del; addHandler(h); return { Dispose() { removeHandler(h); } }; } }; }