DirectObject.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. """Defines the DirectObject class, a convenient class to inherit from if the
  2. object needs to be able to respond to events."""
  3. __all__ = ['DirectObject']
  4. from direct.directnotify.DirectNotifyGlobal import directNotify
  5. from direct.task.TaskManagerGlobal import taskMgr
  6. from .MessengerGlobal import messenger
  7. class DirectObject:
  8. """
  9. This is the class that all Direct/SAL classes should inherit from
  10. """
  11. #def __del__(self):
  12. # This next line is useful for debugging leaks
  13. #print "Destructing: ", self.__class__.__name__
  14. # Wrapper functions to have a cleaner, more object oriented approach to
  15. # the messenger functionality.
  16. def accept(self, event, method, extraArgs=[]):
  17. return messenger.accept(event, self, method, extraArgs, 1)
  18. def acceptOnce(self, event, method, extraArgs=[]):
  19. return messenger.accept(event, self, method, extraArgs, 0)
  20. def ignore(self, event):
  21. return messenger.ignore(event, self)
  22. def ignoreAll(self):
  23. return messenger.ignoreAll(self)
  24. def isAccepting(self, event):
  25. return messenger.isAccepting(event, self)
  26. def getAllAccepting(self):
  27. return messenger.getAllAccepting(self)
  28. def isIgnoring(self, event):
  29. return messenger.isIgnoring(event, self)
  30. #This function must be used if you want a managed task
  31. def addTask(self, *args, **kwargs):
  32. if not hasattr(self, "_taskList"):
  33. self._taskList = {}
  34. kwargs['owner'] = self
  35. task = taskMgr.add(*args, **kwargs)
  36. return task
  37. def doMethodLater(self, *args, **kwargs):
  38. if not hasattr(self, "_taskList"):
  39. self._taskList = {}
  40. kwargs['owner'] = self
  41. task = taskMgr.doMethodLater(*args, **kwargs)
  42. return task
  43. def removeTask(self, taskOrName):
  44. if isinstance(taskOrName, str):
  45. # we must use a copy, since task.remove will modify self._taskList
  46. if hasattr(self, '_taskList'):
  47. taskListValues = list(self._taskList.values())
  48. for task in taskListValues:
  49. if task.name == taskOrName:
  50. task.remove()
  51. else:
  52. taskOrName.remove()
  53. def removeAllTasks(self):
  54. if hasattr(self, '_taskList'):
  55. for task in list(self._taskList.values()):
  56. task.remove()
  57. def _addTask(self, task):
  58. self._taskList[task.id] = task
  59. def _clearTask(self, task):
  60. del self._taskList[task.id]
  61. def detectLeaks(self):
  62. if not __dev__:
  63. return
  64. # call this after the DirectObject instance has been destroyed
  65. # if it's leaking, will notify user
  66. # make sure we're not still listening for messenger events
  67. events = messenger.getAllAccepting(self)
  68. # make sure we're not leaking tasks
  69. # TODO: include tasks that were added directly to the taskMgr
  70. tasks = []
  71. if hasattr(self, '_taskList'):
  72. tasks = [task.name for task in self._taskList.values()]
  73. if len(events) != 0 or len(tasks) != 0:
  74. from direct.showbase.PythonUtil import getRepository
  75. estr = ('listening to events: %s' % events if len(events) != 0 else '')
  76. andStr = (' and ' if len(events) != 0 and len(tasks) != 0 else '')
  77. tstr = ('%srunning tasks: %s' % (andStr, tasks) if len(tasks) != 0 else '')
  78. notify = directNotify.newCategory('LeakDetect')
  79. crash = getattr(getRepository(), '_crashOnProactiveLeakDetect', False)
  80. func = (self.notify.error if crash else self.notify.warning)
  81. func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
  82. #snake_case alias:
  83. add_task = addTask
  84. do_method_later = doMethodLater
  85. detect_leaks = detectLeaks
  86. accept_once = acceptOnce
  87. ignore_all = ignoreAll
  88. get_all_accepting = getAllAccepting
  89. is_ignoring = isIgnoring
  90. remove_all_tasks = removeAllTasks
  91. remove_task = removeTask
  92. is_accepting = isAccepting