加载性能优化, 暂时放弃异步加载

This commit is contained in:
2025-12-11 18:03:57 +08:00
parent eebf283e12
commit b99b7f2743
9 changed files with 150 additions and 138 deletions

View File

@@ -1,2 +1,15 @@
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Demo.Game.GameController), true)]
public class GameControllerEditor : Convention.AbstractCustomEditor
{
}
[CustomEditor(typeof(Demo.Editor.EditorController), true)]
public class EditorControllerEditor : Convention.AbstractCustomEditor
{
}

View File

@@ -61,7 +61,7 @@ namespace Demo.Game
Datas.Dispose();
}
#region MyRegion
#region Serialize
protected override bool IsImptSerialize => true;
protected override IEnumerator CreateAndLoadingImptCacheFile(ToolFile scriptFile, ToolFile cacheFile)
@@ -69,10 +69,10 @@ namespace Demo.Game
yield return this.ParseScript2Expr(scriptFile.LoadAsText());
using var stream = File.OpenWrite(cacheFile.GetFullPath());
using var writer = new BinaryWriter(stream);
writer.Write(Datas.Length);
foreach (var i in Datas)
writer.Write(Count);
for (int i = 0; i < Count; i++)
{
writer.Write(i);
writer.Write(Datas[i]);
}
}
protected override IEnumerator LoadFromImptCacheFile(ToolFile cacheFile)
@@ -80,7 +80,7 @@ namespace Demo.Game
using var stream = File.OpenRead(cacheFile.GetFullPath());
using var reader = new BinaryReader(stream);
Count = reader.ReadInt32();
Datas = new NativeArray<float>(Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
Datas.ResizeArray(Mathf.Max(128, Count));
for (int i = 0; i < Count; i++)
{
Datas[i] = reader.ReadSingle();
@@ -89,5 +89,16 @@ namespace Demo.Game
}
#endregion
#if UNITY_EDITOR
[Setting, SerializeField] private List<float> d_Datas = new();
protected override IEnumerator DoSomethingDuringApplyScript()
{
yield return base.DoSomethingDuringApplyScript();
for (int i = 0; i < Count; i++)
d_Datas.Add(Datas[i]);
}
#endif
}
}

View File

@@ -13,6 +13,14 @@ namespace Demo.Game
{
public partial class GameController : MonoBehaviour
{
#if UNITY_EDITOR
[Resources]
public void DebugGetScriptCounter()
{
Debug.Log(ScriptableObject.s_DebugContainer.Count, this);
}
#endif
[Resources, SerializeField] public BasicAudioSystem MainAudio;
[Resources, SerializeField] private CinemachineVirtualCameraBase MainCamera;
[Resources, SerializeField] public GlobalConfig MainConfig;
@@ -201,46 +209,37 @@ namespace Demo.Game
rootGameObject.SetContent(nameof(SongOffset), SongOffset);
rootGameObject.SetContent(nameof(IsAutoPlay), IsAutoPlay ? 1 : 0);
rootGameObject.SetContent("SongLength", MainAudio.CurrentClip.length);
static IEnumerator Foo(IEnumerator ir)
{
Stack<IEnumerator> loadingTask = new();
loadingTask.Push(rootGameObject.ParseFromScriptFile2Expr(rootObject));
float waitClock = Time.realtimeSinceStartup;
Dictionary<Type, int> DebugCounter = new();
loadingTask.Push(ir);
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 if (loadingTask.Peek().Current is ScriptableObject)
yield return null;
}
else
{
loadingTask.Pop();
}
yield return null;
}
int NDFSCount = 0;
IEnumerator NDFS(ScriptableObject current)
yield break;
}
yield return Foo(rootGameObject.ParseFromScriptFile2Expr(rootObject));//ConventionUtility.AvoidFakeStop(rootGameObject.ParseFromScriptFile2Expr(rootObject));
static void NDFS(ScriptableObject current)
{
foreach (var child in current.Childs)
{
ConventionUtility.StartCoroutine(NDFS(child));
NDFSCount++;
if(NDFSCount % 100 == 0)
{
yield return null;
}
NDFS(child);
}
if (current.IsScriptApply == false)
ConventionUtility.StartCoroutine(current.ApplyScript());
}
//yield return
ConventionUtility.StartCoroutine(NDFS(rootGameObject));
NDFS(rootGameObject);
float loadRootObjectEndTime = Time.realtimeSinceStartup;
float loadRootObjectElapsed = (loadRootObjectEndTime - loadRootObjectStartTime) * 1000f;
Debug.Log($"[GameInit] Load Root Object 耗时: {loadRootObjectElapsed:F2} ms", this);

View File

@@ -111,7 +111,7 @@ namespace Demo
/// </summary>
public partial class ScriptableObject
{
public Dictionary<string, float> ScriptableObjectContents = new();
public readonly Dictionary<string, float> ScriptableObjectContents = new();
[Convention.RScript.Variable.Attr.Method]
public float GetContent(string key)
@@ -120,10 +120,6 @@ namespace Demo
{
return result;
}
if (Parent != null)
{
return Parent.GetContent(key);
}
throw new InvalidOperationException($"Key {key} is not find in contnet");
}
@@ -254,6 +250,8 @@ namespace Demo
return;
}
this.Parent = parent;
if (parent != null)
this.ScriptableObjectContents.AddRange(parent.ScriptableObjectContents);
this.name = ScriptName;
@@ -470,9 +468,21 @@ namespace Demo
#endif
IHierarchyItemClickEventListener
{
#if UNITY_EDITOR
internal static readonly HashSet<ScriptableObject> s_DebugContainer = new();
private void Awake()
{
s_DebugContainer.Add(this);
}
private void OnDestroy()
{
s_DebugContainer.Remove(this);
}
#endif
protected virtual IEnumerator DoSomethingDuringApplyScript()
{
return null;
yield break;
}
[Content]
@@ -497,17 +507,19 @@ namespace Demo
{
yield break;
}
if (IsScriptApply)
yield break;
// 等待自身脚本解析完毕
while (this.IsParseScript2Expr)
{
yield return null;
yield return this;
}
while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0)
{
LoadingTaskCoroutineCount++;
ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value);
WaitingTaskForLoadingCoroutine.RemoveFirst();
}
}
yield return DoSomethingDuringApplyScript();
// 增数
{
@@ -525,36 +537,37 @@ namespace Demo
GetRoot().UpdateChilds[type] = new() { this };
}
}
// 释放资源
{
this.ScriptableObjectContents.Clear();
}
IsScriptApply = true;
}
public virtual IEnumerator UnloadScript()
{
if (EnsureEnableScript())
if (IsScriptApply)
{
this.name = "<Unloading>";
foreach (var child in Childs)
{
ConventionUtility.StartCoroutine(child.UnloadScript());
}
if (IsScriptApply)
{
yield return new WaitUntil(() => Childs.Any(x => x.isEnableScript == false) == false);
// 清理各种状态
IsScriptApply = false;
// 清理Cache
//
// 减数
ApplyScriptableObjectCounter--;
EnableScriptableObjectCounter++;
EnableScriptableObjectCounter--;
AllScriptableObjectCounterHierarchyItem.GetHierarchyItem().text = $"SOC: {ApplyScriptableObjectCounter}/{EnableScriptableObjectCounter}";
}
if (MyHierarchyItem != null)
{
// 卸载UI
MyHierarchyItem.Release();
MyHierarchyItem = null;
}
yield return new WaitUntil(() => Childs.Any(x => x.isEnableScript == false) == false);
this.isEnableScript = false;
this.Parent = null;
this.name = "<Unload>";

View File

@@ -247,7 +247,6 @@ namespace Demo
}
private static readonly Dictionary<string, object> s_FileLocker = new();
private static readonly Dictionary<string, RScriptEngine> s_RScriptEngineCache = new();
public IEnumerator ParseFromScriptFile2Expr(ToolFile file)
{
@@ -263,23 +262,16 @@ namespace Demo
{
lastHashFile.MustExistsPath();
lastHashFile.SaveAsText(hash);
yield return CreateAndLoadingImptCacheFile(file, bin);
yield return ConventionUtility.AvoidFakeStop(CreateAndLoadingImptCacheFile(file, bin));
}
else
{
yield return LoadFromImptCacheFile(bin);
yield return ConventionUtility.AvoidFakeStop(LoadFromImptCacheFile(bin));
}
}
else
{
bool is_engine_cached = false;
IEnumerator step = null;
lock (s_RScriptEngineCache)
is_engine_cached = s_RScriptEngineCache.ContainsKey(file.GetFullPath());
if (is_engine_cached == false)
{
lock (s_RScriptEngineCache)
{
RScriptEngine engine = new();
RScriptImportClass importClass = GenerateImport();
RScriptVariables variables = GenerateVariables(this);
@@ -322,20 +314,7 @@ namespace Demo
step = engine.RunAsync(structBin, importClass, variables);
}
s_RScriptEngineCache.Add(file.GetFullPath(), engine);
}
}
else
{
var engine = s_RScriptEngineCache[file.GetFullPath()];
lock (engine)
{
engine.context.Variables["this"] = new() { data = this, type = this.GetType() };
engine.context.Variables["self"] = new() { data = this, type = this.GetType() };
step = engine.ReRunAsync();
}
}
yield return step;
yield return step;// ConventionUtility.AvoidFakeStop(step);
}
}
finally
@@ -354,7 +333,7 @@ namespace Demo
RScriptVariables variables = GenerateVariables(this);
var step = engine.RunAsync(script, importClass, variables);
yield return step;
yield return step;//ConventionUtility.AvoidFakeStop(step);
}
finally
{

View File

@@ -50,31 +50,33 @@ namespace Demo.Game
public class SplineCore : ScriptableObject
{
protected override bool IsSelfEnableUpdate => false;
public static SplineCore Make()
{
SplineCore result = new GameObject("").AddComponent<SplineCore>();
var core = result.GetOrAddComponent<SplineComputer>();
result.m_MySplineComputer = core;
core.multithreaded = true;
return result;
}
[Content] private SplineComputer m_MySplineComputer;
[Content] public int NodeContent = 0;
[Content] public readonly List<SplineNode> MySplineNodes = new();
[Content] public List<SplineNode> MySplineNodes = new();
[Content] public SplineComputer.SampleMode MySampleMode = default;
[Content] public Spline.Type MyType = default;
public bool IsClose = false;
public SplineComputer MySplineComputer
{
get
{
if(m_MySplineComputer==null)
m_MySplineComputer= GetComponent<SplineComputer>();
return m_MySplineComputer;
}
}
public SplineComputer MySplineComputer => m_MySplineComputer;
//{
// get
// {
// if (m_MySplineComputer == null)
// m_MySplineComputer = this.GetComponent<SplineComputer>();
// return m_MySplineComputer;
// }
//}
/// <summary>
/// <see cref="SplineCore"/>需要在子<see cref="SplineNode"/>都添加后再应用脚本才能使得节点生效

View File

@@ -1,4 +1,5 @@
using System.Collections;
using Convention;
using Dreamteck.Splines;
using UnityEngine;
@@ -10,7 +11,9 @@ namespace Demo.Game
public static SplineNode Make()
{
return new GameObject("", typeof(Node)).AddComponent<SplineNode>();
var node = new GameObject("", typeof(Node)).AddComponent<SplineNode>();
node.m_MyNode = node.GetOrAddComponent<Node>();
return node;
}
private Node m_MyNode;
@@ -21,15 +24,7 @@ namespace Demo.Game
public int MyNodeContent = 0;
public Node MyNode
{
get
{
if (m_MyNode == null)
m_MyNode = GetComponent<Node>();
return m_MyNode;
}
}
public Node MyNode => m_MyNode;
public void AddTo(SplineCore core)
{