Compare commits

...

2 Commits

Author SHA1 Message Date
a3483f23d8 更新迭代器函数 2025-12-11 18:02:49 +08:00
3db8bde1c2 新增Avoid拆分协程 2025-12-09 18:00:47 +08:00

View File

@@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Convention.WindowsUI; using Convention.WindowsUI;
using Demo.Game;
using UnityEditor; using UnityEditor;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor.Build; using UnityEditor.Build;
@@ -1271,7 +1272,11 @@ namespace Convention
#endif #endif
public static void InitExtensionEnv() public static void InitExtensionEnv()
{ {
UnityEngine.Application.quitting += () => CoroutineStarter = null; UnityEngine.Application.quitting += () =>
{
GameObject.Destroy(s_CoroutineStarter.gameObject);
s_CoroutineStarter = null;
};
InitExtensionEnvCalls(); InitExtensionEnvCalls();
GlobalConfig.InitExtensionEnv(); GlobalConfig.InitExtensionEnv();
@@ -1285,27 +1290,82 @@ namespace Convention
return MainThreadID == Thread.CurrentThread.ManagedThreadId; return MainThreadID == Thread.CurrentThread.ManagedThreadId;
} }
private static CoroutineMonoStarterUtil CoroutineStarter; private static CoroutineMonoStarterUtil s_CoroutineStarter;
private static CoroutineMonoStarterUtil CoroutineStarter
{
get
{
if (s_CoroutineStarter == null)
{
s_CoroutineStarter = new GameObject($"{nameof(ConventionUtility)}-{nameof(CoroutineStarter)}").AddComponent<CoroutineMonoStarterUtil>();
}
return s_CoroutineStarter;
}
}
public static GameObject Singleton => CoroutineStarter.gameObject; public static GameObject Singleton => CoroutineStarter.gameObject;
private class CoroutineMonoStarterUtil : MonoBehaviour private class CoroutineMonoStarterUtil : MonoBehaviour
{ {
internal float waitClock;
private void Update() private void Update()
{ {
waitClock = Time.realtimeSinceStartup;
MainThreadID = Thread.CurrentThread.ManagedThreadId; MainThreadID = Thread.CurrentThread.ManagedThreadId;
} }
private void OnDestroy() private void OnDestroy()
{ {
CoroutineStarter = null; s_CoroutineStarter = null;
}
}
/// <summary>
/// 包装即将用于协程的迭代器成为一个防止假死机的迭代器
/// </summary>
/// <param name="ir"></param>
/// <returns></returns>
public static IEnumerator AvoidFakeStop(IEnumerator ir, float fps = 5)
{
Stack<IEnumerator> loadingTask = new();
loadingTask.Push(ir);
float maxWaitClock = 1 / fps;
while (loadingTask.Count > 0)
{
// 防止大量无延迟函数的使用导致假死机
//if (Time.realtimeSinceStartup - CoroutineStarter.waitClock > maxWaitClock)
{
yield return null;
}
if (loadingTask.Peek().MoveNext())
{
if (loadingTask.Peek().Current is IEnumerator next)
loadingTask.Push(next);
}
else
{
loadingTask.Pop();
}
}
}
/// <summary>
/// 包装即将用于协程的迭代器成为一个防止假死机的迭代器
/// </summary>
/// <param name="ir"></param>
/// <returns></returns>
public static IEnumerator AvoidFakeStopWithoutDeepStack(IEnumerator ir, float fps = 5)
{
float maxWaitClock = 1 / fps;
while (ir.MoveNext())
{
// 防止大量无延迟函数的使用导致假死机
if (Time.realtimeSinceStartup - CoroutineStarter.waitClock > maxWaitClock)
{
yield return null;
}
} }
} }
public static Coroutine StartCoroutine(IEnumerator coroutine) public static Coroutine StartCoroutine(IEnumerator coroutine)
{ {
if (CoroutineStarter == null)
{
CoroutineStarter = new GameObject($"{nameof(ConventionUtility)}-{nameof(CoroutineStarter)}").AddComponent<CoroutineMonoStarterUtil>();
}
return CoroutineStarter.StartCoroutine(coroutine); return CoroutineStarter.StartCoroutine(coroutine);
} }
public static void CloseCoroutine(Coroutine coroutine) public static void CloseCoroutine(Coroutine coroutine)