EditorTool3D/Assets/ZXL/Scripts/Test/FS/FileSystem.cs

180 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using ZXL;
namespace ZXLA
{
public enum FileOperationType
{
Create,
Rename,
Move,
Delete,
}
public enum FileObjectType
{
File,
Directory
}
public class FileSystem : MonoBehaviour, IFileSystem
{
private SortedDictionary<string, FileSystemObject> dic = new SortedDictionary<string, FileSystemObject>();
public event Action<string> OnCeateFile;
public event Action<string> OnCeateDirectory;
public event Action<FileSystemOperation> OnFileSystemChanged;
public void CreateFile(string path, int parentDepth)
{
dic.Add(path, new File(path, parentDepth + 1));
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.File, FileOperationType.Create, null,
path, null, null));
}
public bool FileExists(string path)
{
return dic.ContainsKey(path);
}
public void RenameFile(string path, string newName)
{
var fileSystemObject = TmpFile(path);
DeleteFileInternal(path);
var s = path.Split("/")[^1];
var replace = path.Replace(s, newName);
dic.Add(replace, new File(replace, fileSystemObject.depth + 1, fileSystemObject.isDisplay));
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.File,
FileOperationType.Rename, null, replace, null, null));
}
public void MoveFile(string oldPath, string newPath)
{
var fileSystemObject = TmpFile(oldPath);
DeleteFileInternal(oldPath);
dic.Add(newPath, new File(newPath, fileSystemObject.depth + 1, fileSystemObject.isDisplay));
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.File,
FileOperationType.Move, null, newPath, null, null));
}
public void DeleteFile(string path)
{
DeleteFileInternal(path);
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.File, FileOperationType.Delete, null,
path, null, null));
}
/// <summary>
/// 缓存一下
/// </summary>
FileSystemObject tmpFileSystemObject;
FileSystemObject TmpFile(string path)
{
tmpFileSystemObject = new FileSystemObject(null, -1);
tmpFileSystemObject.path = dic[path].path;
tmpFileSystemObject.depth = dic[path].depth;
tmpFileSystemObject.fileType = dic[path].fileType;
tmpFileSystemObject.isDisplay = dic[path].isDisplay;
return tmpFileSystemObject;
}
private void DeleteFileInternal(string path)
{
dic.Remove(path);
}
private List<FileSystemObject> tmpFileSystemObjects;
FileSystemObject TmpDirectory(string path)
{
tmpFileSystemObject = new FileSystemObject(null, -1);
tmpFileSystemObject.path = dic[path].path;
tmpFileSystemObject.depth = dic[path].depth;
tmpFileSystemObject.fileType = dic[path].fileType;
tmpFileSystemObject.isDisplay = dic[path].isDisplay;
return tmpFileSystemObject;
}
List<FileSystemObject> TmpDirectoryWithFiles(string path)
{
tmpFileSystemObjects ??= new List<FileSystemObject>();
tmpFileSystemObjects.Clear();
var keys = dic.Keys.ToListPooled();
var indexOf = keys.IndexOf(path);
for (int i = indexOf + 1; i < keys.Count; i++)
{
if (dic[keys[i]] is not File)
break;
var fileSystemObject = TmpFile(keys[i]);
tmpFileSystemObjects.Add(fileSystemObject);
DeleteFileInternal(keys[i]);
}
keys.Free();
return tmpFileSystemObjects;
}
public void CreateDirectory(string path, int parentDepth)
{
dic.Add(path, new Directory(path, parentDepth + 1));
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.Directory, FileOperationType.Create,
null, path, null, null));
}
public bool DirectoryExists(string path)
{
return dic.ContainsKey(path);
}
public void RenameDirectory(string path, string newName)
{
var s = path.Split("/")[^1];
var replace = path.Replace(s, newName);
var fileSystemObject = TmpDirectory(path);
dic.Remove(path);
dic.Add(replace, fileSystemObject);
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.Directory, FileOperationType.Rename,
null, replace, null, null));
}
public void MoveDirectory(string oldPath, string newPath)
{
var tmpDirectoryWithFiles = TmpDirectoryWithFiles(oldPath);
DeleteDirectory(oldPath);
var depth = dic[newPath].depth;
foreach (var tmpDirectoryWithFile in tmpDirectoryWithFiles)
{
var replace = tmpDirectoryWithFile.path.Replace(oldPath, newPath);
var tmp = new FileSystemObject(replace, depth + 1, tmpDirectoryWithFile.isDisplay);
dic.Add(replace, tmp);
}
}
public void DeleteDirectory(string path)
{
var keys = dic.Keys.ToListPooled();
var indexOf = keys.IndexOf(path);
for (int i = indexOf + 1; i < keys.Count; i++)
{
if (dic[keys[i]] is not File)
break;
DeleteFileInternal(keys[i]);
}
keys.Free();
dic.Remove(path);
OnFileSystemChanged?.Invoke(new FileSystemOperation(FileObjectType.Directory, FileOperationType.Delete,
null, path, null, null));
}
public IReadOnlyDictionary<string, FileSystemObject> GetAllObjects()
{
return this.dic;
}
}
}