forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJob.py
More file actions
executable file
·137 lines (109 loc) · 4.03 KB
/
Job.py
File metadata and controls
executable file
·137 lines (109 loc) · 4.03 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from direct.showbase.DirectObject import DirectObject
if __debug__:
from panda3d.core import PStatCollector
class Job(DirectObject):
"""Base class for cpu-intensive or non-time-critical operations that
are run through the :class:`.JobManager`.
To use, subclass and override the `run()` method.
"""
#: Yielded from the `run()` generator method when the job is done.
Done = object()
#: ``yield None`` is acceptable in place of ``yield Job.Continue``
Continue = None
#: Yield any remaining time for this job until next frame.
Sleep = object()
# These priorities determine how many timeslices a job gets relative to other
# jobs. A job with priority of 1000 will run 10 times more often than a job
# with priority of 100.
Priorities = ScratchPad(Min=1, Low=100, Normal=1000, High=10000)
_SerialGen = SerialNumGen()
def __init__(self, name):
self._name = name
self._generator = None
self._id = Job._SerialGen.next()
self._printing = False
self._priority = Job.Priorities.Normal
self._finished = False
if __debug__:
self._pstats = PStatCollector("App:Show code:jobManager:%s" % self._name)
def destroy(self):
del self._name
del self._generator
del self._printing
def getFinishedEvent(self):
return 'job-finished-%s' % self._id
def run(self):
"""This should be overridden with a generator that does the
needful processing.
yield `Job.Continue` when possible/reasonable, and try not to run
longer than the JobManager's timeslice between yields.
When done, yield `Job.Done`.
"""
raise NotImplementedError("don't call down")
def getPriority(self):
return self._priority
def setPriority(self, priority):
self._priority = priority
def printingBegin(self):
self._printing = True
def printingEnd(self):
self._printing = False
def resume(self):
"""Called every time JobManager is going to start running this job."""
#if self._printing:
# # we may be suspended/resumed multiple times per frame, that gets spammy
# # if we need to pick out the output of a job, put a prefix onto each line
# # of the output
# print('JOB:%s:RESUME' % self._name)
def suspend(self):
"""Called when JobManager is going to stop running this job for a
while.
"""
#if self._printing:
# #print('JOB:%s:SUSPEND' % self._name)
# pass
# """
def _setFinished(self):
self._finished = True
self.finished()
def isFinished(self):
return self._finished
def finished(self):
# called when the job finishes and has been removed from the JobManager
pass
def getJobName(self):
return self._name
def _getJobId(self):
return self._id
def _getGenerator(self):
if self._generator is None:
self._generator = self.run()
return self._generator
def _cleanupGenerator(self):
if self._generator is not None:
self._generator = None
if __debug__: # __dev__ not yet available at this point
from direct.showbase.Job import Job
class TestJob(Job):
def __init__(self):
Job.__init__(self, 'TestJob')
self._counter = 0
self._accum = 0
self._finished = False
def run(self):
self.printingBegin()
while True:
while self._accum < 100:
self._accum += 1
print('counter = %s, accum = %s' % (self._counter, self._accum))
yield None
self._accum = 0
self._counter += 1
if self._counter >= 100:
print('Job.Done')
self.printingEnd()
yield Job.Done
else:
yield None
def addTestJob():
jobMgr.add(TestJob())