SyntheticMDProductions's picture
ADAM October 2026 source release: PixelRow, INRFlow, Wan Video, Oasis player and field guide
f8c73f9 verified
Raw History Blame Contribute Delete
2.84 kB
"""Share one background model scan between workspaces without racing job writes."""
from __future__ import annotations
from copy import deepcopy
from dataclasses import asdict
from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QApplication
from adam.assets import AssetRegistry
from adam.ui.background import BackgroundRead
class AssetRefresh(QObject):
changed = Signal()
def __init__(self, assets: AssetRegistry, config) -> None:
super().__init__(QApplication.instance())
self.assets = assets
self.config = config
self._folders = None
self.reader = BackgroundRead(self)
self.reader.ready.connect(self._merge)
def request(self, *, force: bool = False) -> None:
folders = deepcopy(self.config.get("tool_folders", {}))
if self._folders is not None and folders != self._folders:
force = True
self._folders = folders
# Copy only data, not the attached Qt service. Discovery never writes
# the registry from a worker or mutates objects used by active jobs.
snapshot = object.__new__(AssetRegistry)
snapshot.path = self.assets.path
snapshot.assets = deepcopy(self.assets.assets)
baseline = {item.id: asdict(item) for item in snapshot.assets}
settings = deepcopy(self.config.settings)
def read():
snapshot.discover(settings, persist=False)
return baseline, snapshot.assets
self.reader.request(read, force=force)
def _merge(self, result) -> None:
baseline, discovered = result
current = {item.id: item for item in self.assets.assets}
paths = {(item.kind, item.path) for item in current.values()}
merged = []
for item in discovered:
existing = current.get(item.id)
if item.id in baseline:
if existing is None:
continue # The user removed it while discovery was running.
merged.append(existing if asdict(existing) != baseline[item.id] else item)
elif (item.kind, item.path) not in paths:
merged.append(item)
retained = {item.id for item in merged}
for item in current.values():
if item.id not in retained and (item.id not in baseline or asdict(item) != baseline[item.id]):
merged.append(item)
if [asdict(item) for item in merged] != [asdict(item) for item in self.assets.assets]:
self.assets.assets = merged
self.assets.save()
self.changed.emit()
def asset_refresh(assets: AssetRegistry, config) -> AssetRefresh:
service = getattr(assets, "_ui_refresh", None)
if service is None:
service = AssetRefresh(assets, config)
assets._ui_refresh = service
return service