Browse Source

feat: 文件系统(简易未定实现)

LanzaSchneider 2 years ago
parent
commit
a3508aae47

+ 3 - 44
Content.cs

@@ -1,6 +1,5 @@
 using System;
 using System;
-using System.IO;
-using Godot;
+using Zio.FileSystems;
 
 
 namespace TBL.GodotSharp.Content;
 namespace TBL.GodotSharp.Content;
 
 
@@ -10,49 +9,9 @@ namespace TBL.GodotSharp.Content;
 public static class Content
 public static class Content
 {
 {
     /// <summary>
     /// <summary>
-    /// 考虑依赖项打开文件流
+    /// 文件系统容器
     /// </summary>
     /// </summary>
-    /// <param name="package">要打开的内容包</param>
-    /// <param name="path">要打开的路径</param>
-    /// <returns>打开的文件流</returns>
-    public static Stream OpenFileStreamWithDependency(
-        this Package package, string path)
-    {
-        var stream = package.OpenFileStream(path);
-
-        // 直接打开成功的场合
-        if (stream != null)
-            return stream;
-
-        // 在同级节点中寻找依赖项
-        Node container;
-        if (null != (container = package.GetParent()))
-        {
-            for (int i = 0, count = container.GetChildCount();
-                 i < count; 
-                 i++)
-            {
-                if (container.GetChild(i) is not Package dependency)
-                    continue;
-                // 遍历依赖项信息
-                foreach (var info in package.Dependencies)
-                {
-                    // 符合依赖项的包将会被试图追溯
-                    if (dependency.SelfInfo.IsCompatibleWith(info))
-                    {
-                        stream = dependency.OpenFileStreamWithDependency(path);
-                        
-                        // 直接打开成功的场合
-                        if (stream != null)
-                            return stream;
-                    }
-                }
-            }
-        }
-
-        // 打开失败的场合
-        return null;
-    }
+    public static readonly AggregateFileSystem FileSystem = new AggregateFileSystem();
     
     
     /// <summary>
     /// <summary>
     /// 判断 <paramref name="actualVersion"/> 能否满足 <paramref name="targetVersion"/> 的版本要求
     /// 判断 <paramref name="actualVersion"/> 能否满足 <paramref name="targetVersion"/> 的版本要求

+ 182 - 0
FileSystem/GodotFileSystem.cs

@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Godot;
+using TBL.GodotSharp.IO.File;
+using Zio;
+
+namespace TBL.GodotSharp.Content.FileSystem;
+
+/// <summary>
+/// Godot 文件系统
+/// </summary>
+public class GodotFileSystem : Zio.FileSystems.FileSystem
+{
+    /// <summary>
+    /// 根目录
+    /// </summary>
+    private readonly string _rootPath;
+
+    /// <summary>
+    /// 目录工具
+    /// </summary>
+    private readonly Godot.Directory _directoryTool;
+
+    public GodotFileSystem(string rootPath)
+    {
+        _rootPath = rootPath;
+        _directoryTool = new Godot.Directory();
+    }
+
+    private string GetFullPath(UPath uPath) => $"{_rootPath}{uPath}";
+    
+    protected override void CreateDirectoryImpl(UPath path)
+    {
+        _directoryTool.MakeDirRecursive(GetFullPath(path));
+    }
+
+    protected override bool DirectoryExistsImpl(UPath path) => _directoryTool.DirExists(GetFullPath(path));
+    
+    protected override bool FileExistsImpl(UPath path) => _directoryTool.FileExists(GetFullPath(path));
+    
+    protected override Stream OpenFileImpl(UPath path, FileMode mode, FileAccess access, FileShare share)
+    {
+        if (mode == FileMode.Open && access == FileAccess.Read)
+        {
+            return new GodotFileStream(GetFullPath(path), Godot.File.ModeFlags.Read);
+        }
+
+        throw new FileNotFoundException();
+    }
+    
+    protected override IEnumerable<UPath> EnumeratePathsImpl(
+        UPath path, 
+        string searchPattern, 
+        SearchOption searchOption, 
+        SearchTarget searchTarget
+        )
+    {
+        var directoryTool = new Godot.Directory();
+        var err = directoryTool.Open(GetFullPath(path));
+        if (err != Error.Ok)
+            throw new IOException($"{err}");
+        directoryTool.ListDirBegin();
+        for (var current = directoryTool.GetNext();; current = directoryTool.GetNext())
+        {
+            if (string.IsNullOrEmpty(current))
+                break;
+            if (current is ".." or ".")
+                continue;
+            if ((searchTarget == SearchTarget.Both || searchTarget == SearchTarget.File) &&
+                !directoryTool.CurrentIsDir())
+                yield return System.IO.Path.Combine(path.FullName, current);
+            if ((searchTarget == SearchTarget.Both || searchTarget == SearchTarget.Directory) &&
+                directoryTool.CurrentIsDir())
+                yield return System.IO.Path.Combine(path.FullName, current);
+            if (directoryTool.CurrentIsDir() && searchOption == SearchOption.AllDirectories)
+            {
+                foreach (var sub in EnumeratePathsImpl(System.IO.Path.Combine(path.FullName, current), 
+                             searchPattern, searchOption, searchTarget))
+                {
+                    yield return sub;
+                }
+            }
+        }
+        directoryTool.ListDirEnd();
+    }
+
+    protected override void MoveDirectoryImpl(UPath srcPath, UPath destPath)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void DeleteDirectoryImpl(UPath path, bool isRecursive)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void CopyFileImpl(UPath srcPath, UPath destPath, bool overwrite)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void ReplaceFileImpl(UPath srcPath, UPath destPath, UPath destBackupPath, bool ignoreMetadataErrors)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override long GetFileLengthImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void MoveFileImpl(UPath srcPath, UPath destPath)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void DeleteFileImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override FileAttributes GetAttributesImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void SetAttributesImpl(UPath path, FileAttributes attributes)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override DateTime GetCreationTimeImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void SetCreationTimeImpl(UPath path, DateTime time)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override DateTime GetLastAccessTimeImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void SetLastAccessTimeImpl(UPath path, DateTime time)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override DateTime GetLastWriteTimeImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override void SetLastWriteTimeImpl(UPath path, DateTime time)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override IEnumerable<FileSystemItem> EnumerateItemsImpl(UPath path, SearchOption searchOption, SearchPredicate searchPredicate)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override IFileSystemWatcher WatchImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override string ConvertPathToInternalImpl(UPath path)
+    {
+        throw new NotImplementedException();
+    }
+
+    protected override UPath ConvertPathFromInternalImpl(string innerPath)
+    {
+        throw new NotImplementedException();
+    }
+}

+ 0 - 13
Package.FileSystem.cs

@@ -1,13 +0,0 @@
-using System.IO;
-
-namespace TBL.GodotSharp.Content;
-
-public partial class Package
-{
-    /// <summary>
-    /// 打开文件流
-    /// </summary>
-    /// <param name="path"></param>
-    /// <returns></returns>
-    public abstract Stream OpenFileStream(string path);
-}

+ 0 - 25
Package.cs

@@ -1,25 +0,0 @@
-using System.Collections.Generic;
-using Godot;
-
-namespace TBL.GodotSharp.Content;
-
-/// <summary>
-/// 资源包节点
-/// </summary>
-public abstract partial class Package : Node
-{
-    /// <summary>
-    /// 自身信息
-    /// </summary>
-    public readonly Info SelfInfo;
-
-    /// <summary>
-    /// 依赖项信息集
-    /// </summary>
-    public readonly ICollection<DependencyInfo> Dependencies = new HashSet<DependencyInfo>();
-
-    public override void _Ready()
-    {
-        Name = SelfInfo.ToString();
-    }
-}

+ 17 - 0
Package/InternalPackage.cs

@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using TBL.GodotSharp.Content.FileSystem;
+using Zio;
+
+namespace TBL.GodotSharp.Content.Package;
+
+/// <summary>
+/// 内部内容包
+/// </summary>
+public class InternalPackage : PackageNode
+{
+    public override IFileSystem SelfFileSystem { get; } = new GodotFileSystem("res://");
+    
+    public override Info SelfInfo { get; }
+    
+    public override ICollection<DependencyInfo> Dependencies { get; }
+}

+ 90 - 90
Package.DependencyInfo.cs → PackageNode.DependencyInfo.cs

@@ -1,91 +1,91 @@
-using System;
-
-namespace TBL.GodotSharp.Content;
-
-public partial class Package
-{
-    /// <summary>
-    /// 包信息
-    /// </summary>
-    public struct Info
-    {
-        /// <summary>
-        /// 包名称
-        /// </summary>
-        public readonly string Name;
-
-        /// <summary>
-        /// 作者信息
-        /// </summary>
-        public readonly string AuthorInfo;
-        
-        /// <summary>
-        /// 版本信息
-        /// </summary>
-        public readonly Version VersionInfo;
-
-        public Info(string name, string author, string version)
-        {
-            Name = name;
-            AuthorInfo = author;
-            if (!Version.TryParse(version, out VersionInfo))
-                VersionInfo = new Version();
-        }
-        
-        /// <summary>
-        /// 判断本信息能否满足 <paramref name="target"/> 的版本要求
-        /// </summary>
-        /// <param name="target">依赖项信息</param>
-        public readonly bool IsCompatibleWith(DependencyInfo target)
-        {
-            return Content.IsCompatibleWith(VersionInfo, target.Target.VersionInfo,
-                (target.Flags & DependencyInfo.FlagsEnum.Strict) != 0 ? 1 : 0);
-        }
-
-        public override string ToString() => $"{Name}_{AuthorInfo}_{VersionInfo}";
-    }
-
-    /// <summary>
-    /// 包依赖信息
-    /// </summary>
-    public struct DependencyInfo
-    {
-        /// <summary>
-        /// 依赖目标
-        /// </summary>
-        public readonly Info Target;
-
-        /// <summary>
-        /// 依赖属性
-        /// </summary>
-        public readonly FlagsEnum Flags;
-        
-        /// <summary>
-        /// 依赖项属性
-        /// </summary>
-        [Flags]
-        public enum FlagsEnum
-        {
-            /// <summary>
-            /// 无属性
-            /// </summary>
-            None,
-                
-            /// <summary>
-            /// 非必须依赖项
-            /// </summary>
-            Unnecessary,
-
-            /// <summary>
-            /// 严格(次版本号)兼容依赖项
-            /// </summary>
-            Strict
-        }
-
-        public DependencyInfo(Info target, FlagsEnum flags = FlagsEnum.None)
-        {
-            Target = target;
-            Flags = flags;
-        }
-    }
+using System;
+
+namespace TBL.GodotSharp.Content;
+
+public partial class PackageNode
+{
+    /// <summary>
+    /// 包信息
+    /// </summary>
+    public struct Info
+    {
+        /// <summary>
+        /// 包名称
+        /// </summary>
+        public readonly string Name;
+
+        /// <summary>
+        /// 作者信息
+        /// </summary>
+        public readonly string AuthorInfo;
+        
+        /// <summary>
+        /// 版本信息
+        /// </summary>
+        public readonly Version VersionInfo;
+
+        public Info(string name, string author, string version)
+        {
+            Name = name;
+            AuthorInfo = author;
+            if (!Version.TryParse(version, out VersionInfo))
+                VersionInfo = new Version();
+        }
+        
+        /// <summary>
+        /// 判断本信息能否满足 <paramref name="target"/> 的版本要求
+        /// </summary>
+        /// <param name="target">依赖项信息</param>
+        public readonly bool IsCompatibleWith(DependencyInfo target)
+        {
+            return Content.IsCompatibleWith(VersionInfo, target.Target.VersionInfo,
+                (target.Flags & DependencyInfo.FlagsEnum.Strict) != 0 ? 1 : 0);
+        }
+
+        public override string ToString() => $"{Name}_{AuthorInfo}_{VersionInfo}";
+    }
+
+    /// <summary>
+    /// 包依赖信息
+    /// </summary>
+    public struct DependencyInfo
+    {
+        /// <summary>
+        /// 依赖目标
+        /// </summary>
+        public readonly Info Target;
+
+        /// <summary>
+        /// 依赖属性
+        /// </summary>
+        public readonly FlagsEnum Flags;
+        
+        /// <summary>
+        /// 依赖项属性
+        /// </summary>
+        [Flags]
+        public enum FlagsEnum
+        {
+            /// <summary>
+            /// 无属性
+            /// </summary>
+            None,
+                
+            /// <summary>
+            /// 非必须依赖项
+            /// </summary>
+            Unnecessary,
+
+            /// <summary>
+            /// 严格(次版本号)兼容依赖项
+            /// </summary>
+            Strict
+        }
+
+        public DependencyInfo(Info target, FlagsEnum flags = FlagsEnum.None)
+        {
+            Target = target;
+            Flags = flags;
+        }
+    }
 }
 }

+ 11 - 0
PackageNode.FileSystem.cs

@@ -0,0 +1,11 @@
+using Zio;
+
+namespace TBL.GodotSharp.Content;
+
+public partial class PackageNode
+{
+    /// <summary>
+    /// 本包文件系统
+    /// </summary>
+    public abstract IFileSystem SelfFileSystem { get; }
+}

+ 42 - 0
PackageNode.cs

@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+using Godot;
+
+namespace TBL.GodotSharp.Content;
+
+/// <summary>
+/// 资源包节点
+/// </summary>
+public abstract partial class PackageNode : Node
+{
+    /// <summary>
+    /// 自身信息
+    /// </summary>
+    public abstract Info SelfInfo { get; }
+
+    /// <summary>
+    /// 依赖项信息集
+    /// </summary>
+    public abstract ICollection<DependencyInfo> Dependencies { get; }
+
+    public override void _Ready()
+    {
+        Name = SelfInfo.ToString();
+    }
+
+    public override void _EnterTree()
+    {
+        if (SelfFileSystem != null)
+        {
+            Content.FileSystem.AddFileSystem(SelfFileSystem);
+        }
+    }
+
+    public override void _ExitTree()
+    {
+        if (SelfFileSystem != null)
+        {
+            Content.FileSystem.RemoveFileSystem(SelfFileSystem);
+            SelfFileSystem.Dispose();
+        }
+    }
+}

+ 6 - 0
TBL.GodotSharp.Content.csproj

@@ -5,4 +5,10 @@
         <LangVersion>latest</LangVersion>
         <LangVersion>latest</LangVersion>
         <Company>lanzainc.xyz</Company>
         <Company>lanzainc.xyz</Company>
     </PropertyGroup>
     </PropertyGroup>
+    <ItemGroup>
+      <PackageReference Include="Zio" Version="0.16.1" />
+    </ItemGroup>
+    <ItemGroup>
+      <ProjectReference Include="..\TBL.GodotSharp\TBL.GodotSharp.csproj" />
+    </ItemGroup>
 </Project>
 </Project>