230 lines
5.3 KiB
C#
230 lines
5.3 KiB
C#
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading;
|
|
|
|
#if UNITY_WINDOW
|
|
using AnotherFileBrowser.Windows;
|
|
#endif
|
|
#if UNITY_5_3_OR_NEWER
|
|
using UnityEngine;
|
|
#endif
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
|
|
|
namespace BITKit.IO
|
|
{
|
|
public interface IApplicationFile
|
|
{
|
|
string Extension { get; set; }
|
|
IStorageFile Current { get; }
|
|
event Func<(string, byte[])> DataHandle;
|
|
event Action<IStorageFile, IStorageFile> OnPathChanged;
|
|
void Save();
|
|
void SaveAs(string path=null);
|
|
void Load(IStorageFile file=null);
|
|
void Reload();
|
|
void AddListener(string key, Action<byte[]> action);
|
|
void RemoveListener(string key, Action<byte[]> action);
|
|
}
|
|
#if UNITY_WINDOW
|
|
[Serializable]
|
|
public sealed class ApplicationFile:IApplicationFile
|
|
{
|
|
private const string DefaultPath = nameof(ApplicationFile)+"."+nameof(DefaultPath);
|
|
|
|
#if UNITY_5_3_OR_NEWER
|
|
[UnityEngine.RuntimeInitializeOnLoadMethod]
|
|
private static void Reload()
|
|
{
|
|
Current = null;
|
|
DataHandle = null;
|
|
_genericEvent.Clear();
|
|
_OpenFileCancellationTokenSource = new();
|
|
}
|
|
#endif
|
|
public static IStorageFile Current
|
|
{
|
|
get => _current;
|
|
set
|
|
{
|
|
OnPathChanged?.Invoke(_current,value);
|
|
_current = value;
|
|
}
|
|
}
|
|
|
|
private static IStorageFile _current;
|
|
public static event Func<(string, byte[])> DataHandle;
|
|
public static event Action<IStorageFile, IStorageFile> OnPathChanged;
|
|
private static readonly GenericEvent _genericEvent = new();
|
|
private static CancellationTokenSource _OpenFileCancellationTokenSource = new();
|
|
private static string Extension { get; set; } = "zip";
|
|
|
|
private static BrowserProperties _browserProperties
|
|
{
|
|
get
|
|
{
|
|
var bp = new BrowserProperties();
|
|
#if UNITY_5_3_OR_NEWER
|
|
if (PlayerPrefs.HasKey(DefaultPath))
|
|
{
|
|
bp.initialDir = PlayerPrefs.GetString(DefaultPath);
|
|
}
|
|
#endif
|
|
if (string.IsNullOrEmpty(Extension) is false)
|
|
{
|
|
bp.filter = $"{Extension} files (*.{Extension})|*.{Extension}";
|
|
}
|
|
return bp;
|
|
}
|
|
}
|
|
|
|
public static void Save()
|
|
{
|
|
if (Current is null)
|
|
{
|
|
var bp = _browserProperties;
|
|
|
|
new Thread(() =>
|
|
{
|
|
new FileBrowser().SaveFileBrowser(bp, nameof(ApplicationFile), $".{Extension}", async path =>
|
|
{
|
|
await BITApp.SwitchToMainThread();
|
|
|
|
Current = new FileProvider(path);
|
|
|
|
Save();
|
|
});
|
|
}).Start();
|
|
|
|
BIT4Log.Log<IApplicationFile>($"无已加载的数据,等待选择保存地址");
|
|
return;
|
|
}
|
|
|
|
if (DataHandle is null)
|
|
{
|
|
BIT4Log.Log<IApplicationFile>("无任何可保存的数据");
|
|
}
|
|
|
|
List<IAsset> assets = new();
|
|
foreach (var func in DataHandle.CastAsFunc())
|
|
{
|
|
(string name,byte[] bytes) value = func.Invoke();
|
|
var asset = new BITAsset(value.name,value.bytes);
|
|
assets.Add(asset);
|
|
}
|
|
BITAssets.Build(Current.GetPath(),assets.ToArray());
|
|
|
|
BIT4Log.Log<IApplicationFile>($"已保存为:{Current.GetPath()}");
|
|
}
|
|
|
|
public static async void SaveAs(string path)
|
|
{
|
|
if (path is null)
|
|
{
|
|
var bp = _browserProperties;
|
|
|
|
new Thread(() =>
|
|
{
|
|
new FileBrowser().SaveFileBrowser(bp, nameof(ApplicationFile), $".{Extension}", async path =>
|
|
{
|
|
await BITApp.SwitchToMainThread();
|
|
|
|
Current = new FileProvider(path);
|
|
|
|
SaveAs(path);
|
|
});
|
|
}).Start();
|
|
|
|
return;
|
|
}
|
|
Current = new FileProvider(path);
|
|
Save();
|
|
}
|
|
public void AddListener(string key, Action<byte[]> action)
|
|
{
|
|
_genericEvent.AddListener<byte[]>(key,action);
|
|
}
|
|
|
|
public void RemoveListener(string key, Action<byte[]> action)
|
|
{
|
|
_genericEvent.RemoveListener<byte[]>(key,action);
|
|
}
|
|
|
|
public static void ReloadFile()
|
|
{
|
|
Load(Current);
|
|
}
|
|
public static void Load(IStorageFile file=null)
|
|
{
|
|
if (file is null)
|
|
{
|
|
_OpenFileCancellationTokenSource.Cancel();
|
|
_OpenFileCancellationTokenSource = new();
|
|
|
|
BIT4Log.Log<IApplicationFile>("正在选择文件,跳过该次载入");
|
|
|
|
var bp = _browserProperties;
|
|
new Thread(() =>
|
|
{
|
|
new FileBrowser().OpenFileBrowser(bp, Filepath);
|
|
return;
|
|
async void Filepath(string path)
|
|
{
|
|
await BITApp.SwitchToMainThread();
|
|
Current = new FileProvider(path);
|
|
Load(Current);
|
|
}
|
|
}).Start();
|
|
|
|
return;
|
|
}
|
|
|
|
Current = file;
|
|
|
|
var path = file.GetPath();
|
|
var header = BITAssets.ReadHeader(path);
|
|
foreach (var name in header.Files)
|
|
{
|
|
var asset = BITAssets.ReadAsset(path, name);
|
|
|
|
_genericEvent.Invoke(asset.Name,asset.Buffer);
|
|
}
|
|
BIT4Log.Log<IApplicationFile>($"已加载{header.Files.Count}个数据");
|
|
}
|
|
string IApplicationFile.Extension
|
|
{
|
|
get => Extension;
|
|
set => Extension = value;
|
|
}
|
|
IStorageFile IApplicationFile.Current => Current;
|
|
|
|
event Func<(string, byte[])> IApplicationFile.DataHandle
|
|
{
|
|
add => DataHandle += value;
|
|
remove => DataHandle -= value;
|
|
}
|
|
event Action<IStorageFile,IStorageFile> IApplicationFile.OnPathChanged
|
|
{
|
|
add => OnPathChanged += value;
|
|
remove=>OnPathChanged -= value;
|
|
}
|
|
|
|
|
|
|
|
void IApplicationFile.Save() => Save();
|
|
|
|
void IApplicationFile.SaveAs(string path) => SaveAs(path);
|
|
|
|
void IApplicationFile.Load(IStorageFile file) => Load(file);
|
|
void IApplicationFile.Reload()=>ReloadFile();
|
|
|
|
}
|
|
#endif
|
|
}
|