using System; using System.Collections.Generic; using System.IO; using Godot; using Zio; namespace TBL.GodotSharp.Content.Package { /// /// 基于文件系统的抽象内容包 /// 会在内部自动检索配置文件来获取描述符和依赖项信息 /// public class FileSystemPackage : PackageNode { public override IFileSystem SelfFileSystem { get; } public sealed override Info SelfInfo { get; } public sealed override IEnumerable Dependencies { get; } public FileSystemPackage(IFileSystem fileSystem) { Dependencies = null; var iniFound = false; foreach (var iniPath in fileSystem.EnumeratePaths(UPath.Root, "*.ini", SearchOption.TopDirectoryOnly, SearchTarget.File)) { var ini = new ConfigFile(); var err = ini.Parse(fileSystem.ReadAllText(iniPath)); if (err != Error.Ok) throw new GodotException(err); iniFound = true; if (SelfInfo.Name.Empty() && ini.HasSection(nameof(SelfInfo))) { SelfInfo = new Info( ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.Name)) as string, ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.AuthorInfo)) as string, ini.GetValue(nameof(SelfInfo), nameof(SelfInfo.VersionInfo)) as string ); } if (Dependencies == null && ini.HasSection(nameof(Dependencies))) { var dependencies = new List(); foreach (var dependencyName in ini.GetSectionKeys(nameof(Dependencies))) { var info = ini.GetValue(nameof(Dependencies), dependencyName) as Godot.Collections.Array; if (info == null || info.Count < 2) continue; var flags = DependencyInfo.FlagsEnum.None; if (info.Count > 2 && info[2] is string flagsInfo) { foreach (var flagInfo in flagsInfo.Split(';')) if (Enum.TryParse(flagInfo.Trim(), out var flag)) flags |= flag; } var dependency = new DependencyInfo(new Info(dependencyName, info[0] as string, info[1] as string), flags); dependencies.Add(dependency); } Dependencies = dependencies; } if (!SelfInfo.Name.Empty() && Dependencies != null) { break; } } if (!iniFound) { QueueFree(); throw new GodotException(Error.FileNotFound); } SelfFileSystem = fileSystem; } } }