加载性能优化, 暂时放弃异步加载
This commit is contained in:
Submodule Assets/Convention updated: 223df3fb91...a3483f23d8
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>";
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Submodule Assets/Scripts/Framework/[RScript] updated: e4b7dc0f55...0a7f6eb362
@@ -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"/>都添加后再应用脚本才能使得节点生效
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user