Cache open blend files
This simplifies blend file handling, ensuring that blend files are only opened once. Otherwise it would be harder to handle things like dependency diamonds (libraries that are referenced via multiple paths through multiple other libraries).
This commit is contained in:
parent
c5a02423cb
commit
09a0866c14
@ -20,6 +20,7 @@
|
||||
# (c) 2014, Blender Foundation - Campbell Barton
|
||||
# (c) 2018, Blender Foundation - Sybren A. Stüvel
|
||||
|
||||
import atexit
|
||||
import collections
|
||||
import gzip
|
||||
import logging
|
||||
@ -27,6 +28,8 @@ import os
|
||||
import struct
|
||||
import pathlib
|
||||
import tempfile
|
||||
|
||||
import functools
|
||||
import typing
|
||||
|
||||
from . import exceptions, dna_io, dna, header
|
||||
@ -39,6 +42,29 @@ FILE_BUFFER_SIZE = 1024 * 1024
|
||||
BLENDFILE_MAGIC = b'BLENDER'
|
||||
GZIP_MAGIC = b'\x1f\x8b'
|
||||
|
||||
_cached_bfiles = {}
|
||||
|
||||
|
||||
def open_cached(path: pathlib.Path, mode='rb') -> 'BlendFile':
|
||||
"""Open a blend file, ensuring it is only opened once."""
|
||||
bfile_path = path.absolute().resolve()
|
||||
try:
|
||||
return _cached_bfiles[bfile_path]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
bfile = BlendFile(path, mode=mode)
|
||||
_cached_bfiles[bfile_path] = bfile
|
||||
return bfile
|
||||
|
||||
|
||||
@atexit.register
|
||||
def close_all_cached():
|
||||
log.info('Closing all blend files')
|
||||
for bfile in _cached_bfiles.values():
|
||||
bfile.close()
|
||||
_cached_bfiles.clear()
|
||||
|
||||
|
||||
class BlendFile:
|
||||
"""Representation of a blend file.
|
||||
|
||||
@ -23,7 +23,7 @@ def deps(bfilepath: pathlib.Path) -> typing.Iterator[result.BlockUsage]:
|
||||
:param bfilepath: File to open.
|
||||
"""
|
||||
|
||||
with blendfile.BlendFile(bfilepath) as bfile:
|
||||
bfile = blendfile.open_cached(bfilepath)
|
||||
for block in asset_holding_blocks(file2blocks.iter_blocks(bfile)):
|
||||
yield from blocks2assets.iter_assets(block)
|
||||
|
||||
|
||||
@ -86,8 +86,7 @@ class _BlockIterator:
|
||||
continue
|
||||
|
||||
log.debug('Expanding %d blocks in %s', len(idblocks), lib_path)
|
||||
|
||||
with blendfile.BlendFile(lib_path) as libfile:
|
||||
libfile = blendfile.open_cached(lib_path)
|
||||
yield from self.iter_blocks(libfile, idblocks)
|
||||
|
||||
def _queue_all_blocks(self, bfile: blendfile.BlendFile):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user