From b99b7f27432766dc5d82aedb89376ccc3b4abdf8 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Thu, 11 Dec 2025 18:03:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96,=20=E6=9A=82=E6=97=B6=E6=94=BE=E5=BC=83=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Convention | 2 +- Assets/Scripts/Editor/CustomEditor.cs | 13 +++ Assets/Scripts/Framework/DDT.cs | 21 ++++- .../Framework/GameContent/GameController.cs | 57 ++++++------ Assets/Scripts/Framework/ScriptableObject.cs | 65 +++++++------ .../DefaultScriptableObjectInstantiate.cs | 91 +++++++------------ Assets/Scripts/Framework/[RScript] | 2 +- Assets/Scripts/MoreSpline/SplineCore.cs | 22 +++-- Assets/Scripts/MoreSpline/SplineNode.cs | 15 +-- 9 files changed, 150 insertions(+), 138 deletions(-) diff --git a/Assets/Convention b/Assets/Convention index 223df3f..a3483f2 160000 --- a/Assets/Convention +++ b/Assets/Convention @@ -1 +1 @@ -Subproject commit 223df3fb9168796af50eadf9c1ed87cc1c9ec5e8 +Subproject commit a3483f23d8e04442b414762a95a130226a4f65bc diff --git a/Assets/Scripts/Editor/CustomEditor.cs b/Assets/Scripts/Editor/CustomEditor.cs index d6e3c78..4501293 100644 --- a/Assets/Scripts/Editor/CustomEditor.cs +++ b/Assets/Scripts/Editor/CustomEditor.cs @@ -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 +{ + +} diff --git a/Assets/Scripts/Framework/DDT.cs b/Assets/Scripts/Framework/DDT.cs index 87be7f4..686847e 100644 --- a/Assets/Scripts/Framework/DDT.cs +++ b/Assets/Scripts/Framework/DDT.cs @@ -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(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 d_Datas = new(); + protected override IEnumerator DoSomethingDuringApplyScript() + { + yield return base.DoSomethingDuringApplyScript(); + for (int i = 0; i < Count; i++) + d_Datas.Add(Datas[i]); + } + +#endif } } diff --git a/Assets/Scripts/Framework/GameContent/GameController.cs b/Assets/Scripts/Framework/GameContent/GameController.cs index 0a47dfa..0fa3f6c 100644 --- a/Assets/Scripts/Framework/GameContent/GameController.cs +++ b/Assets/Scripts/Framework/GameContent/GameController.cs @@ -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); - Stack loadingTask = new(); - loadingTask.Push(rootGameObject.ParseFromScriptFile2Expr(rootObject)); - float waitClock = Time.realtimeSinceStartup; - Dictionary DebugCounter = new(); - while (loadingTask.Count > 0) + static IEnumerator Foo(IEnumerator ir) { - // 防止大量无延迟函数如NewSubObject的使用导致的假死机 - if (Time.realtimeSinceStartup - waitClock > 0.1f) + Stack loadingTask = new(); + loadingTask.Push(ir); + while (loadingTask.Count > 0) { - 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(); + } } - if (loadingTask.Peek().MoveNext()) - { - if (loadingTask.Peek().Current is IEnumerator next) - loadingTask.Push(next); - } - else - { - loadingTask.Pop(); - } - yield return null; + yield break; } - int NDFSCount = 0; - IEnumerator NDFS(ScriptableObject current) + 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); diff --git a/Assets/Scripts/Framework/ScriptableObject.cs b/Assets/Scripts/Framework/ScriptableObject.cs index 5799ca1..7f222d7 100644 --- a/Assets/Scripts/Framework/ScriptableObject.cs +++ b/Assets/Scripts/Framework/ScriptableObject.cs @@ -111,7 +111,7 @@ namespace Demo /// public partial class ScriptableObject { - public Dictionary ScriptableObjectContents = new(); + public readonly Dictionary 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 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,16 +507,18 @@ namespace Demo { yield break; } + if (IsScriptApply) + yield break; // 等待自身脚本解析完毕 while (this.IsParseScript2Expr) { - yield return null; - while (LoadingTaskCoroutineCount < MaxLoadingCoroutine && WaitingTaskForLoadingCoroutine.Count > 0) - { - LoadingTaskCoroutineCount++; - ConventionUtility.StartCoroutine(WaitingTaskForLoadingCoroutine.First.Value); - WaitingTaskForLoadingCoroutine.RemoveFirst(); - } + 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 = ""; foreach (var child in Childs) { ConventionUtility.StartCoroutine(child.UnloadScript()); } - if (IsScriptApply) - { - // 清理各种状态 - IsScriptApply = false; - // 清理Cache - // - // 减数 - ApplyScriptableObjectCounter--; - EnableScriptableObjectCounter++; - AllScriptableObjectCounterHierarchyItem.GetHierarchyItem().text = $"SOC: {ApplyScriptableObjectCounter}/{EnableScriptableObjectCounter}"; - } + yield return new WaitUntil(() => Childs.Any(x => x.isEnableScript == false) == false); + // 清理各种状态 + IsScriptApply = false; + // 清理Cache + // + // 减数 + ApplyScriptableObjectCounter--; + 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 = ""; diff --git a/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs b/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs index 25b058c..4fb4112 100644 --- a/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs +++ b/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs @@ -247,7 +247,6 @@ namespace Demo } private static readonly Dictionary s_FileLocker = new(); - private static readonly Dictionary s_RScriptEngineCache = new(); public IEnumerator ParseFromScriptFile2Expr(ToolFile file) { @@ -263,79 +262,59 @@ 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) + RScriptEngine engine = new(); + RScriptImportClass importClass = GenerateImport(); + RScriptVariables variables = GenerateVariables(this); + object locker; + if (lastHashFile.Exists() == false || lastHashFile.LoadAsText() != hash) { - lock (s_RScriptEngineCache) + lastHashFile.MustExistsPath(); + bin.MustExistsPath(); + lastHashFile.SaveAsText(hash); + var script = file.LoadAsText(); + + var structBin = engine.Compile(script, importClass, variables); + lock (s_FileLocker) { - RScriptEngine engine = new(); - RScriptImportClass importClass = GenerateImport(); - RScriptVariables variables = GenerateVariables(this); - object locker; - if (lastHashFile.Exists() == false || lastHashFile.LoadAsText() != hash) + if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false) { - lastHashFile.MustExistsPath(); - bin.MustExistsPath(); - lastHashFile.SaveAsText(hash); - var script = file.LoadAsText(); - - var structBin = engine.Compile(script, importClass, variables); - lock (s_FileLocker) - { - if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false) - { - s_FileLocker.Add(file.GetFullPath(), locker = new object()); - } - } - lock (locker) - { - bin.SaveAsBinary(RScriptSerializer.SerializeClass(structBin)); - } - step = engine.RunAsync(script, importClass, variables); + s_FileLocker.Add(file.GetFullPath(), locker = new object()); } - else - { - RScriptContext.SerializableClass structBin; - lock (s_FileLocker) - { - if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false) - { - s_FileLocker.Add(file.GetFullPath(), locker = new object()); - } - } - lock (locker) - { - structBin = RScriptSerializer.DeserializeClass(bin.LoadAsBinary()); - } - step = engine.RunAsync(structBin, importClass, variables); - - } - s_RScriptEngineCache.Add(file.GetFullPath(), engine); } + lock (locker) + { + bin.SaveAsBinary(RScriptSerializer.SerializeClass(structBin)); + } + step = engine.RunAsync(script, importClass, variables); } else { - var engine = s_RScriptEngineCache[file.GetFullPath()]; - lock (engine) + RScriptContext.SerializableClass structBin; + lock (s_FileLocker) { - engine.context.Variables["this"] = new() { data = this, type = this.GetType() }; - engine.context.Variables["self"] = new() { data = this, type = this.GetType() }; - step = engine.ReRunAsync(); + if (s_FileLocker.TryGetValue(file.GetFullPath(), out locker) == false) + { + s_FileLocker.Add(file.GetFullPath(), locker = new object()); + } } + lock (locker) + { + structBin = RScriptSerializer.DeserializeClass(bin.LoadAsBinary()); + } + step = engine.RunAsync(structBin, importClass, variables); + } - 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 { diff --git a/Assets/Scripts/Framework/[RScript] b/Assets/Scripts/Framework/[RScript] index e4b7dc0..0a7f6eb 160000 --- a/Assets/Scripts/Framework/[RScript] +++ b/Assets/Scripts/Framework/[RScript] @@ -1 +1 @@ -Subproject commit e4b7dc0f559d28177ef22aed219e97733738c1e3 +Subproject commit 0a7f6eb3625cc82e92aa949549d834cc4121f614 diff --git a/Assets/Scripts/MoreSpline/SplineCore.cs b/Assets/Scripts/MoreSpline/SplineCore.cs index 7c45176..2ac4ed8 100644 --- a/Assets/Scripts/MoreSpline/SplineCore.cs +++ b/Assets/Scripts/MoreSpline/SplineCore.cs @@ -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(); var core = result.GetOrAddComponent(); + result.m_MySplineComputer = core; core.multithreaded = true; return result; } [Content] private SplineComputer m_MySplineComputer; [Content] public int NodeContent = 0; - [Content] public readonly List MySplineNodes = new(); + [Content] public List 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(); - return m_MySplineComputer; - } - } + public SplineComputer MySplineComputer => m_MySplineComputer; + //{ + // get + // { + // if (m_MySplineComputer == null) + // m_MySplineComputer = this.GetComponent(); + // return m_MySplineComputer; + // } + //} /// /// 需要在子都添加后再应用脚本才能使得节点生效 diff --git a/Assets/Scripts/MoreSpline/SplineNode.cs b/Assets/Scripts/MoreSpline/SplineNode.cs index 22ba294..b9d342c 100644 --- a/Assets/Scripts/MoreSpline/SplineNode.cs +++ b/Assets/Scripts/MoreSpline/SplineNode.cs @@ -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(); + var node = new GameObject("", typeof(Node)).AddComponent(); + node.m_MyNode = node.GetOrAddComponent(); + 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(); - return m_MyNode; - } - } + public Node MyNode => m_MyNode; public void AddTo(SplineCore core) {