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)