| | """Base class for GLU callback-caching structures""" |
| | import ctypes |
| | import weakref |
| | from OpenGL._bytes import long, integer_types |
| |
|
| | class GLUStruct( object ): |
| | """Mix-in class for GLU Structures that want to retain references to callbacks |
| | |
| | Also provides original-object-return for the "datapointer" style paremters |
| | |
| | Each sub-class must override: |
| | CALLBACK_TYPES -- maps a "which" constant to a function type |
| | CALLBACK_FUNCTION_REGISTRARS -- maps a "which" constant to the |
| | registration function for functions of that type |
| | WRAPPER_METHODS -- maps a "which" consant to a method of the structure |
| | that produces a callable around the function which takes care of |
| | input/output arguments, data conversions, error handling and the |
| | like. |
| | Creates a dictionary member dataPointers if original-object-return is used |
| | Creates a dictionary member callbacks if callback registration is used |
| | """ |
| | def getAsParam( self ): |
| | """Gets as a ctypes pointer to the underlying structure""" |
| | return ctypes.pointer( self ) |
| | _as_parameter_ = property( getAsParam ) |
| | CALLBACK_TYPES = None |
| | CALLBACK_FUNCTION_REGISTRARS = None |
| | WRAPPER_METHODS = None |
| | def noteObject( self, object ): |
| | """Note object for later retrieval as a Python object pointer |
| | |
| | This is the registration point for "original object return", returns |
| | a void pointer to the Python object, though this is, effectively, an |
| | opaque value. |
| | """ |
| | identity = id(object) |
| | try: |
| | self.dataPointers[ identity ] = object |
| | except AttributeError as err: |
| | self.dataPointers = { identity: object } |
| | return identity |
| | def originalObject( self, voidPointer ): |
| | """Given a void-pointer, try to find our original Python object""" |
| | if isinstance( voidPointer, integer_types): |
| | identity = voidPointer |
| | elif voidPointer is None: |
| | return None |
| | else: |
| | try: |
| | identity = voidPointer.value |
| | except AttributeError as err: |
| | identity = voidPointer[0] |
| | try: |
| | return self.dataPointers[ identity ] |
| | except (KeyError,AttributeError) as err: |
| | return voidPointer |
| | def addCallback( self, which, function ): |
| | """Register a callback for this structure object""" |
| | callbackType = self.CALLBACK_TYPES.get( which ) |
| | if not callbackType: |
| | raise ValueError( |
| | """Don't have a registered callback type for %r"""%( |
| | which, |
| | ) |
| | ) |
| | wrapperMethod = self.WRAPPER_METHODS.get( which ) |
| | if wrapperMethod is not None: |
| | function = getattr(self,wrapperMethod)( function ) |
| | cCallback = callbackType( function ) |
| | |
| | try: |
| | self.CALLBACK_FUNCTION_REGISTRARS[which]( self, which, cCallback ) |
| | except ctypes.ArgumentError as err: |
| | err.args += (which,cCallback) |
| | raise |
| | |
| | |
| | if getattr( self, 'callbacks', None ) is None: |
| | self.callbacks = {} |
| | self.callbacks[ which ] = cCallback |
| | return cCallback |
| | def ptrAsArray( self, ptr, length, type ): |
| | """Copy length values from ptr into new array of given type""" |
| | result = type.zeros( (length,) ) |
| | for i in range(length): |
| | result[i] = ptr[i] |
| | return result |
| |
|