Mercurial > code > home > repos > light9
diff blender/time_sync/time_from_graph.py @ 2454:405abed9a45c
fix up asyncio-in-bg-thread sorcery
author | drewp@bigasterisk.com |
---|---|
date | Mon, 19 May 2025 21:25:32 -0700 |
parents | b23afde50bc2 |
children | 2d454737a916 |
line wrap: on
line diff
--- a/blender/time_sync/time_from_graph.py Sun May 18 20:08:35 2025 -0700 +++ b/blender/time_sync/time_from_graph.py Mon May 19 21:25:32 2025 -0700 @@ -1,13 +1,18 @@ +import asyncio import threading import time +from typing import Coroutine, cast import bpy # type: ignore from bpy.app.handlers import persistent # type: ignore -from light9_sync.asyncio_thread import startLoopInThread +from ..asyncio_thread import startLoopInThread from rdfdb.syncedgraph.syncedgraph import SyncedGraph +from rdflib import URIRef +from rdflib.graph import _ContextType -from light9 import networking +from light9 import networking, showconfig from light9.namespaces import L9 +from light9.newtypes import decimalLiteral from light9.run_local import log from light9.typedgraph import typedValue @@ -31,16 +36,26 @@ # main thread self.lastSetFrame = -1 self.lastGraphFrame = -1 - startLoopInThread(self.task()) + show = showconfig.showUri() + self.ctx = cast(_ContextType, (URIRef(show + '/ascoltami'))) + log.debug('🚋3 startLoopInThread') + self._loop = startLoopInThread(self.task()) + # need persistent because `blender --addons ...` seems to start addon # before loading scene. bpy.app.timers.register(self.update, persistent=True) bpy.app.handlers.frame_change_post.append(self.on_frame_change_post) + log.info('🚋10 Sync initd') ## updates from graph -> self + def runInBackgroundLoop(self, f: Coroutine): + asyncio.run_coroutine_threadsafe(f, self._loop) + + async def task(self): # bg thread with asyncio loop + log.info('🚋11 start SyncedGraph') self.graph = SyncedGraph(networking.rdfdb.url, "time_sync") self.graph.addHandler(self.syncFromGraph) @@ -63,7 +78,7 @@ ## graph time -> blender time - # @persistent + @persistent def update(self): # main thread? wherever blender runs timers if self.playing: @@ -90,7 +105,15 @@ # self.setGraphTime(scene.frame_current / scene.render.fps, self.duration) self.lastSetFrame = scene.frame_current t = scene.frame_current / scene.render.fps - self.setInGraph(t) + self.runInBackgroundLoop(self.setInGraph(t, bpy.context.screen.is_animation_playing)) - def setInGraph(self, t: float): - log.warning(f'todo: set graph to {t:.2f}') + async def setInGraph(self, t: float, isBlenderPlaying: bool): + log.info(f'set graph time to {t:.2f}') + if isBlenderPlaying: + log.info(' playing mode') + p = self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], decimalLiteral(t)) + else: + log.info(' paused mode') + p = self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], decimalLiteral(t)) + + await self.graph.patch(p)