annotate blender/time_sync/time_from_graph.py @ 2457:d94480bfb179

more work on blender time sync. Might be working, aside from blender play-button
author drewp@bigasterisk.com
date Tue, 20 May 2025 13:48:07 -0700
parents 2d454737a916
children 0e27ba33118c
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
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
6 from attr import dataclass
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
7 from rdfdb.patch import Patch
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
8 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
9 from rdflib import Literal
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
10
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
11 from light9 import networking, showconfig
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
12 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
13 from light9.ascoltami.play_state import AscoPlayState
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
14 from light9.namespaces import L9
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
15 from light9.newtypes import decimalLiteral
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
16 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
17 from light9.typedgraph import typedValue
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
18
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
19 from ..asyncio_thread import startLoopInThread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
20 from .blender_time import (
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
21 BlenderTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
22 PausedGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
23 PlayingGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
24 SceneLoaded,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
25 _TimeEvent,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
26 )
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
27
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
28
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
29 class Sync:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
30 """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
31 lock = threading.Lock()
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
32
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
33 # 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
34 ascoPlayState: AscoPlayState
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
35
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
36 def __init__(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
37 # main thread
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
38 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
39 self.blenderTime = BlenderTime(self.onBlenderEvent, self.ascoPlayState)
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
40 self.blenderTime.start()
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
41
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
42 self.ctx = ascoltamiContext(showconfig.showUri())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
43 log.debug('🚋3 startLoopInThread')
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
44 self._loop = startLoopInThread(self.connectGraph())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
45 log.info('🚋10 Sync initd')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
46
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
47 def onBlenderEvent(self, event: _TimeEvent):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
48 # main thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
49 match event:
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
50 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
51 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
52 self.blenderTime.setCurrentTime(self.ascoPlayState.getCurrentSongTime() or 0.0)
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
53 case PausedGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
54 self.runInBackgroundLoop(self.setInGraph(t, False))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
55 case PlayingGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
56 self.runInBackgroundLoop(self.setInGraph(t, True))
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
57
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
58 def runInBackgroundLoop(self, f: Coroutine):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
59 # main thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
60 asyncio.run_coroutine_threadsafe(f, self._loop)
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
61
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
62 async def connectGraph(self):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
63 # bg thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
64 log.info('🚋11 start SyncedGraph')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
65 self.graph = SyncedGraph(networking.rdfdb.url, "time_sync")
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
66 self.graph.addHandler(self.syncFromGraph)
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
67
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
68 def syncFromGraph(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
69 # bg thread
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
70 with self.lock:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
71 asco = L9['ascoltami']
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
72
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
73 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
74 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
75 self.ascoPlayState.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
76 self.blenderTime.durationDirty = True # todo: called too often
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
77 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
78 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
79 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
80 self.blenderTime.curFrameDirty = True
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
81
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
82 async def setGraphPlaying(self, isBlenderPlaying: bool):
2457
d94480bfb179 more work on blender time sync. Might be working, aside from blender play-button
drewp@bigasterisk.com
parents: 2455
diff changeset
83 return
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
84 # bg thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
85 log.info(f'set graph playing to {isBlenderPlaying}')
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
86 self.graph.patchObject(self.ctx, L9['ascoltami'], L9['playing'], Literal(isBlenderPlaying))
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
87
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
88 async def setInGraph(self, t: float, isBlenderPlaying: bool):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
89 # bg thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
90 log.info(f'set graph time to {t:.2f} {isBlenderPlaying=}')
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
91 p = Patch()
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
92 if isBlenderPlaying:
2455
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['playing'], Literal(True)))
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['wallStartTime'], decimalLiteral(round(time.time() - t, 1))))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
95 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
96 else:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
97 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
98 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
99 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
100
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
101 if p.isEmpty():
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
102 return
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
103 log.info(f'setInGraph {p.shortSummary()}')
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
104 await self.graph.patch(p)