Package glitter :: Package raw :: Module logger
[hide private]
[frames] | no frames]

Source Code for Module glitter.raw.logger

 1  """Logging of OpenGL calls. 
 2  """ 
 3   
 4  import re 
 5   
6 -class LoggingWrapper(object):
7 """Wrap a ctypes function so that function calls are logged. 8 """ 9
10 - def __init__(self, func, logger_func):
11 self._func = func 12 self._logger_func = logger_func 13 self.__name__ = func.__name__ 14 self.__doc__ = func.__doc__ 15 16 for key in dir(func): 17 if not key.startswith("_"): 18 setattr(self, key, getattr(func, key))
19
20 - def _format_arg(self, x):
21 if hasattr(x, "_type_") and hasattr(x, "__len__") and hasattr(x, "__getitem__"): 22 return "%s[%s]" % (x._type_.__name__, ", ".join(self._format_arg(a) for a in x)) 23 elif hasattr(x, "value"): 24 return "%s(%r)" % (x.__class__.__name__, x.value) 25 elif hasattr(x, "contents"): 26 return "&%s" % self._format_arg(x.contents) 27 elif hasattr(x, "_name"): 28 return x._name 29 else: 30 return repr(x)
31
32 - def _format_args(self, args, kwargs):
33 return ", ".join([self._format_arg(x) for x in args] + ["%s=%s" % (k, self._format_arg(v)) for (k, v) in kwargs.items()])
34
35 - def __call__(self, *args, **kwargs):
36 self._logger_func("%s(%s)", self.__name__, self._format_args(args, kwargs)) 37 return self._func(*args, **kwargs)
38
39 - def __str__(self):
40 return self.__name__
41
42 -def add_logger(logger="root", name_re="^(gl|glu|glut|glX)[A-Z].*$", d=None):
43 """Add a logger to OpenGL functions. 44 45 All values in C{d} that match C{name_re} have an C{errcheck} attribute will 46 be replaced by corresponding L{LoggingWrapper}s that call C{logger} before 47 each invocation. By default, C{d} is C{glitter.raw.__dict__}. 48 49 C{logger} may be either a callable, a C{logging.logger} object, the name of 50 a registered C{logging.Logger} object, or C{None} to remove the logger. 51 52 @attention: If you add multiple loggers to a function, you will not only 53 incur a double performance penalty, but also have to remove them in the 54 reverse order; there is no way to remove a specific logger. 55 """ 56 57 if d is None: 58 from glitter import raw 59 d = raw.__dict__ 60 61 if logger is None: 62 for key, value in d.items(): 63 if re.match(name_re, key) and isinstance(value, LoggingWrapper): 64 d[key] = value._func 65 else: 66 if not callable(logger): 67 import logging 68 if isinstance(logger, logging.Logger): 69 logger = logger.debug 70 else: 71 logger = logging.getLogger(logger).debug 72 73 for key, value in d.items(): 74 if re.match(name_re, key) and hasattr(value, "errcheck"): 75 d[key] = LoggingWrapper(value, logger)
76 77 __all__ = ["LoggingWrapper", "add_logger"] 78