Skip to content
Snippets Groups Projects
Select Git revision
  • 626932d65d04f99e5abb97aa9edde18a81018aab
  • master default
  • disable-new-requests
  • fix-bulletin-view-missing-notes-error
  • add-missing-queue-managers
  • projects-task-53
  • projects-task-51
  • projects-task-43
  • projects-task-24
  • projects-task-31
  • projects-task-32
  • projects-task-8
  • project-setup-docs
  • projects-task-28
  • projects-task-27
  • projects-task-9
  • projects-task-7
  • mass-update-course-codes-in-sections
  • wdn-four
  • learning-outcomes
  • additional-bulletin-pages
  • svn-redesign
  • svn-popups
  • svn-trunk
  • svn-performance
  • svn-tim
26 results

SloController.php

Blame
  • control_inversion.js 1.38 KiB
    import './utility.js';
    
    const runningCoprograms = [];
    
    export class Coprogram {
      constructor(main) {
        this._main = main;
        this._running = false;
        this.state = main();
        this.inputQueue = [];
      }
    
      _continue(input) {
        runningCoprograms.push(this);
        this.state.next(input);
        while (this.inputQueue.length > 0) {
          this.state.next(this.inputQueue.shift());
        }
        runningCoprograms.pop();
      }
    
      run() {
        console.assert(!this._running, `Tried to run the coprogram ${this._main} when it is already running.`);
        this._running = true;
        this._continue();
      }
    
      unblock(input) {
        if (!this._running || runningCoprograms.includes(this)) {
          this.inputQueue.push(input);
        } else {
          console.assert(this.inputQueue.length === 0, `Found coprogram ${this} blocked waiting for input when there was already input in its queue.`);
          this._continue(input);
        }
      }
    }
    
    export function*block(arm, disarm) {
      const coprogram = runningCoprograms.top();
      arm((input) => coprogram.unblock(input));
      const result = yield;
      if (disarm !== undefined) {
        disarm();
      }
      return result;
    }
    
    export const UNPAUSE = Symbol('UNPAUSE');
    
    export function*pause(delay) {
      return yield* block((unblock) => {
        if (Number.isFinite(delay)) {
          window.setTimeout(() => {
            unblock(UNPAUSE);
          }, delay);
        }
      });
    }
    
    export const internals = {runningCoprograms};