home *** CD-ROM | disk | FTP | other *** search
- """Storage of per-context values of various types
-
- Because OpenGL needs persistent references to the
- objects we're constructing to shadow Python objects,
- we have to store references to the objects somewhere
-
- For any given Python GUI library, we can use a weakref
- to the library's representation of the GL context to
- call the cleanup function. That means some per-GUI
- library code in OpenGL (or the library), but it gives
- us very natural operations within OpenGL.
- """
- from OpenGL import platform
- storedPointers = {
- # map from contextID: { constant: value }
- }
- storedWeakPointers = {
- # map from contextID: WeakValueDictionary({ constant: value })
- }
- STORAGES = [ storedPointers, storedWeakPointers ]
-
- def getContext( context = None ):
- """Get the context (if passed, just return)
-
- context -- the context ID, if None, the current context
- """
- if context is None:
- context = platform.GetCurrentContext()
- if context == 0:
- from OpenGL import error
- raise error.Error(
- """Attempt to retrieve context when no valid context"""
- )
- return context
- def setValue( constant, value, context=None, weak=False ):
- """Set a stored value for the given context
-
- constant -- Normally a GL constant value, but can be any hashable value
- value -- the value to be stored. If weak is true must be
- weak-reference-able. If None, then the value will be deleted from
- the storage
- context -- the context identifier for which we're storing the value
- weak -- if true, value will be stored with a weakref
- Note: you should always pass the same value for "weak" for a given
- constant, otherwise you will create two storages for the constant.
- """
- if getattr( value, '_no_cache_', False ):
- return
- context = getContext( context )
- if weak:
- storage = storedWeakPointers
- cls = weakref.WeakValueDictionary
- else:
- storage = storedPointers
- cls = dict
- current = storage.get( context )
- if current is None:
- storage[context] = current = cls()
- previous = current.get( constant )
- if value is None:
- try:
- del current[ constant ]
- except (KeyError,TypeError,ValueError), err:
- pass
- else:
- # XXX potential for failure here if a non-weakref-able objects
- # is being stored with weak == True
- current[ constant ] = value
- ## print 'previous', previous, value, constant
- return previous
- def delValue( constant, context=None ):
- """Delete the specified value for the given context
-
- constant -- Normally a GL constant value, but can be any hashable value
- context -- the context identifier for which we're storing the value
- """
- context = getContext( context )
- found = False
- for storage in STORAGES:
- contextStorage = storage.get( context )
- if contextStorage:
- try:
- del contextStorage[ constant ]
- found = True
- except KeyError, err:
- pass
- return found
-
- def getValue( constant, context = None ):
- """Get a stored value for the given constant
-
- constant -- unique ID for the type of data being retrieved
- context -- the context ID, if None, the current context
- """
- context = getContext( context )
- for storage in STORAGES:
- contextStorage = storage.get( context )
- if contextStorage:
- value = contextStorage.get( constant )
- if value is not None:
- return value
- return None
-
- def cleanupContext( context=None ):
- """Cleanup all held pointer objects for the given context
-
- Warning: this is dangerous, as if you call it before a context
- is destroyed you may release memory held by the context and cause
- a protection fault when the GL goes to render the scene!
-
- Normally you will want to get the context ID explicitly and then
- register cleanupContext as a weakref callback to your GUI library
- Context object with the (now invalid) context ID as parameter.
- """
- if context is None:
- context = platform.GetCurrentContext()
- for storage in STORAGES:
- try:
- del storedPointers[ context ]
- except KeyError, err:
- return False
- else:
- return True
-