Mercurial > code > home > repos > light9
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 |
rev | line source |
---|---|
2454 | 1 import asyncio |
2432 | 2 import threading |
3 import time | |
2455 | 4 from typing import Coroutine |
2432 | 5 |
2455 | 6 from rdfdb.patch import Patch |
2432 | 7 from rdfdb.syncedgraph.syncedgraph import SyncedGraph |
2455 | 8 from rdflib import Literal |
2432 | 9 |
2454 | 10 from light9 import networking, showconfig |
2455 | 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 | 13 from light9.namespaces import L9 |
2454 | 14 from light9.newtypes import decimalLiteral |
2432 | 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 | 17 |
2455 | 18 from ..asyncio_thread import startLoopInThread |
19 from .blender_time import ( | |
20 BlenderTime, | |
21 PausedGotoTime, | |
22 PlayingGotoTime, | |
23 SceneLoaded, | |
24 _TimeEvent, | |
25 ) | |
2432 | 26 |
27 | |
28 class Sync: | |
2455 | 29 """asco is the authority on playback status. Sync maintains a copy of the state""" |
2432 | 30 lock = threading.Lock() |
2455 | 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 | 34 |
35 def __init__(self): | |
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 | 41 self.blenderTime.start() |
42 | |
43 self.ctx = ascoltamiContext(showconfig.showUri()) | |
2454 | 44 log.debug('🚋3 startLoopInThread') |
2455 | 45 self._loop = startLoopInThread(self.connectGraph()) |
2454 | 46 log.info('🚋10 Sync initd') |
2432 | 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 | 49 # main thread |
50 match event: | |
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 | 54 case PausedGotoTime(t): |
55 self.runInBackgroundLoop(self.setInGraph(t, False)) | |
56 case PlayingGotoTime(t): | |
57 self.runInBackgroundLoop(self.setInGraph(t, True)) | |
2432 | 58 |
2454 | 59 def runInBackgroundLoop(self, f: Coroutine): |
2455 | 60 # main thread |
2454 | 61 asyncio.run_coroutine_threadsafe(f, self._loop) |
62 | |
2455 | 63 async def connectGraph(self): |
64 # bg thread | |
2454 | 65 log.info('🚋11 start SyncedGraph') |
2432 | 66 self.graph = SyncedGraph(networking.rdfdb.url, "time_sync") |
67 self.graph.addHandler(self.syncFromGraph) | |
68 | |
69 def syncFromGraph(self): | |
70 # bg thread | |
71 with self.lock: | |
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 | 82 |
2454 | 83 async def setInGraph(self, t: float, isBlenderPlaying: bool): |
2455 | 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 | 86 p = Patch() |
2454 | 87 if isBlenderPlaying: |
2455 | 88 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(True))) |
89 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], decimalLiteral(round(time.time() - t, 1)))) | |
90 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], None)) | |
2454 | 91 else: |
2455 | 92 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(False))) |
93 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], None)) | |
94 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], decimalLiteral(round(t, 1)))) | |
2454 | 95 |
2455 | 96 if p.isEmpty(): |
97 return | |
2454 | 98 await self.graph.patch(p) |