Notifier.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. """
  2. Notifier module: contains methods for handling information output
  3. for the programmer/user
  4. """
  5. from LoggerGlobal import defaultLogger
  6. from direct.showbase import PythonUtil
  7. import time
  8. import types
  9. class Notifier:
  10. serverDelta = 0
  11. # If this object is set to something, it is used to print output
  12. # messages instead of writing them to the console. This is
  13. # particularly useful for integrating the Python notify system
  14. # with the C++ notify system.
  15. streamWriter = None
  16. def __init__(self, name, logger=None):
  17. """
  18. name is a string
  19. logger is a Logger
  20. Create a new instance of the Notifier class with a given name
  21. and an optional Logger class for piping output to. If no logger
  22. specified, use the global default
  23. """
  24. self.__name = name
  25. if (logger==None):
  26. self.__logger = defaultLogger
  27. else:
  28. self.__logger = logger
  29. # Global default levels are initialized here
  30. self.__info = 1
  31. self.__warning = 1
  32. self.__debug = 0
  33. self.__logging = 0
  34. def setServerDelta(self, delta, timezone):
  35. """
  36. Call this method on any Notify object to globally change the
  37. timestamp printed for each line of all Notify objects.
  38. This synchronizes the timestamp with the server's known time
  39. of day, and also switches into the server's timezone.
  40. """
  41. delta = int(round(delta))
  42. Notifier.serverDelta = delta + time.timezone - timezone
  43. # The following call is necessary to make the output from C++
  44. # notify messages show the same timestamp as those generated
  45. # from Python-level notify messages.
  46. from pandac.PandaModules import NotifyCategory
  47. NotifyCategory.setServerDelta(self.serverDelta)
  48. self.info("Notify clock adjusted by %s (and timezone adjusted by %s hours) to synchronize with server." % (PythonUtil.formatElapsedSeconds(delta), (time.timezone - timezone) / 3600))
  49. def getTime(self):
  50. """
  51. Return the time as a string suitable for printing at the
  52. head of any notify message
  53. """
  54. # for some strange reason, time.time() updates only once/minute if
  55. # the task is out of focus on win32. time.clock doesn't have this problem.
  56. return time.strftime(":%m-%d-%Y %H:%M:%S ", time.localtime(time.time() + self.serverDelta))
  57. def getOnlyTime(self):
  58. """
  59. Return the time as a string.
  60. The Only in the name is referring to not showing the date.
  61. """
  62. return time.strftime("%H:%M:%S", time.localtime(time.time() + self.serverDelta))
  63. def __str__(self):
  64. """
  65. Print handling routine
  66. """
  67. return "%s: info = %d, warning = %d, debug = %d, logging = %d" % \
  68. (self.__name, self.__info, self.__warning, self.__debug, self.__logging)
  69. # Severity funcs
  70. def setSeverity(self, severity):
  71. from pandac.PandaModules import NSDebug, NSInfo, NSWarning, NSError
  72. if severity >= NSError:
  73. self.setWarning(0)
  74. self.setInfo(0)
  75. self.setDebug(0)
  76. elif severity == NSWarning:
  77. self.setWarning(1)
  78. self.setInfo(0)
  79. self.setDebug(0)
  80. elif severity == NSInfo:
  81. self.setWarning(1)
  82. self.setInfo(1)
  83. self.setDebug(0)
  84. elif severity <= NSDebug:
  85. self.setWarning(1)
  86. self.setInfo(1)
  87. self.setDebug(1)
  88. def getSeverity(self):
  89. from pandac.PandaModules import NSDebug, NSInfo, NSWarning, NSError
  90. if self.getDebug():
  91. return NSDebug
  92. elif self.getInfo():
  93. return NSInfo
  94. elif self.getWarning():
  95. return NSWarning
  96. else:
  97. return NSError
  98. # error funcs
  99. def error(self, errorString, exception=StandardError):
  100. """
  101. Raise an exception with given string and optional type:
  102. Exception: error
  103. """
  104. string = (self.getTime() + str(exception) + ": " + self.__name + ": " + errorString)
  105. self.__log(string)
  106. raise exception(errorString)
  107. # warning funcs
  108. def warning(self, warningString):
  109. """
  110. Issue the warning message if warn flag is on
  111. """
  112. if self.__warning:
  113. string = (self.getTime() + self.__name + '(warning): ' + warningString)
  114. self.__log(string)
  115. self.__print(string)
  116. return 1 # to allow assert myNotify.warning("blah")
  117. def setWarning(self, bool):
  118. """
  119. Enable/Disable the printing of warning messages
  120. """
  121. self.__warning = bool
  122. def getWarning(self):
  123. """
  124. Return whether the printing of warning messages is on or off
  125. """
  126. return(self.__warning)
  127. # debug funcs
  128. def debug(self, debugString):
  129. """
  130. Issue the debug message if debug flag is on
  131. """
  132. if self.__debug:
  133. string = (self.getTime() + self.__name + '(debug): ' + debugString)
  134. self.__log(string)
  135. self.__print(string)
  136. return 1 # to allow assert myNotify.debug("blah")
  137. def setDebug(self, bool):
  138. """
  139. Enable/Disable the printing of debug messages
  140. """
  141. self.__debug = bool
  142. def getDebug(self):
  143. """
  144. Return whether the printing of debug messages is on or off
  145. """
  146. return self.__debug
  147. # info funcs
  148. def info(self, infoString):
  149. """
  150. Print the given informational string, if info flag is on
  151. """
  152. if self.__info:
  153. string = (self.getTime() + self.__name + '(info): ' + infoString)
  154. self.__log(string)
  155. self.__print(string)
  156. return 1 # to allow assert myNotify.info("blah")
  157. def getInfo(self):
  158. """
  159. Return whether the printing of info messages is on or off
  160. """
  161. return self.__info
  162. def setInfo(self, bool):
  163. """
  164. Enable/Disable informational message printing
  165. """
  166. self.__info = bool
  167. # log funcs
  168. def __log(self, logEntry):
  169. """
  170. Determine whether to send informational message to the logger
  171. """
  172. if self.__logging:
  173. self.__logger.log(logEntry)
  174. def getLogging(self):
  175. """
  176. Return 1 if logging enabled, 0 otherwise
  177. """
  178. return (self.__logging)
  179. def setLogging(self, bool):
  180. """
  181. Set the logging flag to int (1=on, 0=off)
  182. """
  183. self.__logging = bool
  184. def __print(self, string):
  185. """
  186. Prints the string to output followed by a newline.
  187. """
  188. if self.streamWriter:
  189. self.streamWriter.appendData(string + '\n')
  190. else:
  191. print string
  192. def debugStateCall(self, obj=None, fsmMemberName='fsm',
  193. secondaryFsm='secondaryFSM'):
  194. """
  195. If this notify is in debug mode, print the time of the
  196. call followed by the [fsm state] notifier category and
  197. the function call (with parameters).
  198. """
  199. #f.f_locals['self'].__init__.im_class.__name__
  200. if self.__debug:
  201. state = ''
  202. doId = ''
  203. if obj is not None:
  204. fsm=obj.__dict__.get(fsmMemberName)
  205. if fsm is not None:
  206. stateObj = fsm.getCurrentState()
  207. if stateObj is not None:
  208. #state = "%s=%s"%(fsmMemberName, stateObj.getName())
  209. state = stateObj.getName()
  210. fsm=obj.__dict__.get(secondaryFsm)
  211. if fsm is not None:
  212. stateObj = fsm.getCurrentState()
  213. if stateObj is not None:
  214. #state = "%s=%s"%(fsmMemberName, stateObj.getName())
  215. state = "%s, %s"%(state, stateObj.getName())
  216. if hasattr(obj, 'doId'):
  217. doId = " doId:%s"%(obj.doId,)
  218. #if type(obj) == types.ClassType:
  219. # name = "%s."%(obj.__class__.__name__,)
  220. string = ":%s:%s [%-7s] id(%s)%s %s"%(
  221. self.getOnlyTime(),
  222. self.__name,
  223. state,
  224. id(obj),
  225. doId,
  226. PythonUtil.traceParentCall())
  227. self.__log(string)
  228. self.__print(string)
  229. return 1 # to allow assert self.notify.debugStateCall(self)
  230. def debugCall(self, debugString=''):
  231. """
  232. If this notify is in debug mode, print the time of the
  233. call followed by the notifier category and
  234. the function call (with parameters).
  235. """
  236. if self.__debug:
  237. string = ":%s:%s \"%s\" %s"%(
  238. self.getOnlyTime(),
  239. self.__name,
  240. debugString,
  241. PythonUtil.traceParentCall())
  242. self.__log(string)
  243. self.__print(string)
  244. return 1 # to allow assert self.notify.debugCall("blah")