Runnable
...

interface RunnableInit {
    onStart?: () => void;
    onStop?: () => void;
    onCancel?: () => void;
}

class Runnable {
    constructor(init?: RunnableInit) {
        this.running = false;
        this.cancelled = false;
        init = init || {};
        this.onStart = init.onStart || null;
        this.onStop = init.onStop || null;
        this.onCancel = init.onCancel || null;
    }
    
    start() {
        if (!this.running) {
            this.running = true;
            this.onStart?.();
        }
    }

    stop() {
        if (this.running) {
            this.running = false;
            this.onStop?.();
        }
    }

    cancel() {
        this.stop();
        if (!this.cancelled) {
            this.cancelled = !0;
            this.onCancel?.();
        }
    }

    isRunning() {
        return this.running
    }
    
    isCancelled() {
        return this.cancelled
    }
}