openfl
Version:
A fast, productive library for 2D cross-platform development.
226 lines (210 loc) • 7.36 kB
JavaScript
// Class: lime.system.ThreadPool
var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this
$global.Object.defineProperty(exports, "__esModule", {value: true});
var __map_reserved = {};
// Imports
var $hxClasses = require("./../../hxClasses_stub").default;
var $hxEnums = require("./../../hxEnums_stub").default;
var $import = require("./../../import_stub").default;
var $bind = require("./../../bind_stub").default;
var $extend = require("./../../extend_stub").default;
function lime_system_WorkOutput() {return require("./../../lime/system/WorkOutput");}
function js__$Boot_HaxeError() {return require("./../../js/_Boot/HaxeError");}
function lime_app_Application() {return require("./../../lime/app/Application");}
function lime_system_JobData() {return require("./../../lime/system/JobData");}
function haxe_CallStack() {return require("./../../haxe/CallStack");}
function haxe_Timer() {return require("./../../haxe/Timer");}
function lime_system_JobList() {return require("./../../lime/system/JobList");}
function lime_app__$Event_$lime_$system_$State_$Void() {return require("./../../lime/app/_Event_lime_system_State_Void");}
function lime_app__$Event_$Dynamic_$Void() {return require("./../../lime/app/_Event_Dynamic_Void");}
// Constructor
var ThreadPool = function(minThreads,maxThreads,mode) {
if(maxThreads == null) {
maxThreads = 1;
}
if(minThreads == null) {
minThreads = 0;
}
this.__jobQueue = new (lime_system_JobList().default)();
this.workPriority = 1;
this.onRun = new (lime_app__$Event_$lime_$system_$State_$Void().default)();
this.onProgress = new (lime_app__$Event_$Dynamic_$Void().default)();
this.onError = new (lime_app__$Event_$Dynamic_$Void().default)();
this.onComplete = new (lime_app__$Event_$Dynamic_$Void().default)();
(lime_system_WorkOutput().default).call(this,mode);
this.__activeJobs = new (lime_system_JobList().default)(this);
this.minThreads = minThreads;
this.maxThreads = maxThreads;
}
// Meta
ThreadPool.__name__ = "lime.system.ThreadPool";
ThreadPool.__isInterface__ = false;
ThreadPool.__super__ = (lime_system_WorkOutput().default);
ThreadPool.prototype = $extend((lime_system_WorkOutput().default).prototype, {
cancel: function(error) {
if(!ThreadPool.isMainThread()) {
throw new (js__$Boot_HaxeError().default)("Call cancel() only from the main thread.");
}
(lime_app_Application().default).current.onUpdate.remove($bind(this,this.__update));
var job = this.__activeJobs;
while(job.hasNext()) {
var job1 = job.next();
if(error != null) {
if(job1.duration == 0) {
job1.duration = ThreadPool.timestamp() - job1.startTime;
}
this.set_activeJob(job1);
this.onError.dispatch(error);
this.set_activeJob(null);
}
}
this.__activeJobs.clear();
if(error != null) {
var job2 = this.__jobQueue;
while(job2.hasNext()) {
var job3 = job2.next();
this.set_activeJob(job3);
this.onError.dispatch(error);
}
}
this.__jobQueue.clear();
this.__jobComplete.value = false;
this.set_activeJob(null);
},
cancelJob: function(jobID) {
if(!this.__activeJobs.remove(this.__activeJobs.get(jobID))) {
return this.__jobQueue.remove(this.__jobQueue.get(jobID));
} else {
return true;
}
},
queue: function(doWork,state) {
return this.run(doWork,state);
},
run: function(doWork,state) {
if(!ThreadPool.isMainThread()) {
throw new (js__$Boot_HaxeError().default)("Call run() only from the main thread.");
}
if(doWork == null) {
if(this.__doWork == null) {
throw new (js__$Boot_HaxeError().default)("run() requires doWork argument.");
} else {
doWork = this.__doWork;
}
}
if(state == null) {
state = { };
}
var job = new (lime_system_JobData().default)(doWork,state);
this.__jobQueue.push(job);
if(!(lime_app_Application().default).current.onUpdate.has($bind(this,this.__update))) {
(lime_app_Application().default).current.onUpdate.add($bind(this,this.__update));
}
return job.id;
},
__update: function(deltaTime) {
if(!ThreadPool.isMainThread()) {
return;
}
while(this.__jobQueue.get_length() > 0 && this.get_activeJobs() < this.maxThreads) {
var job = this.__jobQueue.pop();
job.startTime = ThreadPool.timestamp();
this.__activeJobs.push(job);
}
if(this.get_mode() == false && this.__activeJobs.hasNext()) {
this.set_activeJob(this.__activeJobs.next());
var state = this.get_activeJob().state;
this.__jobComplete.value = false;
this.workIterations.value = 0;
var maxTimeElapsed = this.workPriority * ThreadPool.workLoad / (ThreadPool.__totalWorkPriority * (lime_app_Application().default).current.get_window().get_frameRate());
var startTime = ThreadPool.timestamp();
var timeElapsed = 0;
try {
while(true) {
this.workIterations.value += 1;
this.get_activeJob().doWork(state,this);
timeElapsed = ThreadPool.timestamp() - startTime;
if(!(!this.__jobComplete.value && timeElapsed < maxTimeElapsed)) {
break;
}
}
} catch( e ) {
(haxe_CallStack().default).lastException = e;
this.sendError(((e) instanceof (js__$Boot_HaxeError().default)) ? e.val : e);
}
this.get_activeJob().duration += timeElapsed;
this.set_activeJob(null);
}
var threadEvent;
while(true) {
threadEvent = this.__jobOutput.pop();
if(!(threadEvent != null)) {
break;
}
if(threadEvent.jobID != null) {
this.set_activeJob(this.__activeJobs.get(threadEvent.jobID));
} else {
this.set_activeJob(threadEvent.job);
}
if(this.get_activeJob() == null || !this.__activeJobs.exists(this.get_activeJob())) {
continue;
}
if(this.get_mode() == true) {
var tmp = ThreadPool.timestamp();
this.get_activeJob().duration = tmp - this.get_activeJob().startTime;
}
switch(threadEvent.event) {
case "COMPLETE":case "ERROR":
if(threadEvent.event == "COMPLETE") {
this.onComplete.dispatch(threadEvent.message);
} else {
this.onError.dispatch(threadEvent.message);
}
this.__activeJobs.remove(this.get_activeJob());
break;
case "PROGRESS":
this.onProgress.dispatch(threadEvent.message);
break;
case "WORK":
this.onRun.dispatch(threadEvent.message);
break;
default:
}
this.set_activeJob(null);
}
if(this.get_activeJobs() == 0 && this.__jobQueue.get_length() == 0) {
(lime_app_Application().default).current.onUpdate.remove($bind(this,this.__update));
}
},
get_activeJobs: function() {
return this.__activeJobs.get_length();
},
get_idleThreads: function() {
return 0;
},
get_currentThreads: function() {
return this.get_activeJobs() + this.get_idleThreads();
},
get_doWork: function() {
return this;
},
set_workPriority: function(value) {
if(this.get_mode() == false && this.get_activeJobs() > 0) {
ThreadPool.__totalWorkPriority += value - this.workPriority;
}
return this.workPriority = value;
}
});
ThreadPool.prototype.__class__ = ThreadPool.prototype.constructor = $hxClasses["lime.system.ThreadPool"] = ThreadPool;
// Init
// Statics
ThreadPool.isMainThread = function() {
return true;
}
ThreadPool.timestamp = function() {
return (haxe_Timer().default).stamp();
}
ThreadPool.workLoad = 0.5
ThreadPool.__totalWorkPriority = 0
// Export
exports.default = ThreadPool;