export class JobQueue { constructor() { this.isFlushing = false; this.isFlushPending = false; this.scheduleId = 0; this.queue = []; this.frameInterval = 33; this.initialTime = Date.now(); } queueJob(job) { if (job.priority & JOB_PRIORITY.PRIOR) { job.cb(); } else { const index = this.findInsertionIndex(job); if (index >= 0) { this.queue.splice(index, 0, job); } } } queueFlush() { if (!this.isFlushing && !this.isFlushPending) { this.isFlushPending = true; this.scheduleJob(); } } queueFlushSync() { if (!this.isFlushing && !this.isFlushPending) { this.isFlushPending = true; this.flushJobsSync(); } } clearJobs() { this.queue.length = 0; this.isFlushing = false; this.isFlushPending = false; this.cancelScheduleJob(); } flushJobs() { this.isFlushPending = false; this.isFlushing = true; const startTime = this.getCurrentTime(); let job; while ((job = this.queue.shift())) { job.cb(); if (this.getCurrentTime() - startTime >= this.frameInterval) { break; } } this.isFlushing = false; if (this.queue.length) { this.queueFlush(); } } flushJobsSync() { this.isFlushPending = false; this.isFlushing = true; let job; while ((job = this.queue.shift())) { try { job.cb(); } catch (error) { // eslint-disable-next-line console.log(error); } } this.isFlushing = false; } findInsertionIndex(job) { let left = 0; let ins = this.queue.length; let right = ins - 1; const priority = job.priority; while (left <= right) { const mid = ((right - left) >> 1) + left; if (priority <= this.queue[mid].priority) { left = mid + 1; } else { ins = mid; right = mid - 1; } } return ins; } scheduleJob() { if ('requestIdleCallback' in window) { if (this.scheduleId) { this.cancelScheduleJob(); } this.scheduleId = window.requestIdleCallback(this.flushJobs.bind(this), { timeout: 100, }); } else { if (this.scheduleId) { this.cancelScheduleJob(); } this.scheduleId = window.setTimeout(this.flushJobs.bind(this)); } } cancelScheduleJob() { if ('cancelIdleCallback' in window) { if (this.scheduleId) { window.cancelIdleCallback(this.scheduleId); } this.scheduleId = 0; } else { if (this.scheduleId) { clearTimeout(this.scheduleId); } this.scheduleId = 0; } } getCurrentTime() { const hasPerformanceNow = typeof performance === 'object' && typeof performance.now === 'function'; if (hasPerformanceNow) { return performance.now(); } return Date.now() - this.initialTime; } } export var JOB_PRIORITY; (function (JOB_PRIORITY) { JOB_PRIORITY[JOB_PRIORITY["Update"] = 2] = "Update"; JOB_PRIORITY[JOB_PRIORITY["RenderEdge"] = 4] = "RenderEdge"; JOB_PRIORITY[JOB_PRIORITY["RenderNode"] = 8] = "RenderNode"; JOB_PRIORITY[JOB_PRIORITY["PRIOR"] = 1048576] = "PRIOR"; })(JOB_PRIORITY || (JOB_PRIORITY = {})); // function findInsertionIndex(job: Job) { // let start = 0 // for (let i = 0, len = queue.length; i < len; i += 1) { // const j = queue[i] // if (j.id === job.id) { // console.log('xx', j.bit, job.bit) // } // if (j.id === job.id && (job.bit ^ (job.bit & j.bit)) === 0) { // return -1 // } // if (j.priority <= job.priority) { // start += 1 // } // } // return start // } //# sourceMappingURL=queueJob.js.map