fix: live-sync drawings/notes; cut per-frame sub cost; pen color+size
- backend: the scene PUT only broadcast to peers when annotation counts changed, so drawing/script-note edits saved but never synced live (only after a reload). Broadcast any gid that actually moved, regardless of type. - perf: active-drawings/active-note-set recomputed fully on every playhead tick (active-drawings even re-resolved each annotation per mark). Split the bar computation into memoized ::drawing-bars/::note-bars (scene/ctx/segs only) and reduce per-frame work to cheap interval tests. - perf: only subscribe drawing-layer to the boil clock when something is actually animating (no more 7fps idle re-renders). - drawings: pen colour picker + stroke-size slider, still defaulting to the annotation colour per session. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9f06b51f76
commit
40ff2ecf52
4 changed files with 80 additions and 54 deletions
|
|
@ -143,7 +143,8 @@ def scene(request, pk):
|
|||
deleted = data.get("deleted") or []
|
||||
summary = None
|
||||
if changed or deleted:
|
||||
groups = dict((p.scene or {}).get("groups", {}))
|
||||
prev_groups = (p.scene or {}).get("groups", {})
|
||||
groups = dict(prev_groups)
|
||||
for gid, patch in changed.items():
|
||||
if isinstance(patch, dict) and isinstance(groups.get(gid), dict):
|
||||
groups[gid] = {**groups[gid], **patch}
|
||||
|
|
@ -154,17 +155,23 @@ def scene(request, pk):
|
|||
merged = dict(p.scene or {}, groups=groups)
|
||||
p.scene, summary, counts = apply_attribution(
|
||||
p.scene, merged, request.user.get_username(), timezone.now().isoformat())
|
||||
if any(counts.values()): # don't log a no-op save
|
||||
scene_groups = (p.scene or {}).get("groups", {})
|
||||
if any(counts.values()): # history logs annotation edits only
|
||||
Revision.objects.create(project=p, user=request.user, summary=summary,
|
||||
annotations=annotation_layer(p.scene))
|
||||
# push the attributed delta to peers viewing this project
|
||||
scene_groups = (p.scene or {}).get("groups", {})
|
||||
# Live sync must cover EVERY group kind, not just annotations: script
|
||||
# notes and drawings aren't counted by attribution, so gating the
|
||||
# broadcast on `counts` silently dropped their updates to peers (they
|
||||
# only appeared on a full reload). Broadcast any gid that really moved.
|
||||
touched = {gid: scene_groups[gid] for gid in changed
|
||||
if gid in scene_groups and scene_groups[gid] != prev_groups.get(gid)}
|
||||
removed = [gid for gid in deleted if gid in prev_groups]
|
||||
if touched or removed:
|
||||
async_to_sync(get_channel_layer().group_send)(
|
||||
f"project_{p.pk}",
|
||||
{"type": "scene.delta",
|
||||
"delta": {"changed": {gid: scene_groups[gid]
|
||||
for gid in changed if gid in scene_groups},
|
||||
"deleted": list(deleted),
|
||||
"delta": {"changed": touched,
|
||||
"deleted": removed,
|
||||
"by": request.user.get_username()}})
|
||||
if "fps" in data:
|
||||
p.fps = data["fps"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue