102 lines
3 KiB
Python
102 lines
3 KiB
Python
|
import bisect, sys
|
||
|
|
||
|
"""
|
||
|
This file contains functions that were originally included in
|
||
|
Panda3D but were removed due to being obsolete. These are required
|
||
|
by Toontown, and probably cannot be replaced by anything else that
|
||
|
is still in Panda3D.
|
||
|
"""
|
||
|
|
||
|
class PriorityCallbacks:
|
||
|
""" manage a set of prioritized callbacks, and allow them to be invoked in order of priority """
|
||
|
def __init__(self):
|
||
|
self._callbacks = []
|
||
|
|
||
|
def clear(self):
|
||
|
while self._callbacks:
|
||
|
self._callbacks.pop()
|
||
|
|
||
|
def add(self, callback, priority=None):
|
||
|
if priority is None:
|
||
|
priority = 0
|
||
|
item = (priority, callback)
|
||
|
bisect.insort(self._callbacks, item)
|
||
|
return item
|
||
|
|
||
|
def remove(self, item):
|
||
|
self._callbacks.pop(bisect.bisect_left(self._callbacks, item))
|
||
|
|
||
|
def __call__(self):
|
||
|
for priority, callback in self._callbacks:
|
||
|
callback()
|
||
|
|
||
|
def clampScalar(value, a, b):
|
||
|
# calling this ought to be faster than calling both min and max
|
||
|
if a < b:
|
||
|
if value < a:
|
||
|
return a
|
||
|
elif value > b:
|
||
|
return b
|
||
|
else:
|
||
|
return value
|
||
|
else:
|
||
|
if value < b:
|
||
|
return b
|
||
|
elif value > a:
|
||
|
return a
|
||
|
else:
|
||
|
return value
|
||
|
|
||
|
def describeException(backTrace = 4):
|
||
|
# When called in an exception handler, returns a string describing
|
||
|
# the current exception.
|
||
|
|
||
|
def byteOffsetToLineno(code, byte):
|
||
|
# Returns the source line number corresponding to the given byte
|
||
|
# offset into the indicated Python code module.
|
||
|
|
||
|
import array
|
||
|
lnotab = array.array('B', code.co_lnotab)
|
||
|
|
||
|
line = code.co_firstlineno
|
||
|
for i in xrange(0, len(lnotab), 2):
|
||
|
byte -= lnotab[i]
|
||
|
if byte <= 0:
|
||
|
return line
|
||
|
line += lnotab[i+1]
|
||
|
|
||
|
return line
|
||
|
|
||
|
infoArr = sys.exc_info()
|
||
|
exception = infoArr[0]
|
||
|
exceptionName = getattr(exception, '__name__', None)
|
||
|
extraInfo = infoArr[1]
|
||
|
trace = infoArr[2]
|
||
|
|
||
|
stack = []
|
||
|
while trace.tb_next:
|
||
|
# We need to call byteOffsetToLineno to determine the true
|
||
|
# line number at which the exception occurred, even though we
|
||
|
# have both trace.tb_lineno and frame.f_lineno, which return
|
||
|
# the correct line number only in non-optimized mode.
|
||
|
frame = trace.tb_frame
|
||
|
module = frame.f_globals.get('__name__', None)
|
||
|
lineno = byteOffsetToLineno(frame.f_code, frame.f_lasti)
|
||
|
stack.append("%s:%s, " % (module, lineno))
|
||
|
trace = trace.tb_next
|
||
|
|
||
|
frame = trace.tb_frame
|
||
|
module = frame.f_globals.get('__name__', None)
|
||
|
lineno = byteOffsetToLineno(frame.f_code, frame.f_lasti)
|
||
|
stack.append("%s:%s, " % (module, lineno))
|
||
|
|
||
|
description = ""
|
||
|
for i in xrange(len(stack) - 1, max(len(stack) - backTrace, 0) - 1, -1):
|
||
|
description += stack[i]
|
||
|
|
||
|
description += "%s: %s" % (exceptionName, extraInfo)
|
||
|
return description
|
||
|
|
||
|
import __builtin__
|
||
|
__builtin__.describeException = describeException
|