| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- "use strict";
- var utils = require("./utils");
- module.exports = function batchProcessorMaker(options) {
- options = options || {};
- var reporter = options.reporter;
- var asyncProcess = utils.getOption(options, "async", true);
- var autoProcess = utils.getOption(options, "auto", true);
- if(autoProcess && !asyncProcess) {
- reporter && reporter.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true.");
- asyncProcess = true;
- }
- var batch = Batch();
- var asyncFrameHandler;
- var isProcessing = false;
- function addFunction(level, fn) {
- if(!isProcessing && autoProcess && asyncProcess && batch.size() === 0) {
- // Since this is async, it is guaranteed to be executed after that the fn is added to the batch.
- // This needs to be done before, since we're checking the size of the batch to be 0.
- processBatchAsync();
- }
- batch.add(level, fn);
- }
- function processBatch() {
- // Save the current batch, and create a new batch so that incoming functions are not added into the currently processing batch.
- // Continue processing until the top-level batch is empty (functions may be added to the new batch while processing, and so on).
- isProcessing = true;
- while (batch.size()) {
- var processingBatch = batch;
- batch = Batch();
- processingBatch.process();
- }
- isProcessing = false;
- }
- function forceProcessBatch(localAsyncProcess) {
- if (isProcessing) {
- return;
- }
- if(localAsyncProcess === undefined) {
- localAsyncProcess = asyncProcess;
- }
- if(asyncFrameHandler) {
- cancelFrame(asyncFrameHandler);
- asyncFrameHandler = null;
- }
- if(localAsyncProcess) {
- processBatchAsync();
- } else {
- processBatch();
- }
- }
- function processBatchAsync() {
- asyncFrameHandler = requestFrame(processBatch);
- }
- function clearBatch() {
- batch = {};
- batchSize = 0;
- topLevel = 0;
- bottomLevel = 0;
- }
- function cancelFrame(listener) {
- // var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout;
- var cancel = clearTimeout;
- return cancel(listener);
- }
- function requestFrame(callback) {
- // var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); };
- var raf = function(fn) { return setTimeout(fn, 0); };
- return raf(callback);
- }
- return {
- add: addFunction,
- force: forceProcessBatch
- };
- };
- function Batch() {
- var batch = {};
- var size = 0;
- var topLevel = 0;
- var bottomLevel = 0;
- function add(level, fn) {
- if(!fn) {
- fn = level;
- level = 0;
- }
- if(level > topLevel) {
- topLevel = level;
- } else if(level < bottomLevel) {
- bottomLevel = level;
- }
- if(!batch[level]) {
- batch[level] = [];
- }
- batch[level].push(fn);
- size++;
- }
- function process() {
- for(var level = bottomLevel; level <= topLevel; level++) {
- var fns = batch[level];
- for(var i = 0; i < fns.length; i++) {
- var fn = fns[i];
- fn();
- }
- }
- }
- function getSize() {
- return size;
- }
- return {
- add: add,
- process: process,
- size: getSize
- };
- }
|