128 lines
4.0 KiB
GDScript
128 lines
4.0 KiB
GDScript
# datapack_manager.gd
|
|
extends Node
|
|
|
|
# --- CONFIGURATION ---
|
|
const DATAPACKS_DIR = "user://datapacks/"
|
|
|
|
# --- STATE ---
|
|
var loaded_packs: Dictionary[String, DatapackModel] = {}
|
|
|
|
|
|
func _ready():
|
|
var dir = DirAccess.open("user://")
|
|
if dir:
|
|
if not dir.dir_exists("datapacks"):
|
|
dir.make_dir("datapacks")
|
|
|
|
load_all_local_packs()
|
|
|
|
|
|
## Scans the local DATAPACKS_DIR, loads all valid datapack subdirectories,
|
|
## and registers them with the manager. This serves as the initial load and the refresh option.
|
|
func load_all_local_packs():
|
|
print("DatapackManager: Starting scan for local datapacks in '%s'" % DATAPACKS_DIR)
|
|
|
|
var loader = DatapackLoader.new()
|
|
var dir = DirAccess.open(DATAPACKS_DIR)
|
|
|
|
if dir == null:
|
|
push_error("DatapackManager: Failed to open datapacks directory: %s" % DATAPACKS_DIR)
|
|
return
|
|
|
|
dir.list_dir_begin()
|
|
var dir_name = dir.get_next()
|
|
|
|
while dir_name != "":
|
|
if dir_name == "." or dir_name == "..":
|
|
dir_name = dir.get_next()
|
|
continue
|
|
|
|
if dir.current_is_dir():
|
|
print("DatapackManager: Found pack directory: %s" % dir_name)
|
|
|
|
var datapack: DatapackModel = loader.load_datapack(dir_name)
|
|
|
|
if datapack:
|
|
register_pack(datapack)
|
|
else:
|
|
push_warning("DatapackManager: Failed to load pack in directory: %s. Skipping." % dir_name)
|
|
|
|
dir_name = dir.get_next()
|
|
|
|
dir.list_dir_end()
|
|
print("DatapackManager: Finished scanning local datapacks.")
|
|
|
|
|
|
func clear_loaded_packs():
|
|
loaded_packs.clear()
|
|
|
|
|
|
func register_pack(datapack: DatapackModel):
|
|
if datapack and datapack.guid:
|
|
var guid_str = datapack.guid.to_string()
|
|
loaded_packs[guid_str] = datapack
|
|
print("DatapackManager: Registered pack '%s' (%s)" % [datapack.name, guid_str])
|
|
else:
|
|
push_error("DatapackManager: Attempted to register invalid or un-GUIDed datapack.")
|
|
|
|
|
|
func unregister_pack(pack_guid: String):
|
|
if loaded_packs.has(pack_guid):
|
|
loaded_packs.erase(pack_guid)
|
|
print("DatapackManager: Unregistered pack with GUID %s." % pack_guid)
|
|
|
|
# ----------------------------------------------------------------------
|
|
# --- DEPENDENCY RESOLUTION ---
|
|
# ----------------------------------------------------------------------
|
|
|
|
## Resolves a single SzObject ID across all loaded packs.
|
|
## Used by SPECIFIC_DATASET mode when the pack GUID is unknown (or referencing local content).
|
|
func resolve_object_dependency(object_id: String) -> SzObject:
|
|
for pack_guid in loaded_packs:
|
|
var pack = loaded_packs[pack_guid]
|
|
var obj = pack.get_object_by_id(object_id)
|
|
|
|
if obj:
|
|
return obj
|
|
|
|
push_error("Dependency Resolution Failed: Could not find object with ID '%s' in any loaded datapack." % object_id)
|
|
return null
|
|
|
|
|
|
## Finds all SzObjects (Datasets or Templates) across all loaded packs
|
|
## that match a given sz_type string.
|
|
## Used by DATASET_TYPE_WILDCARD and CHARACTER_TEMPLATE_REF modes.
|
|
func resolve_type_wildcard(sz_type: String) -> Array[SzObject]:
|
|
var matching_objects: Array[SzObject] = []
|
|
for pack_guid in loaded_packs:
|
|
var pack = loaded_packs[pack_guid]
|
|
|
|
for obj in pack.sz_objects:
|
|
if obj.sz_type == sz_type:
|
|
matching_objects.append(obj)
|
|
|
|
if matching_objects.is_empty():
|
|
push_warning("Wildcard Resolution Failed: Could not find any object with sz_type '%s' in loaded datapacks." % sz_type)
|
|
|
|
return matching_objects
|
|
|
|
## Main entry point for resolving a DependencySource defined in a Template.
|
|
## Returns an array of SzObjects (can be Datasets or Templates)
|
|
func resolve_dependency_source(source: DependencySource) -> Array:
|
|
match source.mode:
|
|
DependencySource.DependencyMode.SPECIFIC_DATASET:
|
|
if source.target_datapack_guid.is_empty():
|
|
var target_obj = resolve_object_dependency(source.target_sz_object_id)
|
|
return [target_obj] if target_obj else []
|
|
|
|
var target_pack = loaded_packs.get(source.target_datapack_guid)
|
|
if target_pack:
|
|
var target_obj = target_pack.get_object_by_id(source.target_sz_object_id)
|
|
return [target_obj] if target_obj else []
|
|
return []
|
|
|
|
DependencySource.DependencyMode.DATASET_TYPE_WILDCARD:
|
|
return resolve_type_wildcard(source.target_type_string)
|
|
|
|
return []
|