pxt-common-packages
Version:
Microsoft MakeCode (PXT) common packages
79 lines (72 loc) • 2.45 kB
text/typescript
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);
}