Source code for nukescripts.cache

# Copyright (c) 2009 The Foundry Visionmongers Ltd.  All Rights Reserved.

import nuke_internal as nuke
from nuke import memory2 as memory

from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QLabel

from PySide2.QtCore import Qt


[docs]def cache_clear(args = None): """ DeprecationWarning: cache_clear is deprecated. Please use the nuke.memory2 module instead. Clears the buffer memory cache by calling nuke.memory("free") If args are supplied they are passed to nuke.memory as well eg. nuke.memory( "free", args ) """ if args is not None and len(args) > 0: nuke.memory("free", args) else: nuke.memory("free")
[docs]def cache_report(args = None): """ DeprecationWarning: cache_report is deprecated. Please use the nuke.memory2 module instead. Gets info on memory by calling nuke.memory("info") If args are supplied they are passed to nuke.memory as well eg. nuke.memory( "info", args ) """ if args is not None and len(args) > 0: return nuke.memory("info", args) else: return nuke.memory("info")
[docs]def clearAllCaches(): """ Clears all caches. The disk cache, viewer playback cache and memory buffers. """ nuke.clearDiskCache() nuke.clearRAMCache() nuke.clearBlinkCache() memory.clearUsage()
[docs]def humanReadable(numBytes): """ Returns a string containing the number of bytes and the ISO/IEC units used. """ def formatBytes(numBytes, unit): return "{:.2f} {}B".format(numBytes, unit) units = (' ', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi') if numBytes < 0: return formatBytes(0, units[0]) for unit in units[:-1]: if numBytes < 1024: return formatBytes(numBytes, unit) numBytes /= 1024 return formatBytes(numBytes, units[-1])
[docs]class ValueLabel(QLabel): def __init__(self, text): QLabel.__init__(self, text) self.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
[docs]class ReportTree(QDialog): def __init__(self): from PySide2.QtWidgets import QVBoxLayout QDialog.__init__(self, parent=QApplication.activeWindow(), f=Qt.Tool) self.setWindowTitle('Buffer Report') self.resize(800, 400) layout = QVBoxLayout() self.headerLayout = self.createHeaderLayout() self.updateUsageLabels() layout.addLayout(self.headerLayout) self.tree = self.createTree() self.updateTreeContents() layout.addWidget(self.tree) layout.addWidget(self.createButtonBox()) self.setLayout(layout) def createHeaderLayout(self): from PySide2.QtWidgets import QGridLayout layout = QGridLayout() layout.addWidget(QLabel("Usage"), 0, 0) layout.addWidget(QLabel("Max Usage"), 1, 0) layout.addWidget(QLabel("Total Memory"), 2, 0) self.labels = [] total = min(memory.totalRAM(), memory.totalVM()) layout.addWidget(ValueLabel(humanReadable(total)), 2, 1) layout.setColumnStretch(3, 1) return layout def updateUsageLabels(self): if self.labels: for label in self.labels: self.headerLayout.removeWidget(label) label.hide() del label self.labels = [] self.labels.append(ValueLabel(humanReadable(memory.usage()))) self.headerLayout.addWidget(self.labels[0], 0, 1) percentage = (memory.usage() / memory.maxUsage()) * 100.0 self.labels.append(ValueLabel("{:.2f} %".format(percentage))) self.headerLayout.addWidget(self.labels[1], 0, 2) self.labels.append(ValueLabel(humanReadable(memory.maxUsage()))) self.headerLayout.addWidget(self.labels[2], 1, 1) percentage = nuke.toNode("preferences")["CacheLimit"].value() self.labels.append(ValueLabel("{:.2f} %".format(percentage))) self.headerLayout.addWidget(self.labels[3], 1, 2) def createTree(self): from PySide2.QtWidgets import QTreeWidget from PySide2.QtWidgets import QHeaderView from PySide2.QtWidgets import QAbstractItemView from PySide2.QtWidgets import QSizePolicy tree = QTreeWidget() headers = ["Name", "Size", "User", "Data"] tree.setColumnCount(len(headers)) tree.setHeaderLabels(headers) tree.header().setSectionResizeMode(QHeaderView.Fixed) tree.setSelectionBehavior(QAbstractItemView.SelectRows) tree.setAlternatingRowColors(True) tree.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) return tree def updateTreeContents(self): from PySide2.QtWidgets import QTreeWidgetItem from operator import itemgetter def sumTotalBytes(items): return sum([item["bytes"] for item in items]) self.info = memory.info() info = list(self.info.items()) info.sort(key=lambda x: sumTotalBytes(x[1]), reverse=True) for name, items in info: branch = QTreeWidgetItem(self.tree) branch.setText(0, name) branch.setText(1, humanReadable(sumTotalBytes(items))) branch.setTextAlignment(1, Qt.AlignRight | Qt.AlignVCenter) items.sort(key=itemgetter("bytes"), reverse=True) for item in items: stem = QTreeWidgetItem(branch) stem.setText(0, item["name"]) stem.setText(1, humanReadable(item["bytes"])) stem.setTextAlignment(1, Qt.AlignRight | Qt.AlignVCenter) for user, data in item.items(): if user == "name" or user == "bytes": continue leaf = QTreeWidgetItem(stem) leaf.setText(2, user) leaf.setText(3, data) self.expandTree() for i in range(self.tree.columnCount()): self.tree.resizeColumnToContents(i) self.collapseTree() def createButtonBox(self): from PySide2.QtWidgets import QDialogButtonBox buttonBox = QDialogButtonBox() def addButton(name, function, tip=None): from PySide2.QtWidgets import QPushButton button = QPushButton(name) button.clicked.connect(function) if tip: button.setToolTip(tip) buttonBox.addButton(button, QDialogButtonBox.ActionRole) addButton("Expand All", self.expandTree) addButton("Collapse All", self.collapseTree) addButton("Update", self.updateContents) addButton("Save", self.save, "Saves the memory info structure to a Json file.") return buttonBox def expandTree(self): self.expand(True) def collapseTree(self): self.expand(False) def __recursiveExpand(self, item, expand): for i in range(item.childCount()): child = item.child(i) self.__recursiveExpand(child, expand) item.setExpanded(expand) def expand(self, expand): for i in range(self.tree.topLevelItemCount()): item = self.tree.topLevelItem(i) self.__recursiveExpand(item, expand) def updateContents(self): self.updateUsageLabels() self.tree.clear() self.updateTreeContents() def save(self): from PySide2.QtWidgets import QFileDialog from json import dump path = QFileDialog.getSaveFileName( parent=self, caption="Save as", filter="Json (*.json)") if path is None: return dump(self.info, open(path[0], 'w'), indent=2)
[docs]def showReportDialog(): """ Creates a tree containing memory information from tracked allocations. """ for widget in QApplication.topLevelWidgets(): if isinstance(widget, ReportTree): widget.updateContents() widget.show() widget.windowHandle().requestActivate() return dialog = ReportTree() dialog.show()