258 lines
6.0 KiB
JavaScript
258 lines
6.0 KiB
JavaScript
"use strict";
|
|
|
|
import {ThreadModel} from "../Models/ThreadModel.ecma.js";
|
|
import {Common} from "../Utils/Common.ecma.js";
|
|
import {Check} from "../Utils/Checks.ecma.js";
|
|
|
|
/**
|
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
|
*/
|
|
|
|
/**
|
|
* @class ThreadsManager
|
|
* @constructor
|
|
* @param {!AnP} anp
|
|
* @returns {void}
|
|
* @access private
|
|
* @static
|
|
*/
|
|
export const ThreadsManager = (function(){
|
|
|
|
/**
|
|
* @callback simple_callback
|
|
* @returns {void}
|
|
*/
|
|
|
|
/**
|
|
* @callback continue_callback
|
|
* @param {!boolean} ok
|
|
* @return {boolean}
|
|
*/
|
|
|
|
/**
|
|
* @constructs ThreadsManager
|
|
* @param {!AnP} anp
|
|
* @returns {void}
|
|
* @access private
|
|
* @static
|
|
*/
|
|
const ThreadsManager = function(anp){
|
|
|
|
/** @type {!AnP} */
|
|
const self = this,
|
|
/** @type {Object.<number, Array.<string>>} */
|
|
threads = {};
|
|
/** @type {boolean} */
|
|
let started = false,
|
|
/** @type {number} */
|
|
thread_i = 0,
|
|
/** @type {number} */
|
|
interval = null,
|
|
/** @type {string} */
|
|
mode = "interval",
|
|
/** @type {number} */
|
|
frames_per_second = 60,
|
|
/** @type {number} */
|
|
timer = 1000 / frames_per_second;
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const constructor = () => {
|
|
|
|
self.start();
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {?continue_callback} callback
|
|
* @returns {boolean}
|
|
* @access public
|
|
*/
|
|
this.update = (callback = null) => {
|
|
|
|
mode = anp.settings.get("threads_mode", null, mode);
|
|
|
|
Common.execute(callback);
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {?continue_callback} callback
|
|
* @returns {boolean}
|
|
* @access public
|
|
*/
|
|
this.reset = (callback = null) => {
|
|
|
|
Common.clear_dictionary(threads);
|
|
mode = "interval";
|
|
|
|
self.update(callback);
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {?continue_callback} callback
|
|
* @returns {boolean}
|
|
* @access public
|
|
*/
|
|
this.start = (callback = null) => {
|
|
|
|
/** @type {continue_callback} */
|
|
const end = ok => Common.execute(callback, ok);
|
|
|
|
if(started){
|
|
end(false);
|
|
return false;
|
|
};
|
|
started = true;
|
|
|
|
self.update(() => {
|
|
executor();
|
|
end(true);
|
|
});
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* @param {?continue_callback} callback
|
|
* @returns {boolean}
|
|
* @access public
|
|
*/
|
|
this.close = (callback = null) => {
|
|
|
|
/** @type {continue_callback} */
|
|
const end = ok => Common.execute(callback, ok);
|
|
|
|
if(!started){
|
|
end(false);
|
|
return false;
|
|
};
|
|
started = false;
|
|
|
|
end(true);
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const execute = () => {
|
|
|
|
/** @type {number} */
|
|
const time = Date.now();
|
|
|
|
[...Object.entries(threads)].forEach(([i, thread]) => {
|
|
if(!thread.stopped && (
|
|
!thread.frames_per_second || time - thread.last >= thread.timer
|
|
)){
|
|
thread.callback(thread);
|
|
if(thread.bucle)
|
|
thread.last = time;
|
|
else
|
|
delete threads[i];
|
|
};
|
|
});
|
|
|
|
};
|
|
|
|
/**
|
|
* @returns {void}
|
|
* @access private
|
|
*/
|
|
const executor = () => {
|
|
|
|
if(!started)
|
|
return;
|
|
|
|
switch(mode){
|
|
case "interval":
|
|
interval = setInterval(execute, timer);
|
|
break;
|
|
case "timeout":
|
|
setTimeout(() => {
|
|
execute();
|
|
executor();
|
|
}, timer);
|
|
break;
|
|
case "animation":
|
|
|
|
/** @type {number} */
|
|
const time = Date.now();
|
|
|
|
requestAnimationFrame(() => {
|
|
execute();
|
|
setTimeout(executor, timer - (Date.now() - time));
|
|
});
|
|
|
|
break;
|
|
case "only_animation":
|
|
requestAnimationFrame(() => {
|
|
execute();
|
|
executor();
|
|
});
|
|
break;
|
|
};
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {?any} inputs
|
|
* @param {!boolean} [overwrite = false]
|
|
* @param {?simple_callback} [callback = null]
|
|
* @return {void}
|
|
* @access public
|
|
*/
|
|
this.add = (callback, inputs = null) => {
|
|
if(!Check.is_function(callback))
|
|
return null;
|
|
|
|
threads[++ thread_i] = new ThreadModel(callback, thread_i, inputs);
|
|
|
|
return thread_i;
|
|
};
|
|
|
|
/**
|
|
* @param {!number} i
|
|
* @return {void}
|
|
* @access public
|
|
*/
|
|
this.play = i => {
|
|
threads[i] && threads[i].stopped && (threads[i].stopped = false);
|
|
};
|
|
|
|
/**
|
|
* @param {!number} i
|
|
* @return {void}
|
|
* @access public
|
|
*/
|
|
this.stop = i => {
|
|
threads[i] && !threads[i].stopped && (threads[i].stopped = true);
|
|
};
|
|
|
|
/**
|
|
* @param {!number} i
|
|
* @return {boolean}
|
|
* @access public
|
|
*/
|
|
this.close = i => {
|
|
if(threads[i]){
|
|
delete threads[i];
|
|
return true;
|
|
};
|
|
return false;
|
|
};
|
|
|
|
constructor();
|
|
|
|
};
|
|
|
|
/** @type {Object.<string, any|null>} */
|
|
ThreadsManager.DEFAULT_SETTINGS = {};
|
|
|
|
return ThreadsManager;
|
|
})(); |