1 """Logging of OpenGL calls.
2 """
3
4 import re
5
7 """Wrap a ctypes function so that function calls are logged.
8 """
9
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
31
34
36 self._logger_func("%s(%s)", self.__name__, self._format_args(args, kwargs))
37 return self._func(*args, **kwargs)
38
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