Skip to content

Instantly share code, notes, and snippets.

@aawray
Created December 16, 2016 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aawray/fdfb1f99dea553064bbf40b5b06dde1f to your computer and use it in GitHub Desktop.
Save aawray/fdfb1f99dea553064bbf40b5b06dde1f to your computer and use it in GitHub Desktop.
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