Files
2026-07-19 10:47:28 +02:00

94 lines
2.7 KiB
GDScript

@tool
class_name YAMLFileSystem extends Node
signal file_opened(path)
signal file_saved(path)
signal file_updated(path)
signal file_closed(path)
signal file_renamed(old_path, new_path)
# Singleton pattern
static var _instance: YAMLFileSystem
static func get_singleton() -> YAMLFileSystem:
if not _instance:
_instance = YAMLFileSystem.new()
Engine.get_main_loop().root.call_deferred("add_child", _instance)
return _instance
func _init() -> void:
if _instance != null:
push_error("YAMLFileSystem singleton already exists")
return
_instance = self
# Mark as persistent so it doesn't get destroyed on scene changes
process_mode = Node.PROCESS_MODE_ALWAYS
# File operations with signals
func save_file(path: String, content: String) -> Error:
var was_new_file = not file_exists(path)
var file := FileAccess.open(path, FileAccess.WRITE)
if not file:
return FileAccess.get_open_error()
file.store_string(content)
file_saved.emit(path)
file_updated.emit(path)
# If this was a new file, notify Godot's filesystem
if was_new_file:
call_deferred("_refresh_filesystem", path)
return OK
func read_file(path: String) -> Variant:
var file := FileAccess.open(path, FileAccess.READ)
if not file:
return FileAccess.get_open_error()
return file.get_as_text()
# Check if a file exists
func file_exists(path: String) -> bool:
return FileAccess.file_exists(path)
# Utility to check if a path is a YAML file
func is_yaml_file(path: String) -> bool:
return path.get_extension().to_lower() in ["yaml", "yml"]
# For external updates, allow code to manually trigger the signal
func notify_file_updated(path: String) -> void:
file_updated.emit(path)
# Called when a file is opened in the editor
func notify_file_opened(path: String) -> void:
file_opened.emit(path)
# Called when a file is closed in the editor
func notify_file_closed(path: String) -> void:
file_closed.emit(path)
# Called when a file is renamed (by the filesystem or editor)
func notify_file_renamed(old_path: String, new_path: String) -> void:
file_renamed.emit(old_path, new_path)
# Find a file by name in the filesystem
func find_file_in_filesystem(dir: EditorFileSystemDirectory, filename: String) -> String:
# Check files in current directory
for i in range(dir.get_file_count()):
var file_path := dir.get_file_path(i)
if file_path.get_file() == filename:
return file_path
# Recursively check subdirectories
for i in range(dir.get_subdir_count()):
var subdir := dir.get_subdir(i)
var result := find_file_in_filesystem(subdir, filename)
if not result.is_empty():
return result
return ""
func _refresh_filesystem(path: String) -> void:
EditorInterface.get_resource_filesystem().update_file(path)