annotate blender/time_sync/time_from_graph.py @ 2455:2d454737a916

split blender code to new file
author drewp@bigasterisk.com
date Tue, 20 May 2025 09:24:35 -0700
parents 405abed9a45c
children d94480bfb179
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
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
12 from light9.namespaces import L9
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
13 from light9.newtypes import decimalLiteral
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
14 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
15 from light9.typedgraph import typedValue
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
16
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
17 from ..asyncio_thread import startLoopInThread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
18 from .blender_time import (
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
19 BlenderTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
20 PausedGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
21 PlayingGotoTime,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
22 SceneLoaded,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
23 _TimeEvent,
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
24 )
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
25
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
26
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
27
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
28
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
29
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
30 class Sync:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
31 """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
32 lock = threading.Lock()
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
33
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
34 # these are written ONLY by bg thread
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
35 duration: float = 1
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
36 wallStartTime: float | None = None
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
37 pausedSongTime: float | None = None
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
38 latestSongTime: float
2433
ffa69645e9dc refactor
drewp@bigasterisk.com
parents: 2432
diff changeset
39 playing = False
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
40
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
41 def __init__(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
42 # main thread
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
43 self.blenderTime = BlenderTime(self.onEvent)
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
44 self.blenderTime.start()
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
45
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
46 self.ctx = ascoltamiContext(showconfig.showUri())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
47 log.debug('🚋3 startLoopInThread')
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
48 self._loop = startLoopInThread(self.connectGraph())
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
49 log.info('🚋10 Sync initd')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
50
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
51 def onEvent(self, event: _TimeEvent):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
52 # main thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
53 match event:
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
54 case SceneLoaded():
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
55 if hasattr(self, "latestSongTime"):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
56 self.blenderTime.setBlenderTime(self.latestSongTime, self.duration)
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
57 case PausedGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
58 self.runInBackgroundLoop(self.setInGraph(t, False))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
59 case PlayingGotoTime(t):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
60 self.runInBackgroundLoop(self.setInGraph(t, True))
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
61
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
62 def runInBackgroundLoop(self, f: Coroutine):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
63 # main thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
64 asyncio.run_coroutine_threadsafe(f, self._loop)
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
65
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
66 async def connectGraph(self):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
67 # bg thread
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
68 log.info('🚋11 start SyncedGraph')
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
69 self.graph = SyncedGraph(networking.rdfdb.url, "time_sync")
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
70 self.graph.addHandler(self.syncFromGraph)
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
71
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
72 def syncFromGraph(self):
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
73 # bg thread
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
74 with self.lock:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
75 asco = L9['ascoltami']
2433
ffa69645e9dc refactor
drewp@bigasterisk.com
parents: 2432
diff changeset
76 self.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime'])
ffa69645e9dc refactor
drewp@bigasterisk.com
parents: 2432
diff changeset
77 self.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime'])
ffa69645e9dc refactor
drewp@bigasterisk.com
parents: 2432
diff changeset
78 self.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0
2436
e683b449506b blender effect that sets lights to match blender lights
drewp@bigasterisk.com
parents: 2434
diff changeset
79 self.playing = typedValue(bool | None, self.graph, asco, L9['playing']) or False
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
80
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
81 def currentTime(self) -> float | None:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
82 if self.wallStartTime is not None:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
83 return time.time() - self.wallStartTime
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
84 if self.pausedSongTime is not None:
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
85 return self.pausedSongTime
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
86 log.warn('no time data')
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
87 return None
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
88
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
89 async def setGraphPlaying(self, isBlenderPlaying: bool):
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
90 # bg thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
91 log.info(f'set graph playing to {isBlenderPlaying}')
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
92 self.graph.patchObject(self.ctx, L9['ascoltami'], L9['playing'], Literal(isBlenderPlaying))
2432
b8a408caf115 start blender sync
drewp@bigasterisk.com
parents:
diff changeset
93
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
94 async def setInGraph(self, t: float, isBlenderPlaying: bool):
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
95 # bg thread
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
96 log.info(f'set graph time to {t:.2f} {isBlenderPlaying=}')
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
97 p = Patch()
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
98 if isBlenderPlaying:
2455
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['playing'], Literal(True)))
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
100 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
101 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
102 else:
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
103 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
104 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
105 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
106
2455
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
107 if p.isEmpty():
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
108 return
2d454737a916 split blender code to new file
drewp@bigasterisk.com
parents: 2454
diff changeset
109 log.info(f'setInGraph {p.shortSummary()}')
2454
405abed9a45c fix up asyncio-in-bg-thread sorcery
drewp@bigasterisk.com
parents: 2453
diff changeset
110 await self.graph.patch(p)