Created
December 16, 2016 13:37
-
-
Save aawray/fdfb1f99dea553064bbf40b5b06dde1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (!String.prototype.hash) { | |
/** | |
* Calculate a 32 bit FNV-1a hash | |
* Found here: https://gist.github.com/vaiorabbit/5657561 | |
* Ref.: http://isthe.com/chongo/tech/comp/fnv/ | |
* | |
* @param {string} str the input value | |
* @param {boolean} [asString=false] set to true to return the hash value as | |
* 8-digit hex string instead of an integer | |
* @param {number} [seed] optionally pass the hash of the previous chunk | |
* @returns {number | string} | |
*/ | |
hashFnv32a = function (str, asString, seed) { | |
var i, l, | |
hval = (seed === undefined) ? 0x811c9dc5 : seed; | |
for (i = 0, l = str.length; i < l; i++) { | |
hval ^= str.charCodeAt(i); | |
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); | |
} | |
if (asString) { | |
// Convert to 8 digit hex string | |
return ("0000000" + (hval >>> 0).toString(16)).substr(-8); | |
} | |
return hval >>> 0; | |
}; | |
String.prototype.hash = function () { | |
return hashFnv32a(this); | |
}; | |
} | |
var JobQueue; | |
JobQueue = function () { | |
/** | |
* JobQueue | |
* @param {object} params настройки очереди | |
*/ | |
this.initialize = function (params) { | |
var self = this; | |
var defaults = {delay: 100}; | |
this.settings = $.extend(params, defaults); | |
this._queue = []; | |
this._timers = []; | |
this._envs = []; | |
this._waiter = setTimeout(function () { | |
self.wait(); | |
}, this.settings.delay); | |
return this; | |
}; | |
/** | |
* JobQueue.append добавляет задачу в очередь на выполнение | |
* | |
* @param {object} item параметры запуска: | |
* fn: функция на запуск (для повторного вызова функция должна вернуть true) | |
* delay: длительность паузы до выполнения вызова | |
* queue_id: имя очереди (для проверки блокировки) | |
* | |
* @return JobQueue | |
* | |
*/ | |
this.append = function (item) { | |
if (typeof item != "object") return; | |
if (typeof item.fn != "function") return; | |
var q = this._queue; | |
item = $.extend({ | |
delay: this.settings.delay, | |
queue_id: 0 | |
}, item); | |
if (typeof item.queue_id == "string") item.queue_id = item.queue_id.hash(); | |
q.push(item); | |
return this; | |
}; | |
/** | |
* JobQueue.is_empty сообщает пустая ли очередь | |
* | |
* @return {boolean} | |
* | |
*/ | |
this.is_empty = function () { | |
return this._queue.length == 0; | |
}; | |
/** | |
* JobQueue.wait поддерживает ожидание если очередь пуста, в противном случае вызывает обработку очереди | |
* | |
* @return JobQueue | |
* | |
*/ | |
this.wait = function () { | |
var self = this; | |
if (!this.is_empty()) this.process(); | |
this._waiter = setTimeout(function () { | |
self.wait(); | |
}, this.settings.delay); | |
return this; | |
}; | |
/** | |
* JobQueue.is_busy сообщает занята ли очередь | |
* | |
* @param id идентификатор внутренней очереди | |
* @return boolean | |
* | |
*/ | |
this.is_busy = function (id) { | |
return !!this._timers[id] || !!this._envs[id]; | |
}; | |
/** | |
* JobQueue.process ищет и отправляет на обработку элементы свободной очереди | |
* | |
* @return JobQueue | |
* | |
*/ | |
this.process = function () { | |
var q = this._queue, | |
item_index = 0; | |
while (item_index < q.length) { | |
var item = q[item_index]; | |
/* Проверяем очередь на блокировку */ | |
if (this.is_busy(item.queue_id)) { | |
++item_index; | |
/* Переходим к следующей итерации цикла */ | |
continue; | |
} | |
/* Обрабатываем элемент */ | |
this.execute(item); | |
/* Удаляем элемент из очереди */ | |
q.splice(item_index, 1); | |
} | |
return this; | |
}; | |
/** | |
* JobQueue.execute ставит таймер на вызов функции | |
* | |
* @return JobQueue | |
* | |
*/ | |
this.execute = function (item) { | |
var self = this, | |
fn, queue_id, delay; | |
if (typeof item != "object") return null; | |
fn = item.fn; | |
queue_id = item.queue_id; | |
delay = item.delay; | |
if (typeof fn != "function") return null; | |
/* Вызываем функцию по новому таймеру */ | |
this._timers[queue_id] = setTimeout(function () { | |
/* Проверка на случай разрушенной очереди */ | |
if (!self._queue) return; | |
/* Инициализируем среду (this) для функции */ | |
self._envs[queue_id] = {}; | |
// fn.apply allows arguments as an Array, but fn.call doesn't | |
var result = fn.call(self._envs[queue_id]); | |
/* Удаляем таймер */ | |
window.clearTimeout(self._timers[queue_id]); | |
delete self._timers[queue_id]; | |
/* Удаляем среду (this) для функции */ | |
delete self._envs[queue_id]; | |
/* Проверяем требование повторить */ | |
if (result === true) self.append(item); | |
}, delay); | |
return this; | |
}; | |
/** | |
* JobQueue.destroy уборщик | |
* | |
*/ | |
this.destroy = function () { | |
delete this._queue; | |
window.clearTimeout(this._waiter); | |
delete this._waiter; | |
for (var i = 0; i < this._timers.length; ++i) { | |
window.clearTimeout(this._timers[i]); | |
delete this._timers[i]; | |
} | |
delete this._timers; | |
delete this._envs; | |
}; | |
/** | |
* JobQueue.test проверка работоспособности модуля | |
* | |
*/ | |
this.test = function () { | |
this.append({ | |
fn: function () { | |
console.log('1-test-1 1s'); | |
return true; | |
}, delay: 1000, queue_id: "qtest-block-1" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('1-test-2 2s'); | |
return true; | |
}, delay: 2000, queue_id: "qtest-block-1" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('1-test-3 3s'); | |
return true; | |
}, delay: 3000, queue_id: "qtest-block-1" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('1-test-4 2s'); | |
return true; | |
}, delay: 2000, queue_id: "qtest-block-1" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('1-test-5 1s'); | |
return true; | |
}, delay: 1000, queue_id: "qtest-block-1" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('2-test-1 1s'); | |
return true; | |
}, delay: 1000, queue_id: "qtest-block-2" | |
}); | |
this.append({ | |
fn: function () { | |
console.log('2-test-2 1s'); | |
return true; | |
}, delay: 1000, queue_id: "qtest-block-2" | |
}); | |
var c1 = $('<canvas style="top:100px;left:100px;position:absolute;z-index:9999;"></canvas>'); | |
$('body').append(c1); | |
var ctx1 = c1.get(0).getContext('2d'); | |
var c2 = $('<canvas style="top:120px;left:100px;position:absolute;z-index:9999;"></canvas>'); | |
$('body').append(c2); | |
var ctx2 = c2.get(0).getContext('2d'); | |
var c3 = $('<canvas style="top:140px;left:100px;position:absolute;z-index:9999;"></canvas>'); | |
$('body').append(c3); | |
var ctx3 = c3.get(0).getContext('2d'); | |
var randomColor = function () { | |
return '#' + (Math.random().toString(16) + "000000").substring(2, 8); | |
}; | |
var getTime = function () { | |
var d = new Date(); | |
return d.toTimeString().split(' ')[0]; | |
}; | |
this.append({ | |
fn: function () { | |
ctx1.clearRect(0, 0, 100, 100); | |
var grd = ctx1.createRadialGradient(75, 50, 5, 90, 60, 100); | |
grd.addColorStop(0, randomColor()); | |
grd.addColorStop(1, randomColor()); | |
ctx1.fillStyle = grd; | |
ctx1.fillText(getTime(), 10, 10); | |
//ctx.fillRect(10,10,20,20); | |
return true; | |
}, | |
delay: 1000, | |
queue_id: "qtest-rect-one" | |
}); | |
this.append({ | |
fn: function () { | |
ctx2.clearRect(0, 0, 100, 100); | |
var grd = ctx2.createRadialGradient(75, 50, 5, 90, 60, 100); | |
grd.addColorStop(0, randomColor()); | |
grd.addColorStop(1, randomColor()); | |
ctx2.fillStyle = grd; | |
ctx2.fillText(getTime(), 10, 10); | |
//ctx2.fillRect(10,40,20,20); | |
return true; | |
}, | |
delay: 2000, | |
queue_id: "qtest-rect-two" | |
}); | |
this.append({ | |
fn: function () { | |
ctx3.clearRect(0, 0, 100, 100); | |
var grd = ctx3.createRadialGradient(75, 50, 5, 90, 60, 100); | |
grd.addColorStop(0, randomColor()); | |
grd.addColorStop(1, randomColor()); | |
ctx3.fillStyle = grd; | |
ctx3.fillText(getTime(), 10, 10); | |
//ctx3.fillRect(10,70,20,20); | |
return true; | |
}, | |
delay: 3000, | |
queue_id: "qtest-rect-three" | |
}); | |
}; | |
this.initialize(arguments[0]); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment