comparison 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
comparison
equal deleted inserted replaced
2457:d94480bfb179 2458:0e27ba33118c
1 import asyncio 1 import asyncio
2 import threading 2 import threading
3 import time 3 import time
4 from typing import Coroutine 4 from typing import Coroutine
5 5
6 from attr import dataclass
7 from rdfdb.patch import Patch 6 from rdfdb.patch import Patch
8 from rdfdb.syncedgraph.syncedgraph import SyncedGraph 7 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
9 from rdflib import Literal 8 from rdflib import Literal
10 9
11 from light9 import networking, showconfig 10 from light9 import networking, showconfig
33 # this is edited ONLY by bg thread 32 # this is edited ONLY by bg thread
34 ascoPlayState: AscoPlayState 33 ascoPlayState: AscoPlayState
35 34
36 def __init__(self): 35 def __init__(self):
37 # main thread 36 # main thread
37
38 # one mutable instance; modified by bg thread
38 self.ascoPlayState = AscoPlayState(None, None, False, False, 1.0) 39 self.ascoPlayState = AscoPlayState(None, None, False, False, 1.0)
39 self.blenderTime = BlenderTime(self.onBlenderEvent, self.ascoPlayState) 40 self.blenderTime = BlenderTime(self.onBlenderEvent, self.ascoPlayState)
40 self.blenderTime.start() 41 self.blenderTime.start()
41 42
42 self.ctx = ascoltamiContext(showconfig.showUri()) 43 self.ctx = ascoltamiContext(showconfig.showUri())
67 68
68 def syncFromGraph(self): 69 def syncFromGraph(self):
69 # bg thread 70 # bg thread
70 with self.lock: 71 with self.lock:
71 asco = L9['ascoltami'] 72 asco = L9['ascoltami']
72 73
73 self.ascoPlayState.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime']) 74 self.ascoPlayState.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime'])
74 self.ascoPlayState.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime']) 75 self.ascoPlayState.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime'])
75 self.ascoPlayState.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0 76 self.ascoPlayState.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0
76 self.blenderTime.durationDirty = True # todo: called too often 77 self.blenderTime.durationDirty = True # todo: called too often
77 self.ascoPlayState.playing = typedValue(bool | None, self.graph, asco, L9['playing']) or False 78 self.ascoPlayState.playing = typedValue(bool | None, self.graph, asco, L9['playing']) or False
78 self.ascoPlayState.endOfSong = typedValue(bool | None, self.graph, asco, L9['endOfSong']) or False 79 self.ascoPlayState.endOfSong = typedValue(bool | None, self.graph, asco, L9['endOfSong']) or False
79 log.info(f'🍇 syncFromGraph {self.ascoPlayState=}') 80 log.info(f'🍇 syncFromGraph {self.ascoPlayState=}')
80 self.blenderTime.curFrameDirty = True 81 self.blenderTime.curFrameDirty = True
81 82
82 async def setGraphPlaying(self, isBlenderPlaying: bool):
83 return
84 # bg thread
85 log.info(f'set graph playing to {isBlenderPlaying}')
86 self.graph.patchObject(self.ctx, L9['ascoltami'], L9['playing'], Literal(isBlenderPlaying))
87
88 async def setInGraph(self, t: float, isBlenderPlaying: bool): 83 async def setInGraph(self, t: float, isBlenderPlaying: bool):
89 # bg thread 84 # bg thread
90 log.info(f'set graph time to {t:.2f} {isBlenderPlaying=}') 85 log.debug(f'set graph time to {t:.2f} {isBlenderPlaying=}')
91 p = Patch() 86 p = Patch()
92 if isBlenderPlaying: 87 if isBlenderPlaying:
93 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(True))) 88 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['playing'], Literal(True)))
94 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], decimalLiteral(round(time.time() - t, 1)))) 89 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], decimalLiteral(round(time.time() - t, 1))))
95 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], None)) 90 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], None))
98 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], None)) 93 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['wallStartTime'], None))
99 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], decimalLiteral(round(t, 1)))) 94 p = p.update(self.graph.getObjectPatch(self.ctx, L9['ascoltami'], L9['pausedSongTime'], decimalLiteral(round(t, 1))))
100 95
101 if p.isEmpty(): 96 if p.isEmpty():
102 return 97 return
103 log.info(f'setInGraph {p.shortSummary()}')
104 await self.graph.patch(p) 98 await self.graph.patch(p)