extends Node ## ## StudioBus - global, loosely-coupled signal hub. ## ## Every subsystem talks through this bus instead of holding direct references ## to each other. This keeps coupling low (easy to disable a module) and lets ## modules be lazily loaded/unloaded without dangling pointers. ## # Selection / scene signal object_selected(node: Node3D) signal object_deselected() signal scene_modified() # Editing signal brush_changed(brush_id: String) signal brush_radius_changed(radius: float) signal brush_strength_changed(strength: float) signal stroke_begin(world_pos: Vector3) signal stroke_apply(world_pos: Vector3, delta: Vector3) signal stroke_end() # Memory / performance signal low_memory() signal fps_throttled(fps: int) # Simulation signal sim_toggled(sim_id: String, enabled: bool) signal sim_settings_changed(sim_id: String, settings: Dictionary) # Animation signal timeline_playhead(time: float) signal keyframe_added(node_path: String, track: String, time: float) signal playback_state_changed(playing: bool) # UI signal panel_toggled(panel_id: String, visible: bool) var _last_fps_emit := 0.0 func _process(delta: float) -> void: # Surface sustained FPS drops so the renderer can throttle (see Step 2.3). if delta <= 0.0: return var fps := int(Engine.get_frames_per_second()) if fps > 0 and fps < 30: _last_fps_emit += delta if _last_fps_emit >= 2.0: _last_fps_emit = 0.0 fps_throttled.emit(fps) else: _last_fps_emit = 0.0