94 lines
2.7 KiB
GDScript
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)
|