1 from os
import pardir
# pardir is .. (parent directory)
2 from os
.path
import dirname
, abspath
, join
3 from sys
import modules
4 from direct
.task
import Task
5 from direct
.interval
.IntervalGlobal
import ivalMgr
6 from ya2
.gameobject
import GameObject
11 paused_taskchain
= 'paused tasks'
13 def __init__(self
, tsk
):
15 path
= dirname(modules
[Task
.__name
__].__file
__)
16 self
.__direct
_dir
= abspath(join(path
, pardir
)) # path of direct.*
19 func
= self
.tsk
.get_function() # ordinary tasks
22 if "from '" in str(modules
[mod
]):
23 modfile
= str(modules
[mod
]).split("from '")[1][:-2]
24 sys_mod
= modfile
.find(self
.__direct
_dir
) < 0
26 if hasattr(func
, 'im_class'):
27 actor_ival
= func
.im_class
.__name
__ == 'ActorInterval'
28 if mod
.find('direct.interval') == 0 and not actor_ival
:
29 self
.tsk
.interval
.pause() # python-based intervals
31 if mod
not in modules
or sys_mod
: return self
.tsk
36 has_args
= hasattr(tsk
, 'getArgs')
37 tsk
.stored_extraArgs
= tsk
.get_args() if has_args
else None
38 if hasattr(tsk
, 'getFunction'): tsk
.stored_call
= tsk
.get_function()
39 has_p
= hasattr(tsk
, '_priority')
40 tsk
.stored_priority
= tsk
._priority
if has_p
else tsk
.get_sort()
41 if hasattr(tsk
, 'remainingTime'): tsk
.remove() # do_later tasks
42 else: # ordinary tasks
43 tsk
.lastactivetime
= -tsk
.time
if hasattr(tsk
, 'time') else 0
44 tsk
.setTaskChain(TaskDec
.paused_taskchain
)
46 def __resume_do_later(self
):
48 d_t
= globalClock
.get_real_time() - globalClock
.get_frame_time()
49 tmp_delay
= tsk
.remainingTime
- d_t
50 upon_death
= tsk
.uponDeath
if hasattr(tsk
, 'uponDeath') else None
51 new_task
= taskMgr
.doMethodLater(
52 tmp_delay
, tsk
.stored_call
, tsk
.name
, uponDeath
=upon_death
,
53 priority
=tsk
.stored_priority
, extraArgs
=tsk
.stored_extraArgs
)
54 if hasattr(tsk
, 'remainingTime'): new_task
.delayTime
= tsk
.delayTime
58 if hasattr(tsk
, 'interval'):
60 if hasattr(tsk
, 'stored_call'): tsk
.set_function(tsk
.stored_call
)
62 if hasattr(tsk
, 'remainingTime'):
63 self
.__resume
_do
_later
()
65 tsk
.set_delay(tsk
.lastactivetime
) # ordinary tasks
66 tsk
.set_task_chain('default')
67 tsk
.clear_delay() # to avoid assertion error on resume
70 class P3dPause(GameObject
):
73 GameObject
.__init
__(self
)
74 taskMgr
.setupTaskChain(TaskDec
.paused_taskchain
, frameBudget
=0)
75 self
.__paused
_ivals
= []
76 self
.__paused
_tasks
= []
80 tsk
= taskMgr
.getTasksNamed('__on_frame')[0]
81 return tsk
.getTaskChain() == TaskDec
.paused_taskchain
83 def pause_tasks(self
):
84 is_tsk
= lambda tsk
: tsk
and hasattr(tsk
, 'getFunction')
85 tasks
= [TaskDec(tsk
) for tsk
in taskMgr
.getTasks() if is_tsk(tsk
)]
86 tasks
= [tsk
for tsk
in tasks
87 if tsk
.tsk
.get_task_chain() != 'unpausable']
88 namefilter
= ['igLoop', 'dataLoop', 'ivalLoop', 'collisionLoop',
89 'garbageCollectStates', 'audioLoop',
90 'resetPrevTransform', 'eventManager']
91 tasks
= [tsk
for tsk
in tasks
92 if tsk
.tsk
.get_name_prefix() not in namefilter
]
93 not_none
= lambda tsk
: tsk
is not None
94 paused_tasks
= list(filter(not_none
, [tsk
.process() for tsk
in tasks
]))
95 self
.__paused
_tasks
= list(map(TaskDec
, paused_tasks
))
96 for tsk
in list(filter(is_tsk
, taskMgr
.getDoLaters())):
97 self
.__paused
_tasks
+= [TaskDec(tsk
)]
98 tsk
.remainingTime
= tsk
.wakeTime
- globalClock
.get_frame_time()
99 list(map(lambda tsk
: tsk
.pause(), self
.__paused
_tasks
))
101 def remove_task(self
, tsk
):
102 list(map(self
.__paused
_tasks
.remove
, [ptsk
for ptsk
in self
.__paused
_tasks
if ptsk
.tsk
== tsk
]))
105 self
.__paused
_ivals
= ivalMgr
.getIntervalsMatching('*')
110 list(map(lambda ival
: ival
.resume(), self
.__paused
_ivals
))
111 list(map(lambda tsk
: tsk
.resume(), self
.__paused
_tasks
))
114 def destroy(self
): GameObject
.destroy(self
)