DRY tag-redraw-3D-viewports loops via tool.Blender.update_all_viewports

Five inline copies of the same defensive pattern lived across
``tool/parametric.py``, ``bim/parametric_lifecycle.py``,
``bim/module/model/preview_base.py`` (twice), and as a near-twin
in ``tool/blender.py:update_all_viewports`` itself.

``tool.Blender.update_all_viewports`` already covered the
``tag_redraw`` job but used an ``assert context.screen`` that would
raise during background-mode operators or early-load_post calls
where ``screen`` legitimately is None. Relax to a defensive
``getattr(context, "screen", None)`` + silent return so the helper
fits every caller's needs, then collapse the 4 inline copies to
single calls.

Net -9 LOC. The helper now describes its contract ("silent no-op
when no screen attached") rather than naming specific callers, so
moving a caller doesn't rot the docstring.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Gorgious56
2026-05-27 16:01:18 +02:00
parent ff4c642db1
commit 2feade01cb
4 changed files with 10 additions and 20 deletions
@@ -126,9 +126,7 @@ def make_dim_setter(
if props is None:
return
setattr(props, field, max(min_value, float(value)))
for area in bpy.context.screen.areas if bpy.context.screen else ():
if area.type == "VIEW_3D":
area.tag_redraw()
tool.Blender.update_all_viewports()
return _set
@@ -179,10 +177,7 @@ def try_cancel_active_preview(context: bpy.types.Context) -> bool:
getattr(bpy.ops.bim, op_name)()
cancelled = True
if cancelled:
screen = context.screen
for area in screen.areas if screen else ():
if area.type == "VIEW_3D":
area.tag_redraw()
tool.Blender.update_all_viewports(context)
return cancelled
@@ -436,11 +436,7 @@ def resync_parametric_drafts_after_undo() -> None:
if regenerator is None:
continue
regenerator(obj)
screen = getattr(bpy.context, "screen", None)
if screen is not None:
for area in screen.areas:
if area.type == "VIEW_3D":
area.tag_redraw()
tool.Blender.update_all_viewports()
@persistent
@@ -464,4 +460,3 @@ def uninstall_parametric_lifecycle_handlers() -> None:
hook.remove(_resync_on_undo)
except ValueError:
pass
>>>>>>> 8e305588d (fixup! Add parametric-draft undo-resync registry + handler hooks)
+6 -2
View File
@@ -680,9 +680,13 @@ class Blender(bonsai.core.tool.Blender):
@classmethod
def update_all_viewports(cls, context: bpy.types.Context | None = None) -> None:
"""Tag every visible 3D viewport for redraw. Silent no-op when no
screen attached (background mode, plug-out, mid-load_post)."""
context = context or bpy.context
assert context.screen
for area in context.screen.areas:
screen = getattr(context, "screen", None)
if screen is None:
return
for area in screen.areas:
if area.type == "VIEW_3D":
area.tag_redraw()
+1 -5
View File
@@ -187,11 +187,7 @@ class Parametric(bonsai.core.tool.Parametric):
cls._geom_generation += 1
bonsai.bim.handler.update_bim_tool_props()
screen = getattr(bpy.context, "screen", None)
if screen is not None:
for area in screen.areas:
if area.type == "VIEW_3D":
area.tag_redraw()
tool.Blender.update_all_viewports()
@classmethod
def find_by_name(cls, name: str) -> Optional[ParametricObject]: