性能优化与检测, 防止假死机

This commit is contained in:
2025-12-09 15:12:25 +08:00
parent 5ab19e39f2
commit eebf283e12
6 changed files with 66 additions and 18 deletions

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
//[CustomEditor(typeof(Demo.ScriptableObject), true)] [CustomEditor(typeof(Demo.ScriptableObject), true)]
public class SOEditor : Convention.AbstractCustomEditor public class SOEditor : Convention.AbstractCustomEditor
{ {

View File

@@ -77,11 +77,11 @@ namespace Demo.Game
} }
protected override IEnumerator LoadFromImptCacheFile(ToolFile cacheFile) protected override IEnumerator LoadFromImptCacheFile(ToolFile cacheFile)
{ {
using var stream = File.OpenWrite(cacheFile.GetFullPath()); using var stream = File.OpenRead(cacheFile.GetFullPath());
using var reader = new BinaryReader(stream); using var reader = new BinaryReader(stream);
int length = reader.ReadInt32(); Count = reader.ReadInt32();
Datas = new NativeArray<float>(length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); Datas = new NativeArray<float>(Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
for (int i = 0; i < length; i++) for (int i = 0; i < Count; i++)
{ {
Datas[i] = reader.ReadSingle(); Datas[i] = reader.ReadSingle();
} }

View File

@@ -4,6 +4,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Unity.Cinemachine; using Unity.Cinemachine;
using Unity.VisualScripting;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
@@ -200,7 +201,29 @@ namespace Demo.Game
rootGameObject.SetContent(nameof(SongOffset), SongOffset); rootGameObject.SetContent(nameof(SongOffset), SongOffset);
rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0); rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0);
rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length); rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length);
yield return rootGameObject.ParseFromScriptFile2Expr(rootObject); Stack<IEnumerator> loadingTask = new();
loadingTask.Push(rootGameObject.ParseFromScriptFile2Expr(rootObject));
float waitClock = Time.realtimeSinceStartup;
Dictionary<Type, int> DebugCounter = new();
while (loadingTask.Count > 0)
{
// 防止大量无延迟函数如NewSubObject的使用导致的假死机
if (Time.realtimeSinceStartup - waitClock > 0.1f)
{
yield return null;
waitClock = Time.realtimeSinceStartup;
}
if (loadingTask.Peek().MoveNext())
{
if (loadingTask.Peek().Current is IEnumerator next)
loadingTask.Push(next);
}
else
{
loadingTask.Pop();
}
yield return null;
}
int NDFSCount = 0; int NDFSCount = 0;
IEnumerator NDFS(ScriptableObject current) IEnumerator NDFS(ScriptableObject current)
{ {

View File

@@ -309,6 +309,11 @@ namespace Demo
#region LoadSubScript #region LoadSubScript
internal static int LoadingTaskCoroutineCount { get; set; } = 0;
internal readonly static LinkedList<IEnumerator> WaitingTaskForLoadingCoroutine = new();
private readonly static WaitForEndOfFrame WaitForEndOfFrameInstance = new();
private const int MaxLoadingCoroutine = 100;
/// <summary> /// <summary>
/// 创建基于子脚本的实例对象 /// 创建基于子脚本的实例对象
/// </summary> /// </summary>
@@ -345,7 +350,22 @@ namespace Demo
Childs.Add(child); Childs.Add(child);
// Load Child Script // Load Child Script
ConventionUtility.StartCoroutine(child.ParseFromScriptFile2Expr(file)); IEnumerator Foo()
{
// 缓存并延迟运行
yield return WaitForEndOfFrameInstance;
yield return child.ParseFromScriptFile2Expr(file);
LoadingTaskCoroutineCount--;
}
child.IsParseScript2Expr = true;
WaitingTaskForLoadingCoroutine.AddLast(Foo());
while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0)
{
LoadingTaskCoroutineCount++;
ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value);
WaitingTaskForLoadingCoroutine.RemoveFirst();
}
return child; return child;
} }
@@ -481,6 +501,12 @@ namespace Demo
while (this.IsParseScript2Expr) while (this.IsParseScript2Expr)
{ {
yield return null; yield return null;
while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0)
{
LoadingTaskCoroutineCount++;
ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value);
WaitingTaskForLoadingCoroutine.RemoveFirst();
}
} }
yield return DoSomethingDuringApplyScript(); yield return DoSomethingDuringApplyScript();
// 增数 // 增数

View File

@@ -251,7 +251,6 @@ namespace Demo
public IEnumerator ParseFromScriptFile2Expr(ToolFile file) public IEnumerator ParseFromScriptFile2Expr(ToolFile file)
{ {
float parseStartTime = Time.realtimeSinceStartup;
IsParseScript2Expr = true; IsParseScript2Expr = true;
try try
{ {
@@ -342,15 +341,11 @@ namespace Demo
finally finally
{ {
IsParseScript2Expr = false; IsParseScript2Expr = false;
float parseEndTime = Time.realtimeSinceStartup;
float parseElapsed = (parseEndTime - parseStartTime) * 1000f;
Debug.Log($"[{nameof(ParseFromScriptFile2Expr)}] {file.GetFullPath()} 耗时: {parseElapsed:F2} ms", this);
} }
} }
public IEnumerator ParseScript2Expr(string script) public IEnumerator ParseScript2Expr(string script)
{ {
float parseStartTime = Time.realtimeSinceStartup;
IsParseScript2Expr = true; IsParseScript2Expr = true;
try try
{ {
@@ -364,9 +359,6 @@ namespace Demo
finally finally
{ {
IsParseScript2Expr = false; IsParseScript2Expr = false;
float parseEndTime = Time.realtimeSinceStartup;
float parseElapsed = (parseEndTime - parseStartTime) * 1000f;
Debug.Log($"[{nameof(ParseScript2Expr)}] {this.ScriptName} 耗时: {parseElapsed:F2} ms", this);
} }
} }
} }

View File

@@ -137,9 +137,16 @@ namespace Demo.Game
{ {
yield return base.DoSomethingDuringApplyScript(); yield return base.DoSomethingDuringApplyScript();
MyMeshGenerator = this.GetOrAddComponent<TMeshGenerator>(); MyMeshGenerator = this.GetOrAddComponent<TMeshGenerator>();
MyMeshGenerator.spline = MySplineCore.MySplineComputer; if (MySplineCore)
SetupMeshGenerator(MyMeshGenerator); {
MyMeshGenerator.RebuildImmediate(); MyMeshGenerator.spline = MySplineCore.MySplineComputer;
SetupMeshGenerator(MyMeshGenerator);
MyMeshGenerator.RebuildImmediate();
}
else
{
Debug.LogError($"{nameof(MySplineCore)} not setup", this);
}
} }
#region SetupMeshGenerator #region SetupMeshGenerator