-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy paththread_queue.gd
More file actions
95 lines (69 loc) · 2.04 KB
/
thread_queue.gd
File metadata and controls
95 lines (69 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class_name ThreadQueue
extends RefCounted
# Thread helper for batch jobs.
signal _thread_finished
var threads_max: int = 1
var _threads: int = 0
var _jobs := []
var _mtx := Mutex.new()
var _working: bool = false
func _nop(arg=null): pass
func _init(tmax : int = 1):
if tmax < 1:
tmax = 1
threads_max = tmax
_thread_finished.connect(__thread_finished)
func clear_jobs() -> void:
_mtx.lock()
_jobs.clear()
_mtx.unlock()
func add_job(function: Callable, callback: Callable = _nop, arguments = null) -> void:
_mtx.lock()
_jobs.append(Job.new(function, callback, arguments))
_mtx.unlock()
func start() -> void:
_mtx.lock()
if not _working:
_working = true
while _working and _jobs.size() and _threads < threads_max:
var thread = Thread.new()
_threads += 1
thread.start(_work, thread, Thread.PRIORITY_LOW)
_mtx.unlock()
func _work(thread) -> void:
while true:
_mtx.lock()
if _jobs.size():
var job = _jobs.pop_front()
_mtx.unlock()
if job:
job.execute()
else:
_mtx.unlock()
break
# Shitty hack so that we safely(i think) end this Thread
(
func(_thread_finished, thread):
_thread_finished.emit(thread)
).call_deferred(_thread_finished, thread)
func __thread_finished(thread: Thread) -> void:
_mtx.lock()
_threads -= 1
# Fairly certain that this Thread should already be dead
#if thread.is_active():
# thread.wait_to_finish.call_deferred()
if _threads < 0:
_threads = 0
if not (_threads and _jobs.size()):
_working = false
_mtx.unlock()
class Job extends RefCounted:
var _function : Callable
var _callback : Callable
var _arguments
func _init(function: Callable, callback: Callable, arguments):
_function = function
_callback = callback
_arguments = arguments
func execute() -> void:
_callback.call(_function.call(_arguments))