OverviewFilesCommitsIssuesDocsReleasesPeers

blender-bridge commits / 0a6cc1c

fix: feedback loop — suppress change detector during imports
Importing transforms from Godot triggered the depsgraph handler, which wrote transforms back to SHM, causing infinite ping-pong. Now suppresses the change detector while applying imported data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0a6cc1c708fc515fa74a3f0c59b0304a5283b9d7
by plankatron <fleeky@gmail.com> · 2026-03-03T00:32:02.000Z

Changed files (2) +26 -5

blender_addon/__init__.py +14 -5
……@@ -48,22 +48,26 @@ def _poll_timer():
4848 for msg in messages:
4949 text = msg.decode("utf-8", errors="replace")
5050 if text == "scene_exported":
51 # Full scene import from Godot
51 # Full scene import from Godot — suppress change detector
5252 if _importer is not None:
53 if _detector is not None:
54 _detector.suppress()
5355 scene = bpy.context.scene
5456 if hasattr(scene, "bridge_clear_on_import") and scene.bridge_clear_on_import:
5557 _clear_bridge_objects()
5658 _importer.full_import()
57 # Share ID mapping with change detector
5859 if _detector is not None:
5960 _detector.set_id_map(_importer._id_to_name)
61 _detector.unsuppress()
6062 print(f"BlenderBridge: Imported scene from Godot")
6163 elif text == "transform_update":
62 # Incremental transform update
64 # Incremental transform update — suppress change detector
6365 if _importer is not None:
66 if _detector is not None:
67 _detector.suppress()
6468 count = _importer.poll_updates()
65 if count > 0:
66 print(f"BlenderBridge: Updated {count} transforms")
69 if _detector is not None:
70 _detector.unsuppress()
6771 elif text.startswith("texture_registered:"):
6872 # Godot registered a texture: texture_registered:name,id
6973 parts = text.split(":", 1)[1].split(",")
……@@ -164,6 +168,10 @@ class BRIDGE_OT_import_scene(bpy.types.Operator):
164168 self.report({"ERROR"}, "Not connected")
165169 return {"CANCELLED"}
166170
171 # Suppress change detector during import
172 if _detector is not None:
173 _detector.suppress()
174
167175 # Clear existing bridge objects if enabled
168176 if context.scene.bridge_clear_on_import:
169177 _clear_bridge_objects()
……@@ -171,6 +179,7 @@ class BRIDGE_OT_import_scene(bpy.types.Operator):
171179 _importer.full_import()
172180 if _detector is not None:
173181 _detector.set_id_map(_importer._id_to_name)
182 _detector.unsuppress()
174183
175184 header = _shm.read_header()
176185 self.report(
blender_addon/change_detector.py +12 -0
……@@ -52,6 +52,8 @@ class ChangeDetector:
5252 self._name_to_id: dict[str, int] = {}
5353 self._next_id = 1
5454 self._registered = False
55 # Suppress change detection during imports (prevent feedback loop)
56 self._suppressed = False
5557
5658 def register(self):
5759 """Register the depsgraph handler."""
……@@ -85,8 +87,18 @@ class ChangeDetector:
8587
8688 # ── Depsgraph handler ────────────────────────────────────────────────
8789
90 def suppress(self):
91 """Temporarily suppress change detection (call during imports)."""
92 self._suppressed = True
93
94 def unsuppress(self):
95 """Re-enable change detection after import."""
96 self._suppressed = False
97
8898 def _on_depsgraph_update(self, scene, depsgraph):
8999 """Called after every depsgraph evaluation."""
100 if self._suppressed:
101 return
90102 dirty = []
91103
92104 for update in depsgraph.updates: