Source code for simvx.editor.script_ops

"""Script management operations mixin for EditorState."""

from __future__ import annotations

import logging
from pathlib import Path
from typing import TYPE_CHECKING

from simvx.core import Node, ScriptManager

if TYPE_CHECKING:
    from .state import EditorState

log = logging.getLogger(__name__)


[docs] class ScriptOps: """Mixin providing script attach/detach/create/save operations. Methods in this class are designed to be mixed into EditorState, which provides the workspace, signals, and delegating properties they depend on. """ if TYPE_CHECKING: self: EditorState # type: ignore[assignment] def _save_script_file(self, node: Node, text: str): """Write text to the node's file-backed script path.""" if not node.script: return p = Path(node.script) if not p.is_absolute() and self.project_path: p = self.project_path / p try: p.parent.mkdir(parents=True, exist_ok=True) p.write_text(text) except Exception as e: log.error("Failed to save script %s: %s", p, e)
[docs] def set_script_text(self, text: str): """Set the code viewport text and sync it to the selected node's script.""" if self._viewport_code is not None: self._viewport_code.text = text node = self.selection.primary if node is None and self.edited_scene: node = self.edited_scene.root if node is not None: if node.script: self._save_script_file(node, text) else: node._script_inline = text self.modified = True
[docs] def attach_script(self, node: Node, path: str): """Attach a file-based script to *node*.""" node.script = path self.modified = True self.script_changed.emit()
[docs] def detach_script(self, node: Node): """Detach the file-based script from *node*.""" if node.script: ScriptManager.unload(node) node.script = None self.modified = True self.script_changed.emit()
[docs] def create_script(self, node: Node, template_name: str, class_name: str, rel_path: str) -> str | None: """Create a new script file from a template and attach it to *node*.""" from .templates import generate_script base = self.project_path or Path(".") abs_path = base / rel_path try: generate_script(template_name, class_name, output_path=str(abs_path)) except Exception as e: log.error("Failed to create script: %s", e) return None self.attach_script(node, rel_path) return str(abs_path)