引入最新版本的AxiNSApi

This commit is contained in:
sin365 2025-08-18 22:12:40 +08:00
parent 8afcbce6b1
commit 57c4947623
6 changed files with 384 additions and 214 deletions

View File

@ -15,6 +15,11 @@ public class AxiNS
}
}
/// <summary>
/// 延迟提交是否使用多线程
/// </summary>
public static bool usedmultithreading = false;
public AxiNSUser user;
public AxiNSMount mount;
public AxiNSIO io;

View File

@ -7,20 +7,20 @@ using System.Text.RegularExpressions;
public class AxiNSIO
{
string save_name => AxiNS.instance.mount.SaveMountName;
public string save_path => $"{save_name}:/";
string save_name => AxiNS.instance.mount.SaveMountName;
public string save_path => $"{save_name}:/";
#if UNITY_SWITCH
private FileHandle fileHandle = new nn.fs.FileHandle();
#endif
static object commitLock = new object();
static object commitLock = new object();
static bool bDirty = false;
static bool bDirty = false;
bool CommitSave()
{
lock (commitLock)
{
bool CommitSave()
{
lock (commitLock)
{
#if UNITY_SWITCH && !UNITY_EDITOR
// 阻止用户在保存时,退出游戏 Switch 条例 0080
@ -39,41 +39,41 @@ public class AxiNSIO
bDirty = false;
return true;
#else
return false;
return false;
#endif
}
}
}
}
void SetCommitDirty()
{
lock (commitLock)
{
bDirty = true;
}
}
void SetCommitDirty()
{
lock (commitLock)
{
bDirty = true;
}
}
public void ApplyAutoCommit()
{
bool temp;
lock (commitLock)
{
temp = bDirty;
}
public void ApplyAutoCommit()
{
bool temp;
lock (commitLock)
{
temp = bDirty;
}
if (temp)
{
CommitSave();
}
}
if (temp)
{
CommitSave();
}
}
/// <summary>
/// 检查Path是否存在
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CheckPathExists(string filePath)
{
/// <summary>
/// 检查Path是否存在
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CheckPathExists(string filePath)
{
#if !UNITY_SWITCH
return false;
#else
@ -86,14 +86,14 @@ public class AxiNSIO
//return nn.fs.FileSystem.ResultPathAlreadyExists.Includes(result);
return !nn.fs.FileSystem.ResultPathNotFound.Includes(result);
#endif
}
/// <summary>
/// 检查Path是否不存在
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CheckPathNotFound(string filePath)
{
}
/// <summary>
/// 检查Path是否不存在
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CheckPathNotFound(string filePath)
{
#if !UNITY_SWITCH
return false;
#else
@ -102,16 +102,16 @@ public class AxiNSIO
//这个异常捕获。真的别扭
return nn.fs.FileSystem.ResultPathNotFound.Includes(result);
#endif
}
/// <summary>
/// 创建目录目录存在也会返回true
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CreateDir(string filePath)
{
lock (commitLock)
{
}
/// <summary>
/// 创建目录目录存在也会返回true
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool CreateDir(string filePath)
{
lock (commitLock)
{
#if !UNITY_SWITCH
return false;
@ -124,43 +124,43 @@ public class AxiNSIO
}
return true;
#endif
}
}
}
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="bw"></param>
/// <returns></returns>
public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms)
{
return FileToSaveWithCreate(filePath, ms.ToArray());
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <returns></returns>
public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms)
{
var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="bw"></param>
/// <returns></returns>
public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms)
{
return FileToSaveWithCreate(filePath, ms.ToArray());
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <returns></returns>
public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms)
{
var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <param name="immediatelyCommit">是否立即Commit到物理存储</param>
/// <returns></returns>
public bool FileToSaveWithCreate(string filePath, byte[] data, bool immediatelyCommit = true)
{
lock (commitLock)
{
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <param name="immediatelyCommit">是否立即Commit到物理存储</param>
/// <returns></returns>
public bool FileToSaveWithCreate(string filePath, byte[] data, bool immediatelyCommit = true)
{
lock (commitLock)
{
#if !UNITY_SWITCH
return false;
#else
@ -293,42 +293,45 @@ public class AxiNSIO
return true;
}
#endif
}
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <returns></returns>
public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data)
{
var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public byte[] LoadSwitchDataFile(string filename)
{
LoadSwitchDataFile(filename, out byte[] outputData);
return outputData;
}
public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms)
{
if (LoadSwitchDataFile(filename, out byte[] outputData))
{
using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms))
{
writer.Write(outputData);
}
return true;
}
return false;
}
public bool LoadSwitchDataFile(string filename, out byte[] outputData)
{
}
}
/// <summary>
/// 保存并创建文件(如果目录不存在回先自动创建目录)
/// </summary>
/// <param name="filePath"></param>
/// <param name="data"></param>
/// <returns></returns>
public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data)
{
var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public byte[] LoadSwitchDataFile(string filename)
{
byte[] outputData;
LoadSwitchDataFile(filename, out outputData);
return outputData;
}
public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms)
{
byte[] outputData;
if (LoadSwitchDataFile(filename, out outputData))
{
using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms))
{
writer.Write(outputData);
}
return true;
}
return false;
}
public bool LoadSwitchDataFile(string filename, out byte[] outputData)
{
#if !UNITY_SWITCH || UNITY_EDITOR
outputData = null;
return false;
outputData = null;
return false;
#else
outputData = null;
if (!AxiNS.instance.mount.SaveIsMount)
@ -376,32 +379,34 @@ public class AxiNSIO
outputData = loadedData;
return true;
#endif
}
public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename)
{
var wait = new AxiNSWait_LoadSwitchDataFile(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool GetDirectoryFiles(string path, out string[] entrys)
{
}
public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename)
{
var wait = new AxiNSWait_LoadSwitchDataFile(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool GetDirectoryFiles(string path, out string[] entrys)
{
#if !UNITY_SWITCH || UNITY_EDITOR
entrys = null;
return false;
entrys = null;
return false;
#else
return GetDirectoryEntrys(path,nn.fs.OpenDirectoryMode.File,out entrys);
#endif
}
public bool GetDirectoryDirs(string path, out string[] entrys)
{
}
public bool GetDirectoryDirs(string path, out string[] entrys)
{
#if !UNITY_SWITCH || UNITY_EDITOR
entrys = null;
return false;
entrys = null;
return false;
#else
return GetDirectoryEntrys(path, nn.fs.OpenDirectoryMode.Directory, out entrys);
#endif
}
}
#if UNITY_SWITCH
public bool GetDirectoryEntrys(string path, nn.fs.OpenDirectoryMode type, out string[] entrys)
@ -430,8 +435,9 @@ public class AxiNSIO
}
#endif
public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys)
{
public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys)
{
#if UNITY_SWITCH
nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle();
@ -462,15 +468,15 @@ public class AxiNSIO
entrys = temp.ToArray();
return true;
#else
entrys = default;
entrys = null;
return false;
#endif
}
}
public IEnumerable<string> EnumerateFiles(string path, string searchPattern)
{
public IEnumerable<string> EnumerateFiles(string path, string searchPattern)
{
#if !UNITY_SWITCH || UNITY_EDITOR
yield break;
yield break;
#else
// 将通配符转换为正则表达式(支持*和?
var regexPattern = "^" +
@ -494,10 +500,10 @@ public class AxiNSIO
}
}
#endif
}
}
public bool DeletePathFile(string filename)
{
public bool DeletePathFile(string filename)
{
#if !UNITY_SWITCH
return false;
#else
@ -526,15 +532,15 @@ public class AxiNSIO
return CommitSave();
#endif
}
public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename)
{
var wait = new AxiNSWait_DeletePathFile(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool DeletePathDir(string filename)
{
}
public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename)
{
var wait = new AxiNSWait_DeletePathFile(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool DeletePathDir(string filename)
{
#if !UNITY_SWITCH
return false;
#else
@ -561,15 +567,15 @@ public class AxiNSIO
#endif
return CommitSave();
#endif
}
public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename)
{
var wait = new AxiNSWait_DeletePathDir(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool DeletePathDirRecursively(string filename)
{
}
public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename)
{
var wait = new AxiNSWait_DeletePathDir(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
public bool DeletePathDirRecursively(string filename)
{
#if !UNITY_SWITCH
return false;
#else
@ -596,19 +602,86 @@ public class AxiNSIO
#endif
return CommitSave();
#endif
}
}
public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename)
{
var wait = new AxiNSWait_DeletePathDirRecursively(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
#if UNITY_SWITCH
public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename)
{
var wait = new AxiNSWait_DeletePathDirRecursively(filename);
AxiNS.instance.wait.AddWait(wait);
return wait;
}
/// <summary>
/// 递归删除目录
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public bool DeleteRecursivelyPathDir(string filename)
{
#if !UNITY_SWITCH
return false;
#else
#if UNITY_SWITCH && !UNITY_EDITOR
// This next line prevents the user from quitting the game while saving.
// This is required for Nintendo Switch Guideline 0080
UnityEngine.Switch.Notification.EnterExitRequestHandlingSection();
#endif
public bool RenameDir(string oldpath, string newpath)
{
if (CheckPathNotFound(filename))
return false;
nn.Result result;
result = nn.fs.Directory.DeleteRecursively(filename);
if (result.IsSuccess() == false)
{
UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}");
return false;
}
#if UNITY_SWITCH && !UNITY_EDITOR
// End preventing the user from quitting the game while saving.
UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection();
#endif
return CommitSave();
#endif
}
/// <summary>
/// 递归删除情况
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public bool CleanRecursivelyPathDir(string filename)
{
#if !UNITY_SWITCH
return false;
#else
#if UNITY_SWITCH && !UNITY_EDITOR
// This next line prevents the user from quitting the game while saving.
// This is required for Nintendo Switch Guideline 0080
UnityEngine.Switch.Notification.EnterExitRequestHandlingSection();
#endif
if (CheckPathNotFound(filename))
return false;
nn.Result result;
result = nn.fs.Directory.CleanRecursively(filename);
if (result.IsSuccess() == false)
{
UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}");
return false;
}
#if UNITY_SWITCH && !UNITY_EDITOR
// End preventing the user from quitting the game while saving.
UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection();
#endif
return CommitSave();
#endif
}
public bool RenameDir(string oldpath, string newpath)
{
#if !UNITY_SWITCH
return false;
#else
@ -637,9 +710,9 @@ public class AxiNSIO
return CommitSave();
#endif
}
bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true)
{
}
bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true)
{
#if !UNITY_SWITCH
return false;
#else
@ -715,14 +788,14 @@ public class AxiNSIO
return true;
#endif
}
/// <summary>
/// 检查指定挂载点是否可访问
/// </summary>
/// <param name="pathPrefix">路径前缀,例如 "save:/" 或 "sd:/"</param>
/// <returns>挂载点是否可访问</returns>
bool IsMountPointAccessible(string pathPrefix)
{
}
/// <summary>
/// 检查指定挂载点是否可访问
/// </summary>
/// <param name="pathPrefix">路径前缀,例如 "save:/" 或 "sd:/"</param>
/// <returns>挂载点是否可访问</returns>
bool IsMountPointAccessible(string pathPrefix)
{
#if !UNITY_SWITCH
return false;
#else
@ -760,5 +833,5 @@ public class AxiNSIO
return true; // 其他挂载点需根据实际需求实现
}
#endif
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using UnityEngine;
public class AxiNSMono : MonoBehaviour
{
Action act;
float waittime;
float lastinvokeTime;
public static void SetInvoke(Action _act, int _waitsec)
{
GameObject gobj = GameObject.Find($"[{nameof(AxiNSMono)}]");
if (gobj == null)
{
gobj = new GameObject();
gobj.name = $"[{nameof(AxiNSMono)}]";
GameObject.DontDestroyOnLoad(gobj);
}
AxiNSMono com = gobj.GetComponent<AxiNSMono>();
if (com == null)
{
com = gobj.AddComponent<AxiNSMono>();
}
com.act = _act;
com.waittime = _waitsec;
}
public void OnEnable()
{
Debug.Log("AxiNSMono Enable");
}
public void Update()
{
if (Time.time - lastinvokeTime < waittime)
return;
lastinvokeTime = Time.time;
if (act != null)
act.Invoke();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23d5745b8989af04d8a871b5c7b65d50
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -116,4 +116,19 @@ public class AxiNSWait_DeletePathDir : AxiNSWaitBase
{
result = AxiNS.instance.io.DeletePathDir(req.filePath);
}
}
public class AxiNSWait_DeletePathDirRecursively : AxiNSWaitBase
{
S_NSWAIT_Path req;
public bool result;
public AxiNSWait_DeletePathDirRecursively(string filePath)
{
req = new S_NSWAIT_Path() { filePath = filePath };
}
public override void Invoke()
{
result = AxiNS.instance.io.DeletePathDirRecursively(req.filePath);
}
}

View File

@ -4,21 +4,30 @@ using System.Threading;
public class AxiNSWaitHandle
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static Thread waitThread = new Thread(Loop);
static bool bSingleInit = false;
static Queue<AxiNSWaitBase> m_QueueReady = new Queue<AxiNSWaitBase>();
static Queue<AxiNSWaitBase> m_QueueWork = new Queue<AxiNSWaitBase>();
public void AddWait(AxiNSWaitBase wait)
{
InitInternalThread();
lock (m_QueueReady)
{
m_QueueReady.Enqueue(wait);
}
autoEvent.Set();
if (AxiNS.usedmultithreading)
{
InitInternalThread();
autoEvent.Set();
}
else
{
InitMonoInit();
}
}
#region 线
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static Thread waitThread = new Thread(Loop);
static bool bSingleInit = false;
static void InitInternalThread()
{
if (bSingleInit) return;
@ -30,27 +39,43 @@ public class AxiNSWaitHandle
{
while (autoEvent.WaitOne())
{
lock (m_QueueReady)
Do();
}
}
#endregion
#region 线
static bool bMonoInit = false;
static void InitMonoInit()
{
if (bMonoInit) return;
AxiNSMono.SetInvoke(Do,15);
bMonoInit = true;
}
#endregion
static void Do()
{
lock (m_QueueReady)
{
while (m_QueueReady.Count > 0)
{
while (m_QueueReady.Count > 0)
{
m_QueueWork.Enqueue(m_QueueReady.Dequeue());
}
m_QueueWork.Enqueue(m_QueueReady.Dequeue());
}
while (m_QueueWork.Count > 0)
}
while (m_QueueWork.Count > 0)
{
AxiNSWaitBase wait = m_QueueWork.Dequeue();
try
{
AxiNSWaitBase wait = m_QueueWork.Dequeue();
try
{
wait.Invoke();
}
catch (Exception ex)
{
wait.errmsg = ex.ToString();
UnityEngine.Debug.Log(ex.ToString());
}
wait.SetDone();
wait.Invoke();
}
catch (Exception ex)
{
wait.errmsg = ex.ToString();
UnityEngine.Debug.Log(ex.ToString());
}
wait.SetDone();
}
}
}