annotate blender/time_sync/time_from_graph.py @ 2458:0e27ba33118c default tip

better blender<->asco playback cooperation. still no play support in blender; only seek
author drewp@bigasterisk.com
date Tue, 20 May 2025 16:25:06 -0700
parents d94480bfb179
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
1 import asyncio
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
2 import threading
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
3 import time
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
4 from typing import Coroutine
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
5
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
6 from rdfdb.patch import Patch
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
7 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
8 from rdflib import Literal
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
9
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
10 from light9 import networking, showconfig
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
11 from light9.ascoltami.graph_context import ascoltamiContext
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
12 from light9.ascoltami.play_state import AscoPlayState
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
13 from light9.namespaces import L9
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
14 from light9.newtypes import decimalLiteral
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
15 from light9.run_local import log
2453
b23afde50bc2 blender addons get thier own pdm setup for now. fix time_from_graph startup race
drewp@bigasterisk.com
parents: 2436
diff changeset
16 from light9.typedgraph import typedValue
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
17
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
18 from ..asyncio_thread import startLoopInThread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
19 from .blender_time import (
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
20 BlenderTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
21 PausedGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
22 PlayingGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
23 SceneLoaded,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
24 _TimeEvent,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
25 )
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
26
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
27
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
28 class Sync:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
29 """asco is the authority on playback status. Sync maintains a copy of the state"""
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
30 lock = threading.Lock()
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
31
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
32 # this is edited ONLY by bg thread
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
33 ascoPlayState: AscoPlayState
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
34
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
35 def __init__(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
36 # main thread
2458
0e27ba33118c better blender<->asco playback cooperation. still no play support in blender; only seek
drewp@bigasterisk.com
parents: 2457
diff changeset
37
0e27ba33118c better blender<->asco playback cooperation. still no play support in blender; only seek
drewp@bigasterisk.com
parents: 2457
diff changeset
38 # one mutable instance; modified by bg thread
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
39 self.ascoPlayState = AscoPlayState(None, None, False, False, 1.0)
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
40 self.blenderTime = BlenderTime(self.onBlenderEvent, self.ascoPlayState)
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
41 self.blenderTime.start()
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
42
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
43 self.ctx = ascoltamiContext(showconfig.showUri())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
44 log.debug('🚋3 startLoopInThread')
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
45 self._loop = startLoopInThread(self.connectGraph())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
46 log.info('🚋10 Sync initd')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
47
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
48 def onBlenderEvent(self, event: _TimeEvent):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
49 # main thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
50 match event:
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
51 case SceneLoaded():
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
52 self.blenderTime.setRange(self.ascoPlayState.duration)
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
53 self.blenderTime.setCurrentTime(self.ascoPlayState.getCurrentSongTime() or 0.0)
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
54 case PausedGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
55 self.runInBackgroundLoop(self.setInGraph(t, False))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
56 case PlayingGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
57 self.runInBackgroundLoop(self.setInGraph(t, True))
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
58
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
59 def runInBackgroundLoop(self, f: Coroutine):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
60 # main thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
61 asyncio.run_coroutine_threadsafe(f, self._loop)
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
62
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
63 async def connectGraph(self):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
64 # bg thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
65 log.info('🚋11 start SyncedGraph')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
66 self.graph = SyncedGraph(networking.rdfdb.url, "time_sync")
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
67 self.graph.addHandler(self.syncFromGraph)
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
68
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
69 def syncFromGraph(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
70 # bg thread
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
71 with self.lock:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
72 asco = L9['ascoltami']
2458
0e27ba33118c better blender<->asco playback cooperation. still no play support in blender; only seek
drewp@bigasterisk.com
parents: 2457
diff changeset
73
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
74 self.ascoPlayState.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime'])
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
75 self.ascoPlayState.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime'])
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
76 self.ascoPlayState.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0
2458
0e27ba33118c better blender<->asco playback cooperation. still no play support in blender; only seek
drewp@bigasterisk.com
parents: 2457
diff changeset
77 self.blenderTime.durationDirty = True # todo: called too often
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
78 self.ascoPlayState.playing = typedValue(bool | None, self.graph, asco, L9['playing']) or False
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
79 self.ascoPlayState.endOfSong = typedValue(bool | None, self.graph, asco, L9['endOfSong']) or False
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
80 log.info(f'🍇 syncFromGraph {self.ascoPlayState=}')
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
81 self.blenderTime.curFrameDirty = True
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
82
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
83 async def setInGraph(self, t: float, isBlenderPlaying: bool):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
84 # bg thread
2458
0e27ba33118c better blender<->asco playback cooperation. still no play support in blender; only seek
drewp@bigasterisk.com
parents: 2457
diff changeset
85 log.debug(f'set graph time to {t:.2f} {isBlenderPlaying=}')
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
86 p = Patch()
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
87 if isBlenderPlaying:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
88 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(True)))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
89 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], decimalLiteral(round(time.time() - t, 1))))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
90 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], None))
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
91 else:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
92 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(False)))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
93 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], None))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
94 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], decimalLiteral(round(t, 1))))
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
95
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
96 if p.isEmpty():
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
97 return
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
98 await self.graph.patch(p)