| """Implementation of OpenGL constant objects""" |
| import sys |
| from OpenGL._bytes import bytes,unicode,as_8_bit, long, integer_types, maxsize |
| from OpenGL import _configflags |
|
|
| class Constant( object ): |
| """OpenGL constant that displays itself as a name rather than a value |
| |
| The purpose of this class is to make debugging OpenGL code easier, |
| as you recieve messages that say what value you passed in in a |
| human-readable form, rather than as a bald number that requires |
| lookup and disambiguation in the header file. |
| """ |
| def __new__( cls, name, value=None ): |
| """Initialise the constant with the given name and value""" |
| if not isinstance( value, Constant ): |
| if isinstance( value, float ) and cls is not FloatConstant: |
| return FloatConstant( name, value ) |
| elif isinstance( value, int ) and cls is not IntConstant: |
| return IntConstant( name, value ) |
| elif isinstance( value, long ) and cls is not LongConstant: |
| return LongConstant( name, value ) |
| elif isinstance( value, (bytes,unicode) ) and cls is not StringConstant: |
| return StringConstant( name, as_8_bit(value) ) |
| if isinstance( value, integer_types ): |
| if value > maxsize: |
| value = - (value & maxsize) |
| base = super(Constant,cls).__new__( cls, value ) |
| base.name = name |
| if _configflags.MODULE_ANNOTATIONS: |
| frame = sys._getframe().f_back |
| if frame and frame.f_back and '__name__' in frame.f_back.f_globals: |
| base.__module__ = frame.f_back.f_globals['__name__'] |
| return base |
| def __repr__( self ): |
| """Return the name, rather than the bald value""" |
| return self.name |
| def __getnewargs__( self ): |
| """Produce the new arguments for recreating the instance""" |
| return (self.name,) + super( Constant, self ).__getnewargs__() |
|
|
| class NumericConstant( Constant ): |
| """Base class for numeric-value constants""" |
| def __str__( self ): |
| """Return the value as a human-friendly string""" |
| return '%s (%s)'%(self.name,super(Constant,self).__str__()) |
| def __getstate__(self): |
| """Retrieve state for pickle and the like""" |
| return self.name |
| def __setstate__( self, state ): |
| self.name = state |
|
|
| class IntConstant( NumericConstant, int ): |
| """Integer constant""" |
| if int is not long: |
| class LongConstant( NumericConstant, long ): |
| """Long integer constant""" |
| else: |
| LongConstant = IntConstant |
| class FloatConstant( NumericConstant, float ): |
| """Float constant""" |
|
|
| class StringConstant( Constant, bytes ): |
| """String constants""" |
| def __repr__( self ): |
| """Return the value as a human-friendly string""" |
| return '%s (%s)'%(self.name,super(Constant,self).__str__()) |
|
|
| if __name__ == "__main__": |
| x = IntConstant( 'testint', 3 ) |
| y = FloatConstant( 'testfloat', 3.0 ) |
| z = StringConstant( 'teststr', 'some testing string' ) |
|
|
| import pickle |
| for val in x,y,z: |
| restored = pickle.loads( pickle.dumps( val )) |
| assert restored == val, (str(restored),str(val)) |
| assert restored.name == val.name, (restored.name,val.name) |
|
|