home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / OpenGL / converters.py < prev    next >
Encoding:
Python Source  |  2008-12-07  |  9.2 KB  |  278 lines

  1. """Implementations for common converter types"""
  2. import ctypes
  3.  
  4. class Converter( object ):
  5.     """Base class for Converter types
  6.     
  7.     Converter objects are callable objects used with the 
  8.     OpenGL.wrapper.Wrapper class to simplify the wrapping
  9.     of functions by collecting commonly used functionality
  10.     into a reusable function.
  11.     
  12.     Each Converter has two (class) attributes:
  13.  
  14.         argNames -- list of argument names for initialisation
  15.         indexLookups -- set of (indexname, argName,methodName) values 
  16.             to lookup on wrapper.  These allow us to use argument-name
  17.             references to refer to which arguments to use when 
  18.             processing (prevents the need to revise pointers when 
  19.             we change the API for a function).
  20.     
  21.     Converters can be any of the Wrapper API helper functions,
  22.     so the callable interface can vary among Converter classes.
  23.     """
  24.     argNames = ( )
  25.     indexLookups = ( )
  26.     def __init__( self, *args, **named ):
  27.         """Store arguments in attributes
  28.         
  29.         *args -- mapped to self.argNames in order to set attributes
  30.         **named -- mapped to self.argNames by name to set attributes
  31.         """
  32.         argNames = list(self.argNames)
  33.         for a in self.argNames:
  34.             if named.has_key( a ):
  35.                 setattr( self, a, named[a] )
  36.                 argNames.remove( a )
  37.         for a,value in zip( argNames, args ):
  38.             setattr( self, a, value )
  39.     def finalise( self, wrapper ):
  40.         """Look up our indices (where appropriate)"""
  41.         for indexname,argName,methodName in self.indexLookups:
  42.             setattr( 
  43.                 self, indexname, 
  44.                 getattr(wrapper,methodName)(getattr( self, argName ))
  45.             )
  46.  
  47. # Definitions of the abstract interfaces...
  48. class PyConverter( Converter ):
  49.     """Converter sub-class for use in Wrapper.pyConverters
  50.     
  51.     This class just defines the interface for a pyConverter-style
  52.     Converter object
  53.     """
  54.     def __call__( self, incoming, function, arguments ):
  55.         """Convert incoming argument into compatable data-types
  56.         
  57.         incoming -- the Python argument for this parameter
  58.         function -- the wrapper.Wrapper class we are supporting
  59.         arguments -- the complete set of arguments passed to the 
  60.             function
  61.         
  62.         
  63.         """
  64.         raise NotImplemented( """%s class doesn't implement __call__"""%(
  65.             self.__class__.__name__,
  66.         ))
  67.     
  68. class CConverter( Converter ):
  69.     """Converter sub-class for use in Wrapper.cConverters
  70.     
  71.     This class just defines the interface for a cConverter-style
  72.     Converter object
  73.     """
  74.     def __call__( self, pyArgs, index, baseOperation ):
  75.         """Calculate C-compatible Python object from Python arguments
  76.         
  77.         pyArgs -- set of Python argument objects converted by 
  78.             pyConverters from the incoming arguments 
  79.         index -- our index in baseOperation.cConverters
  80.         baseOperation -- the Wrapper object which we are supporting
  81.         """
  82.         raise NotImplemented( """%s class doesn't implement __call__"""%(
  83.             self.__class__.__name__,
  84.         ))
  85. class ReturnValues( Converter ):
  86.     """Converter sub-class for use as Wrapper.returnValues
  87.     
  88.     This class just defines the interface for a returnValues-style
  89.     Converter object
  90.     """
  91.     def __call__( self, result, baseOperation, pyArgs, cArgs ):
  92.         """Return a final value to the caller
  93.         
  94.         result -- the raw ctypes result value 
  95.         baseOperation -- the Wrapper object which we are supporting
  96.         pyArgs -- the set of Python arguments produced by pyConverters
  97.         cArgs -- the set of C-compatible arguments produced by CConverter
  98.         
  99.         return the Python object for the final result
  100.         """
  101.         raise NotImplemented( """%s class doesn't implement __call__"""%(
  102.             self.__class__.__name__,
  103.         ))
  104.  
  105. # Now the concrete classes...
  106. try:
  107.     from OpenGL_accelerate.wrapper import CallFuncPyConverter, DefaultCConverter
  108. except ImportError, err:
  109.     class CallFuncPyConverter( PyConverter ):
  110.         """PyConverter that takes a callable and calls it on incoming"""
  111.         def __init__( self, function ):
  112.             """Store the function"""
  113.             self.function = function 
  114.         def __call__( self, incoming, function, argument ):
  115.             """Call our function on incoming"""
  116.             return self.function( incoming )
  117.     class DefaultCConverter( CConverter ):
  118.         """NULL or Default CConverter, returns same-named Python argument
  119.         
  120.         Used primarily to allow for specifying a converter that explicitly
  121.         says "use the default behaviour".  This is *not* a finalise-ing
  122.         converter, it is passed in the index explicitly and just retrieves
  123.         that index from pyArgs when called.  
  124.         
  125.         Raises informative errors if the index cannot be resolved in pyArgs
  126.         """
  127.         def __init__( self, index ):
  128.             """Just store index for future access"""
  129.             self.index = index 
  130.         def __call__( self, pyArgs, index, wrapper ):
  131.             """Return pyArgs[self.index] or raise a ValueError"""
  132.             try:
  133.                 return pyArgs[ self.index ]
  134.             except IndexError, err:
  135.                 raise ValueError(
  136.                     """Expected parameter index %r, but pyArgs only length %s"""%(
  137.                     self.index,
  138.                     len(pyArgs )
  139.                 ))
  140.  
  141. class returnCArgument( ReturnValues ):
  142.     """ReturnValues returning the named cArgs value"""
  143.     argNames = ('name',)
  144.     indexLookups = [ ('index','name', 'cArgIndex' ), ]
  145.     __slots__ = ( 'index', 'name' )
  146.     def __call__( self, result, baseOperation, pyArgs, cArgs ):
  147.         """Retrieve cArgs[ self.index ]"""
  148.         return cArgs[self.index]
  149.     
  150. class returnPyArgument( ReturnValues ):
  151.     """ReturnValues returning the named pyArgs value"""
  152.     argNames = ('name',)
  153.     indexLookups = [ ('index','name', 'pyArgIndex' ), ]
  154.     __slots__ = ( 'index', 'name' )
  155.     def __call__( self, result, baseOperation, pyArgs, cArgs ):
  156.         """Retrieve pyArgs[ self.index ]"""
  157.         return pyArgs[self.index]
  158.  
  159.  
  160. class getPyArgsName( CConverter ):
  161.     """CConverter returning named Python argument
  162.     
  163.     Intended for use in cConverters, the function returned 
  164.     retrieves the named pyArg and returns it when called.
  165.     """
  166.     argNames = ('name',)
  167.     indexLookups = [ ('index','name', 'pyArgIndex' ), ]
  168.     __slots__ = ( 'index', 'name')
  169.     def __call__( self, pyArgs, index, baseOperation ):
  170.         """Return pyArgs[ self.index ]"""
  171.         try:
  172.             return pyArgs[ self.index ]
  173.         except AttributeError, err:
  174.             raise RuntimeError( """"Did not resolve parameter index for %r"""%(self.name))
  175.  
  176. class Output( CConverter ):
  177.     """CConverter generating static-size typed output arrays
  178.     
  179.     Produces an output array of given type (arrayType) and 
  180.     size using self.lookup() to determine the size of the 
  181.     array to be produced, where the lookup function is passed 
  182.     as an initialisation argument.
  183.     
  184.     Provides also:
  185.     
  186.         oldStyleReturn( ... ) for use in the default case of
  187.             PyOpenGL compatability mode, where result arrays of
  188.             size (1,) are returned as scalar values.
  189.     """
  190.     argNames = ('name','size','arrayType' )
  191.     indexLookups = [ ('outIndex','name', 'cArgIndex' ), ]
  192.     __slots__ = ('index','size','arrayType')
  193.     def __call__( self, pyArgs, index, baseOperation ):
  194.         """Return pyArgs[ self.index ]"""
  195.         return self.arrayType.zeros( self.getSize(pyArgs) )
  196.     def getSize( self, pyArgs ):
  197.         """Retrieve the array size for this argument"""
  198.         return self.size
  199.     def oldStyleReturn( self, result, baseOperation, pyArgs, cArgs ):
  200.         """Retrieve cArgs[ self.index ]"""
  201.         result = cArgs[ self.outIndex ]
  202.         thisSize = self.getSize(pyArgs)
  203.         if thisSize == (1,):
  204.             try:
  205.                 return result[0]
  206.             except TypeError, err:
  207.                 return result
  208.         else:
  209.             return result
  210.  
  211. class SizedOutput( Output ):
  212.     """Output generating dynamically-sized typed output arrays
  213.     
  214.     Takes an extra parameter "specifier", which is the name of
  215.     a Python argument to be passed to the lookup function in order
  216.     to determine the appropriate size for the output array.
  217.     """
  218.     argNames = ('name','specifier','lookup','arrayType' )
  219.     indexLookups = [ 
  220.         ('outIndex','name', 'cArgIndex' ),
  221.         ('index','specifier', 'pyArgIndex' ), 
  222.     ]
  223.     __slots__ = ('index','specifier','lookup','arrayType')
  224.     def getSize( self, pyArgs ):
  225.         """Retrieve the array size for this argument"""
  226.         try:
  227.             specifier = pyArgs[ self.index ]
  228.         except AttributeError, err:
  229.             raise RuntimeError( """"Did not resolve parameter index for %r"""%(self.name))
  230.         else:
  231.             try:
  232.                 return self.lookup( specifier )
  233.             except KeyError, err:
  234.                 raise KeyError( """Unknown specifier %s"""%( specifier ))
  235.  
  236. class StringLengths( CConverter ):
  237.     """CConverter for processing array-of-pointers-to-strings data-type
  238.     
  239.     Converter is a CConverter for the array-of-lengths for a
  240.     array-of-pointers-to-strings data-type used to pass a set
  241.     of code fragments to the GLSL compiler.
  242.     
  243.     Provides also:
  244.     
  245.         stringArray -- PyConverter callable ensuring list-of-strings 
  246.             format for the python argument
  247.             
  248.         stringArrayForC -- CResolver converting the array to 
  249.             POINTER(c_char_p) format for passing to C
  250.             
  251.         totalCount -- CConverter callable giving count of string 
  252.             pointers (that is, length of the pointer array)
  253.     """
  254.     argNames = ('name',)
  255.     indexLookups = [ ('index','name', 'pyArgIndex' ), ]
  256.     __slots__ = ()
  257.     def __call__( self, pyArgs, index, baseOperation ):
  258.         """Get array of length integers for string contents"""
  259.         from OpenGL import arrays
  260.         return arrays.GLintArray.asArray(
  261.             [len(x) for x in pyArgs[self.index]]
  262.         )
  263.     def totalCount( self, pyArgs, index, baseOperation ):
  264.         """Get array of length integers for string contents"""
  265.         return len(pyArgs[self.index])
  266.     def stringArray( self, arg, baseOperation, args ):
  267.         """Create basic array-of-strings object from pyArg"""
  268.         value = [str(x) for x in arg]
  269.         return value
  270.     def stringArrayForC( self, strings ):
  271.         """Create a ctypes pointer to char-pointer set"""
  272.         from OpenGL import arrays
  273.         result = (ctypes.c_char_p * len(strings))()
  274.         for i,s in enumerate(strings):
  275.             result[i] = arrays.GLcharARBArray.dataPointer(s)
  276.         return result
  277.  
  278.