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 / contextdata.py < prev    next >
Encoding:
Python Source  |  2008-12-07  |  3.8 KB  |  124 lines

  1. """Storage of per-context values of various types
  2.  
  3. Because OpenGL needs persistent references to the
  4. objects we're constructing to shadow Python objects,
  5. we have to store references to the objects somewhere
  6.  
  7. For any given Python GUI library, we can use a weakref
  8. to the library's representation of the GL context to 
  9. call the cleanup function.  That means some per-GUI 
  10. library code in OpenGL (or the library), but it gives 
  11. us very natural operations within OpenGL.
  12. """
  13. from OpenGL import platform
  14. storedPointers = {
  15.     # map from contextID: { constant: value }
  16. }
  17. storedWeakPointers = {
  18.     # map from contextID: WeakValueDictionary({ constant: value })
  19. }
  20. STORAGES = [ storedPointers, storedWeakPointers ]
  21.  
  22. def getContext( context = None ):
  23.     """Get the context (if passed, just return)
  24.     
  25.     context -- the context ID, if None, the current context
  26.     """
  27.     if context is None:
  28.         context = platform.GetCurrentContext()
  29.         if context == 0:
  30.             from OpenGL import error
  31.             raise error.Error(
  32.                 """Attempt to retrieve context when no valid context"""
  33.             )
  34.     return context
  35. def setValue( constant, value, context=None, weak=False ):
  36.     """Set a stored value for the given context
  37.     
  38.     constant -- Normally a GL constant value, but can be any hashable value 
  39.     value -- the value to be stored.  If weak is true must be 
  40.         weak-reference-able.  If None, then the value will be deleted from 
  41.         the storage 
  42.     context -- the context identifier for which we're storing the value
  43.     weak -- if true, value will be stored with a weakref
  44.         Note: you should always pass the same value for "weak" for a given 
  45.         constant, otherwise you will create two storages for the constant.
  46.     """
  47.     if getattr( value, '_no_cache_', False ):
  48.         return 
  49.     context = getContext( context )
  50.     if weak:
  51.         storage = storedWeakPointers
  52.         cls = weakref.WeakValueDictionary
  53.     else:
  54.         storage = storedPointers
  55.         cls = dict
  56.     current = storage.get( context )
  57.     if current is None:
  58.         storage[context] = current = cls()
  59.     previous = current.get( constant )
  60.     if value is None:
  61.         try:
  62.             del current[ constant ]
  63.         except (KeyError,TypeError,ValueError), err:
  64.             pass 
  65.     else:
  66.         # XXX potential for failure here if a non-weakref-able objects
  67.         # is being stored with weak == True
  68.         current[ constant ] = value 
  69. ##    print 'previous', previous, value, constant
  70.     return previous
  71. def delValue( constant, context=None ):
  72.     """Delete the specified value for the given context
  73.     
  74.     constant -- Normally a GL constant value, but can be any hashable value 
  75.     context -- the context identifier for which we're storing the value
  76.     """
  77.     context = getContext( context )
  78.     found = False
  79.     for storage in STORAGES:
  80.         contextStorage = storage.get( context  )
  81.         if contextStorage:
  82.             try:
  83.                 del contextStorage[ constant ]
  84.                 found = True
  85.             except KeyError, err:
  86.                 pass
  87.     return found
  88.  
  89. def getValue( constant, context = None ):
  90.     """Get a stored value for the given constant
  91.     
  92.     constant -- unique ID for the type of data being retrieved
  93.     context -- the context ID, if None, the current context
  94.     """
  95.     context = getContext( context )
  96.     for storage in STORAGES:
  97.         contextStorage = storage.get( context  )
  98.         if contextStorage:
  99.             value =  contextStorage.get( constant )
  100.             if value is not None:
  101.                 return value
  102.     return None
  103.  
  104. def cleanupContext( context=None ):
  105.     """Cleanup all held pointer objects for the given context
  106.     
  107.     Warning: this is dangerous, as if you call it before a context 
  108.     is destroyed you may release memory held by the context and cause
  109.     a protection fault when the GL goes to render the scene!
  110.     
  111.     Normally you will want to get the context ID explicitly and then 
  112.     register cleanupContext as a weakref callback to your GUI library 
  113.     Context object with the (now invalid) context ID as parameter.
  114.     """
  115.     if context is None:
  116.         context = platform.GetCurrentContext()
  117.     for storage in STORAGES:
  118.         try:
  119.             del storedPointers[ context ]
  120.         except KeyError, err:
  121.             return False
  122.         else:
  123.             return True
  124.