diff --git a/Assets/Scripts/Framework/EditiorContent/ProjectCreateHelper.cs b/Assets/Scripts/Framework/EditiorContent/ProjectCreateHelper.cs index 8a73813..8665e46 100644 --- a/Assets/Scripts/Framework/EditiorContent/ProjectCreateHelper.cs +++ b/Assets/Scripts/Framework/EditiorContent/ProjectCreateHelper.cs @@ -23,6 +23,7 @@ namespace Demo.Editor // 绘制工具宏 stream.WriteLine("#define __build_in_pragma #"); stream.WriteLine("#define __build_in_to_text(x) #x"); + stream.WriteLine("#define this"); // 绘制类定义标识符 foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { @@ -44,6 +45,10 @@ namespace Demo.Editor foreach (var method in typeof(Mathf).GetMethods()) { stream.WriteLine($"#define {method.Name}({string.Join(',', from param in method.GetParameters() select param.Name)})"); + } + foreach (var curveType in Enum.GetNames(typeof(MathExtension.EaseCurveType))) + { + stream.WriteLine($"#define {curveType}"); } // 绘制label与goto stream.Write(@" diff --git a/Assets/Scripts/Framework/ScriptableObject.cs b/Assets/Scripts/Framework/ScriptableObject.cs index 5b30186..4071e10 100644 --- a/Assets/Scripts/Framework/ScriptableObject.cs +++ b/Assets/Scripts/Framework/ScriptableObject.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using Convention; +using Convention.RScript; using Convention.WindowsUI.Variant; using Demo.Game; using Flee.PublicTypes; @@ -252,23 +253,7 @@ namespace Demo case ProjectDefaultFileStyle.CPP: { fs.WriteLine($"#include \"{typeName}.helper.h\""); - if (attr == null) - { - var scriptCalls = (from info in type.GetMembers(BindingFlags.Public | BindingFlags.Instance) - where info is MethodInfo - where info.GetCustomAttribute(false) != null - select info as MethodInfo).ToList(); - if (scriptCalls.Count > 0) - { - foreach (var scriptCall in scriptCalls) - { - fs.WriteLine($"#ifndef {scriptCall.Name}"); - fs.WriteLine($"#define {scriptCall.Name}({string.Join(',', (from param in scriptCall.GetParameters() select param.Name))})"); - fs.WriteLine($"#endif"); - } - } - } - else + if (attr != null) { var text = attr.DefaultScript; fs.Write(text); @@ -649,6 +634,11 @@ namespace Demo public string ScriptPath; public string ScriptTypename; + // Hierarchy + + public PropertiesWindow.ItemEntry MyHierarchyItem; + public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem; + public void EnableScript(string sourcePath, string scriptPath, string scriptType, ScriptableObject parent) { #if UNITY_EDITOR||Using_ProfilerMarker @@ -699,8 +689,204 @@ namespace Demo /// public partial class ScriptableObject { + public static Dictionary FastScriptableObjectTypen = new(); + public static int AllScriptableObjectCounter = 0; +#if UNITY_EDITOR||Using_ProfilerMarker + public ProfilerMarker s_PreparePerfMarker; +#endif + + #region LoadSubScript + + private static ScriptableObject LastLoadedScriptableObject; + + public IEnumerator DoLoadSubScriptAsync([In] string type, [In] string path, [Opt] Action callback) + { + // 鍒ゆ柇绫诲瀷鏄惁鍚堟硶 + if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false) + { + Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this); + callback?.Invoke(null); + yield break; + } + // 鐢熸垚瀵硅薄 + var child = creater(); + // 璺緞棰勫鐞 + if (path.Replace('\\', '/').ToLower().StartsWith(RootObjectQuickPath)) + path = $"{new ToolFile(GetRoot().SourcePath) | path[RootObjectQuickPath.Length..]}"; + // 鑾峰彇鏂囦欢 + ToolFile file; + if (File.Exists(path)) + file = new(path); + else + file = new ToolFile(SourcePath) | path; + // 鎵句笉鍒拌剼鏈 + if (file.Exists() == false) + { + Debug.LogError($"{file}<{path}> is not found", this); + callback?.Invoke(null); + yield break; + } + child.ScriptName = file.GetName(true); + child.transform.SetParent(this.transform); + child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + child.transform.localScale = Vector3.one; + child.EnableScript(file.GetCurrentDirName(), Path.Combine(file.GetCurrentDirName(), file.GetName(false)), type, this); + + // Add Child + Childs.Add(child); + + // Load Child Script + yield return child.LoadScript(file.LoadAsText()); + + LastLoadedScriptableObject = child; + callback?.Invoke(child); + } + + /// + /// 鍔犺浇瀛愯剼鏈 + /// + /// 鎸囧畾绫诲瀷 + /// 鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 + [ScriptableCall(@" + +鍔犺浇瀛愯剼鏈 + +鎸囧畾绫诲瀷 +鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 +")] + public IEnumerator LoadSubScript([In] string type, [In] string path) + { + return DoLoadSubScriptAsync(type, path, null); + } + + /// + /// 鑾峰彇宸插姞杞界殑鑴氭湰瀵硅薄 + /// + /// 鏃犳硶鎵惧埌鏃跺皢杩斿洖绌 + [ScriptableCall(@" + +鑾峰彇宸插姞杞界殑鑴氭湰瀵硅薄 + +鏃犳硶鎵惧埌鏃跺皢杩斿洖绌 +")] + public ScriptableObject GetLoadedObject(string path) + { + return FindWithPath(path, false); + } + + /// + /// 鑾峰彇鐖惰剼鏈璞 + /// + /// + [ScriptableCall(@" + +鑾峰彇鐖惰剼鏈璞 + + +")] + public ScriptableObject GetParentObject() + { + return Parent; + } + + /// + /// 鑾峰彇涓婁竴涓姞杞界殑鑴氭湰瀵硅薄 + /// + /// + [ScriptableCall(@" + +鑾峰彇涓婁竴涓姞杞界殑鑴氭湰瀵硅薄 + + +")] + public ScriptableObject GetLastLoadedScriptableObject() + { + return LastLoadedScriptableObject; + } + + /* + /// + /// 寮傛鍔犺浇瀛愯剼鏈 + /// + /// 鎸囧畾绫诲瀷 + /// 鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 + [ScriptableCall(@" + +寮傛鍔犺浇瀛愯剼鏈 + +鎸囧畾绫诲瀷 +鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 +")] + public void LoadSubScriptAsync([In] string type, [In] string path) + { + StartCoroutine(DoLoadSubScriptAsync(type, path, null)); + } + */ + + #endregion + + private IEnumerator ParseScript2Expr(string script) + { + RScriptEngine engine = new(); + RScriptImportClass importClass = new() + { + typeof(Mathf), + }; + RScriptVariables variables = new() + { + { "this", new() { data = this, type = this.GetType() } }, + { "self", new() { data = this, type = this.GetType() } } + }; + return engine.RunAsync(script, importClass, variables); + } + + [Content] private bool IsEnableUpdate = false; + + public enum TickType + { + Reset, + Pause, + Start, + Update + } + + [Content, SerializeField] private int ScriptUpdateCounter = 0; + public void ScriptUpdate(float currentTime, float deltaTime, TickType tickType) + { + if (IsEnableUpdate == false) + return; + if (gameObject.activeInHierarchy == false) + return; +#if UNITY_EDITOR||Using_ProfilerMarker + s_PreparePerfMarker.Begin(this); +#endif + if (tickType == TickType.Reset) + { + ResetEnterGameStatus(); + } + // UpdateTicks + if (UpdatePerFrame > 0) + { + if (ScriptUpdateCounter % UpdatePerFrame == 0) + UpdateTicks(currentTime, deltaTime, tickType); + ScriptUpdateCounter += tickType == TickType.Update ? 1 : 0; + } + // Childs UpdateTicks + foreach (var child in Childs) + { + child.ScriptUpdate(currentTime, deltaTime, tickType); + } +#if UNITY_EDITOR||Using_ProfilerMarker + s_PreparePerfMarker.End(); +#endif + } + + protected virtual void UpdateTicks(float currentTime, float deltaTime, TickType tickType) + { + + } } /// @@ -710,12 +896,8 @@ namespace Demo public partial class ScriptableObject : SerializedMonoBehaviour, IHierarchyItemClickEventListener { - public static Dictionary FastScriptableObjectTypen = new(); public static bool IsAutoPlay = false; -#if UNITY_EDITOR||Using_ProfilerMarker - public ProfilerMarker s_PreparePerfMarker; -#endif public ScriptableObject Parent; public RootObject GetRoot() @@ -729,16 +911,9 @@ namespace Demo public List Childs = new(); - // Hierarchy - - public PropertiesWindow.ItemEntry MyHierarchyItem; - public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem; - public static int AllScriptableObjectCounter = 0; // Cache - public static Dictionary> MethodInvokerCache = new(); - public const string RootObjectQuickPath = "project/"; public ScriptableObject FindWithPath(string path, bool isMustExist = true) @@ -810,281 +985,6 @@ namespace Demo return result; } - public IEnumerator DoLoadSubScriptAsync([In] string type, [In] string path, [Opt] Action callback) - { - // 鍒ゆ柇绫诲瀷鏄惁鍚堟硶 - if (DefaultInstantiate.GetScriptableObjectInstantiate().TryGetValue(type, out var creater) == false) - { - Debug.LogError($"{type} is not exist or {type}'s Instantiater is not valid", this); - callback?.Invoke(null); - yield break; - } - // 鐢熸垚瀵硅薄 - var child = creater(); - // 璺緞棰勫鐞 - if (path.Replace('\\', '/').ToLower().StartsWith(RootObjectQuickPath)) - path = $"{new ToolFile(GetRoot().SourcePath) | path[RootObjectQuickPath.Length..]}"; - // 鑾峰彇鏂囦欢 - ToolFile file; - if (File.Exists(path)) - file = new(path); - else - file = new ToolFile(SourcePath) | path; - // 鎵句笉鍒拌剼鏈 - if (file.Exists() == false) - { - Debug.LogError($"{file}<{path}> is not found", this); - callback?.Invoke(null); - yield break; - } - child.ScriptName = file.GetName(true); - child.transform.SetParent(this.transform); - child.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); - child.transform.localScale = Vector3.one; - child.EnableScript(file.GetCurrentDirName(), Path.Combine(file.GetCurrentDirName(), file.GetName(false)), type, this); - - // Add Child - Childs.Add(child); - - // Load Child Script - yield return child.LoadScript(file.LoadAsText()); - - callback?.Invoke(child); - } - - /// - /// 鍔犺浇瀛愯剼鏈 - /// - /// 鎸囧畾绫诲瀷 - /// 鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 - [ScriptableCall(@" - -鍔犺浇瀛愯剼鏈 - -鎸囧畾绫诲瀷 -鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 -")] - public IEnumerator LoadSubScript([In] string type, [In] string path) - { - return DoLoadSubScriptAsync(type, path, null); - } - - /* - /// - /// 寮傛鍔犺浇瀛愯剼鏈 - /// - /// 鎸囧畾绫诲瀷 - /// 鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 - [ScriptableCall(@" - -寮傛鍔犺浇瀛愯剼鏈 - -鎸囧畾绫诲瀷 -鎸囧畾鑴氭湰锛屽彲鐢ㄥ喅瀹氳矾寰勬垨涓庡綋鍓嶈剼鏈洰褰曠殑鐩稿璺緞 -")] - public void LoadSubScriptAsync([In] string type, [In] string path) - { - StartCoroutine(DoLoadSubScriptAsync(type, path, null)); - } - */ - - private enum ParseStats - { - None, - Continue, - Break - } - - // TODO : 杩囧鐨勯昏緫閮芥尋鍦ㄨ繖閲, 闇瑕佹媶鍒 - // TODO : 濡備綍缁熻鏁翠釜娓告垙鍏冲崱鏄惁鍔犺浇瀹屾垚, 灏ゅ叾鏄澶勭殑resultEnumerator涓嶪LoadAssetBundle, 灏嗕細鍚屾椂瀛樺湪澶氭潯寮傛鍔犺浇鐨勬椂闂寸嚎 - private IEnumerator ParseScript2Expr(string script) - { - // 棰勫鐞 - var lines = script.Split('\n'); - string preprocessing = ""; - foreach (var line in lines) - { - var expr = line.Trim(); - //娉ㄩ噴璇彞(py椋庢牸涓巆椋庢牸) - if (expr.StartsWith('#') || expr.StartsWith("//")) - continue; - preprocessing += expr; - } - var exprs = preprocessing.Split(';'); - - ParseStats ParseCommandAndParamaterWords(int commandIterator, ref string command, ref string[] words, ref Dictionary withVariables) - { - var expr = exprs[commandIterator].Trim(); - //绌鸿鍙 - if (string.IsNullOrEmpty(expr)) - return ParseStats.Continue; - //浣滅敤鍩熸爣璇嗙 - if (expr.StartsWith('{') || expr.EndsWith('}')) - //蹇界暐瀵煎叆璇彞(py椋庢牸) - if (expr.StartsWith("import ") || expr.StartsWith("from ")) - return ParseStats.Continue; - //杩涘叆涓诲嚱鏁板悗涓柇璇诲彇 - if (expr.StartsWith("if __name__") || expr.StartsWith("int main") || expr.StartsWith("void main")) - return ParseStats.Break; - if (MethodInvokerCache.ContainsKey(this.GetType()) == false) - { - MethodInvokerCache.Add(this.GetType(), new()); - } - //鍑芥暟瑙f瀽 - (command, words, withVariables) = ScriptCallUtility.ParseFunctionCall(expr); - if (string.IsNullOrEmpty(command)) - return ParseStats.Continue; - for (int i = 0, e = words.Length; i < e; i++) - { - //鍘婚櫎 - words[i] = words[i].Trim('\"'); - } - - return ParseStats.None; - } - - // Runtime Structures - Dictionary commandLabels = new(); - for (int commandIterator = 0; commandIterator < exprs.Length; commandIterator++) - { - string command = null; - string[] words = null; - Dictionary withVariables = new(); - var stats = ParseCommandAndParamaterWords(commandIterator, ref command, ref words,ref withVariables); - if (stats == ParseStats.Continue) - continue; - else if (stats == ParseStats.Break) - break; - var expr = exprs[commandIterator].Trim(); - if (command=="label") - { - if(words.Length<1) - { - Debug.LogError($"in line \"{expr}\", label miss argument", this); - } - commandLabels[words[0]] = commandIterator; - } - } - // Main Loop - for (int commandIterator = 0; commandIterator < exprs.Length; commandIterator++) - { - // Run Stats - string command = null; - string[] words = null; - Dictionary withVariables = new(); - var stats = ParseCommandAndParamaterWords(commandIterator, ref command, ref words, ref withVariables); - if (stats == ParseStats.Continue) - continue; - else if (stats == ParseStats.Break) - break; - - // Logic - if (command == "label") - { - continue; - } - var expr = exprs[commandIterator].Trim(); - if (command == "goto") - { - if (words.Length < 3) - { - Debug.LogError($"in line \"{expr}\", goto need 3 arguments, but currently less", this); - yield break; - } - float a = Parse(words[0]), b = Parse(words[1]); - if (a > b) - { - commandIterator = commandLabels[words[2]]; - } - continue; - } - - // Functions - var paramsList = (from word in words where string.IsNullOrEmpty(word.Trim()) == false select (object)word.Trim()).ToArray(); - if (MethodInvokerCache[this.GetType()].TryGetValue(command, out MemberInfo commandInfo) == false) - { - var commandInfo_try = ConventionUtility.SeekMemberInfo(this, new Type[] { typeof(ScriptableCallAttribute) }, null); - commandInfo_try.RemoveAll(x => x.Name != command); - if (commandInfo_try.Count <= 0) - { - Debug.LogError($"in line {expr}, {command} is unable to invoke, because the function is not found", this); - continue; - } - commandInfo = commandInfo_try[0]; - MethodInvokerCache[this.GetType()].Add(command, commandInfo); - } - Debug.Log($"in line \"{expr}\" of \"{ScriptPath}\", {command} is try to invoke", this); - IEnumerator resultEnumerator = null; - - // 澶勭悊 with 瀛愬彞锛氫繚瀛樺綋鍓嶅彉閲忕姸鎬佸苟璁剧疆鏂板彉閲 - Dictionary originalVariables = new Dictionary(); - if (withVariables.Count > 0) - { - foreach (var kvp in withVariables) - { - // 淇濆瓨鍘熷鍊硷紙濡傛灉瀛樺湪锛 - if (ScriptContextSpace.TryGetValue(kvp.Key, out var originalValue)) - { - originalVariables[kvp.Key] = originalValue; - } - // 璁剧疆鏂板 - ScriptContextSpace[kvp.Key] = Parse(kvp.Value); - } - } - - try - { - // 璋冪敤鎴愬姛 - if (ConventionUtility.TryInvokeMember(commandInfo, this, out var invokeResult, paramsList) == true) - { - Debug.Log($"in line \"{expr}\" of \"{ScriptPath}\", {command} is invoke succeed", this); - // 灏ゅ叾鐢ㄤ簬鍔犺浇瀛愮被鏃 - if (invokeResult != null && invokeResult is IEnumerator _resultEnumerator) - { - resultEnumerator = _resultEnumerator; - } - } - // 璋冪敤澶辫触 - else - { - MethodInvokerCache[this.GetType()].Remove(command); - var attr = commandInfo.GetCustomAttribute(); - if (attr == null) - Debug.LogError($"in line \"{expr}\" of \"{ScriptPath}\", {command} is unable to invoke", this); - else - Debug.LogError($"in line \"{expr}\" of \"{ScriptPath}\", {command} is failed to invoke, see: {attr.Description}", this); - } - } - catch (Exception ex) - { - Debug.LogError($"in line \"{expr}\" of \"{ScriptPath}\", {command}({string.Join(',', words)}) is failed to invoke , see: {ex.Message}", this); - Debug.LogException(ex, this); - yield break; - } - - yield return resultEnumerator; - - // 鎭㈠ with 瀛愬彞涓殑鍙橀噺鐘舵 - if (withVariables.Count > 0) - { - foreach (var kvp in withVariables) - { - if (originalVariables.ContainsKey(kvp.Key)) - { - // 鎭㈠鍘熷鍊 - ScriptContextSpace[kvp.Key] = originalVariables[kvp.Key]; - } - else - { - // 鍒犻櫎涓嶅瓨鍦ㄧ殑鍙橀噺 - ScriptContextSpace.Remove(kvp.Key); - } - } - } - } - } - - [Content] private bool IsEnableUpdate = false; public virtual IEnumerator LoadScript(string script) { @@ -1140,51 +1040,6 @@ namespace Demo } } - public enum TickType - { - Reset, - Pause, - Start, - Update//, - //LateUpdate - } - - [Content, SerializeField] private int ScriptUpdateCounter = 0; - public void ScriptUpdate(float currentTime, float deltaTime, TickType tickType) - { - if (IsEnableUpdate == false) - return; - if (gameObject.activeInHierarchy == false) - return; -#if UNITY_EDITOR||Using_ProfilerMarker - s_PreparePerfMarker.Begin(this); -#endif - if (tickType == TickType.Reset) - { - ResetEnterGameStatus(); - } - // UpdateTicks - if (UpdatePerFrame > 0) - { - if (ScriptUpdateCounter % UpdatePerFrame == 0) - UpdateTicks(currentTime, deltaTime, tickType); - ScriptUpdateCounter += tickType == TickType.Update ? 1 : 0; - } - // Childs UpdateTicks - foreach (var child in Childs) - { - child.ScriptUpdate(currentTime, deltaTime, tickType); - } -#if UNITY_EDITOR||Using_ProfilerMarker - s_PreparePerfMarker.End(); -#endif - } - - protected virtual void UpdateTicks(float currentTime, float deltaTime, TickType tickType) - { - - } - public virtual void ResetEnterGameStatus() { ResetScriptableObjectEnterGameStatus(); diff --git a/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs b/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs index 39324e3..012609a 100644 --- a/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs +++ b/Assets/Scripts/Framework/ScriptableObjectInstantiate/DefaultScriptableObjectInstantiate.cs @@ -121,7 +121,7 @@ namespace Demo.Game { x = childFilePath[path2.Length..].TrimStart('\\', '/'); } - fs.Write($"\n{nameof(so.LoadSubScript)}({type}, \"{x}\");"); + fs.Write($"\nthis.{nameof(so.LoadSubScript)}({type}, \"{x}\");"); // 鏂板缓鏃舵坊鍔犳ā鏉垮唴瀹 using var childFileStream = File.AppendText(childFile); { diff --git a/Assets/Scripts/Framework/[RScript] b/Assets/Scripts/Framework/[RScript] index 90ae999..4f358c9 160000 --- a/Assets/Scripts/Framework/[RScript] +++ b/Assets/Scripts/Framework/[RScript] @@ -1 +1 @@ -Subproject commit 90ae999ba24d6e65738ce023238e561ce1497510 +Subproject commit 4f358c9664a77ffa0f5e400a1bd60b9694049540