def test_CacheContextLifetime(self): # Check that python object lifetimes are preserved as expected, to ensure # that the C++ objects they refer to do not expire prematurely. import weakref # Create a cache and a weak reference to it. cache = Usd.StageCache() weakCache = weakref.ref(cache) # Create a nonpopulating wrapper around the cache, and a weakref to it. nonPop = Usd.UseButDoNotPopulateCache(cache) weakNonPop = weakref.ref(nonPop) # del our local name 'cache'. The rw object should keep it alive. del cache assert weakCache() # Create a CacheContext. ctx = Usd.StageCacheContext(nonPop) # del our local name 'rw'. The ctx object should keep it alive (and # transitively, the cache object). del nonPop assert weakNonPop() assert weakCache() # Try populating into the cache, for fun. with ctx: stage = Usd.Stage.Open(Sdf.Layer.CreateAnonymous()) assert weakNonPop() assert weakCache() assert not weakCache().Contains(stage) # nonpopulating cache usage. # Killing our ctx reference should let the objects expire. del ctx assert weakNonPop() is None assert weakCache() is None # Now try again with a context on the cache directly. cache = Usd.StageCache() weakCache = weakref.ref(cache) ctx = Usd.StageCacheContext(cache) del cache assert weakCache() with ctx: stage = Usd.Stage.Open(Sdf.Layer.CreateAnonymous()) assert weakCache() assert weakCache().Contains(stage) # this ctx will populate. # Killing ctx should let the cache expire. del ctx assert weakCache() is None
def test_CacheContext(self): layer1 = Sdf.Layer.CreateAnonymous() layer2 = Sdf.Layer.CreateAnonymous() cache1 = Usd.StageCache() # Populate cache1 with a stage, by binding a context and using the # Stage.Open API. with Usd.StageCacheContext(cache1): stage = Usd.Stage.Open(layer1) assert cache1.Size() == 1 assert cache1.Contains(stage) assert cache1.FindOneMatching(layer1) == stage # Read the stage from the read-only cache, assert a different opened stage # doesn't populate the cache. with Usd.StageCacheContext(Usd.UseButDoNotPopulateCache(cache1)): stageAgain = Usd.Stage.Open(layer1) newStage = Usd.Stage.Open(layer2) assert stageAgain is stage assert newStage assert not cache1.Contains(newStage) # Create a new cache, make a context for both, and check that a newly # created stage publishes to both caches. cache1.Clear() cache2 = Usd.StageCache() with Usd.StageCacheContext(cache1): with Usd.StageCacheContext(cache2): newStage = Usd.Stage.Open(layer2) assert cache1.Contains(newStage) assert cache2.Contains(newStage) # Publish a stage with a specific session layer to a cache, then check that # a call to Stage.Open() that doesn't specify a session layer finds that # layer in the cache, but that a call to Stage.Open() that demands no # session layer finds no layer in the cache. cache1.Clear() with Usd.StageCacheContext(cache1): newStage = Usd.Stage.Open(layer1, layer2) newStage2 = Usd.Stage.Open(layer1) assert newStage is newStage2 newStage3 = Usd.Stage.Open(layer1, sessionLayer=None) assert newStage3 != newStage # Verify that blocking caches works as expected. cache1.Clear() with Usd.StageCacheContext(cache1): # Populate a stage into the cache. newStage = Usd.Stage.Open(layer1) assert cache1.Contains(newStage) with Usd.StageCacheContext(Usd.BlockStageCaches): # Open() should create a new stage, since cache is blocked. newStage2 = Usd.Stage.Open(layer1) assert newStage2 != newStage assert cache1.Size() == 1 # Opening a different stage should not populate the cache. newStage3 = Usd.Stage.Open(layer2) assert not cache1.Contains(newStage3) assert cache1.Size() == 1 # Try blocking cache writes only. cache1.Clear() with Usd.StageCacheContext(cache1): # Populate a stage into the cache. newStage = Usd.Stage.Open(layer1) assert cache1.Contains(newStage) with Usd.StageCacheContext(Usd.BlockStageCachePopulation): # Open() should read the stage from the cache. newStage2 = Usd.Stage.Open(layer1) assert newStage2 == newStage # Opening a different stage should not populate the cache. newStage3 = Usd.Stage.Open(layer2) assert not cache1.Contains(newStage3) assert cache1.Size() == 1