UNPKG

pxt-common-packages

Version:
79 lines (72 loc) 2.45 kB
namespace control { class PollEvent { public eid: number; public vid: number; public start: number; public timeOut: number; public condition: () => boolean; public once: boolean; constructor(eid: number, vid: number, start: number, timeOut: number, condition: () => boolean, once: boolean) { this.eid = eid; this.vid = vid; this.start = start; this.timeOut = timeOut; this.condition = condition; this.once = once; } } let _pollEventQueue: PollEvent[] = undefined; function pollEvents() { while (_pollEventQueue.length > 0) { const now = control.millis(); for (let i = 0; i < _pollEventQueue.length; ++i) { const ev = _pollEventQueue[i]; if (ev.condition() || (ev.timeOut > 0 && now - ev.start > ev.timeOut)) { control.raiseEvent(ev.eid, ev.vid); if (ev.once) { _pollEventQueue.splice(i, 1); --i; } } } pause(50); } // release fiber _pollEventQueue = undefined; } export function __queuePollEvent(timeOut: number, condition: () => boolean, handler: () => void) { const ev = new PollEvent( DAL.DEVICE_ID_NOTIFY, control.allocateNotifyEvent(), control.millis(), timeOut, condition, !handler ); // start polling fiber if needed if (!_pollEventQueue) { _pollEventQueue = [ev]; control.runInParallel(pollEvents); } else { // add to the queue _pollEventQueue.push(ev) } // register event if (handler) control.onEvent(ev.eid, ev.vid, handler); else // or wait control.waitForEvent(ev.eid, ev.vid); } } /** * Busy wait for a condition to be true * @param condition condition to test for * @param timeOut if positive, maximum duration to wait for in milliseconds */ //% blockId="pxt_pause_until" function pauseUntil(condition: () => boolean, timeOut?: number): void { if (!condition || condition()) return; // optimistic path if (!timeOut) timeOut = 0; control.__queuePollEvent(timeOut, condition, undefined); }