export class LoadScheduler {
    constructor() {
        this.queues = new Map();
    }
    scheduleGfxLoading(load) {
        return this.schedule("gfxLoading", load);
    }
    scheduleActionExecution(execute) {
        return this.schedule("actionExecution", execute);
    }
    schedulePostUpdateManipulation(execute) {
        return this.schedule("postUpdateManipulation", execute);
    }
    schedule(type, cb) {
        return new Promise((resolve, reject) => {
            this.queue(type, () => cb()
                .then(resolve)
                .catch(reject));
            if (this.activeType === undefined) {
                // start execution of queue if nothing is currently active
                this.executeType(type);
            }
        });
    }
    async executeType(type) {
        this.activeType = type;
        const queue = this.queues.get(type).splice(0);
        await Promise.all(queue.map(cb => cb()));
        // get the first queue with at least one entry and start execution
        for (const [loadType, typeQueue] of this.queues.entries()) {
            if (typeQueue.length > 0) {
                this.executeType(loadType);
                return;
            }
        }
        this.activeType = undefined;
    }
    queue(type, cb) {
        let queue = this.queues.get(type);
        // create and register the queue if it does not yet exist
        if (queue === undefined) {
            queue = [];
            this.queues.set(type, queue);
        }
        // add the cb to the queue
        queue.push(cb);
    }
}
