1 """Named constants.
2 """
3
4 import re
5 import types
6
8 """Named constant.
9 """
10
13
16
19
21 """Named integer constant.
22 """
23
26
29
32
34 i = 0
35 while i < len(self._name) and self._name[-i-1:].isdigit():
36 i += 1
37 basename = self._name[:-i]
38 digit = int(self._name[-i:]) if i > 0 else None
39 return basename, digit
40
42 if isinstance(other, NamedConstant):
43 raise TypeError("cannot add two constants")
44 else:
45 basename, digit = self._split_name()
46 if digit is None:
47 raise TypeError("not a numeric constant")
48 digit += other
49 if digit < 0:
50 raise ValueError("range exceeded")
51 return type(self)("%s%d" % (basename, digit), super(NamedConstant, self).__add__(other))
52
55
57 if isinstance(other, NamedConstant):
58 return super(NamedConstant, self).__sub__(other)
59 else:
60 basename, digit = self._split_name()
61 if digit is None:
62 raise TypeError("not a numeric constant")
63 digit -= other
64 if digit < 0:
65 raise ValueError("range exceeded")
66 return type(self)("%s%d" % (basename, digit), super(NamedConstant, self).__add__(other))
67
70
73
75 """Create a named constant with name C{name} and value C{value}.
76
77 An appropriate wrapper class will be generated if necessary.
78 """
79
80 dtype = type(value)
81
82 cls_name = "%sConstant" % "".join(x[0].upper() + x[1:] for x in dtype.__name__.split())
83 if cls_name not in globals():
84 d = {
85 "__new__": lambda cls, name, value: dtype.__new__(cls, value),
86 "__init__": lambda self, name, value: NamedConstant.__init__(self, name),
87 "__hash__": lambda self: dtype.__hash__(self),
88 }
89 globals()[cls_name] = types.ClassType(cls_name, (NamedConstant, dtype), d)
90
91 return globals()[cls_name](name, value)
92
93 -def wrap_constants(name_re="^(GL|GLU|GLUT|GLX)_[A-Z][A-Z0-9_]*$", types=(int, long, float), d=None):
94 """Convert OpenGL constants to named constants.
95
96 All values in C{d} that match C{name_re} and are of one of the types in
97 C{types} will be replaced by corresponding L{NamedConstant}s. By default,
98 C{d} is C{glitter.raw.__dict__}.
99 """
100
101 if d is None:
102 from glitter import raw
103 d = raw.__dict__
104
105 for key, value in d.items():
106 if re.match(name_re, key) and isinstance(value, tuple(types)):
107 d[key] = make_constant(key, value)
108
109 __all__ = ["NamedConstant", "wrap_constants"]
110