修复了一些bug(包含窗口预制体中的错误与{}列表解析存在死循环的错误)

This commit is contained in:
2025-10-04 23:09:46 +08:00
parent 1ecb1b0ba4
commit 84e31fe63a
16 changed files with 2590 additions and 832 deletions

View File

@@ -35,8 +35,7 @@ namespace Demo
public static (string functionName, string[] arguments) ParseFunctionCall(string input)
{
// 匹配函数名和参数部分
string pattern = @"^(\w+)\s*\(\s*(.*?)\s*\)\s*;?$";
Match match = Regex.Match(input, pattern);
Match match = Regex.Match(input, @"^(\w+)\s*\(\s*(.*?)\s*\)\s*;?$");
if (!match.Success)
return (null, new string[0]);
@@ -56,14 +55,84 @@ namespace Demo
if (string.IsNullOrWhiteSpace(argumentsString))
return new string[0];
// 处理字符串字面量和普通参数的正则表达式
string argPattern = @"""(?:[^""\\]|\\.)*""|[^,]+";
var arguments = new List<string>();
int i = 0;
while (i < argumentsString.Length)
{
// 跳过空白字符
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
i++;
// 越界检查
if (i >= argumentsString.Length)
break;
string argument = ExtractArgument(argumentsString, ref i);
if (!string.IsNullOrEmpty(argument))
arguments.Add(argument.Trim());
return Regex.Matches(argumentsString, argPattern)
.Cast<Match>()
.Select(m => m.Value.Trim())
.Where(arg => !string.IsNullOrEmpty(arg))
.ToArray();
// 跳过空白字符
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
i++;
// 越界检查
if (i >= argumentsString.Length)
break;
// 必定是逗号, 否则异常情况
if (argumentsString[i] != ',')
throw new InvalidOperationException("Parser is invalid logic");
i++;
}
return arguments.ToArray();
}
// 提取单个参数的方法,支持花括号和字符串字面量
private static string ExtractArgument(string input, ref int index)
{
int start = index;
if (input[index] == '"')
{
// 处理字符串字面量
index++; // 跳过开始的引号
while (index < input.Length)
{
if (input[index] == '"' && (index == 0 || input[index - 1] != '\\'))
{
index++; // 跳过结束的引号
break;
}
index++;
}
}
else if (input[index] == '{')
{
// 处理花括号内的内容
int braceCount = 0;
while (index < input.Length)
{
if (input[index] == '{')
braceCount++;
else if (input[index] == '}')
braceCount--;
index++;
if (braceCount == 0)
break;
}
}
else
{
// 处理普通参数(直到遇到逗号)
while (index < input.Length && input[index] != ',')
index++;
}
return input[start..index];
}
}
@@ -396,6 +465,28 @@ namespace Demo
}
}
public partial class ScriptableObject
{
[Content] public int UpdatePerFrame = 1;
/// <summary>
/// 指定多少个<see cref="TickType.Update"/>状态的<see cref="UpdateTicks(float, float, TickType)"/>执行一次更新,不会影响到子物体
/// 属于性能优化的高级选项
/// </summary>
/// <param name="frame">间隔帧数, 小于等于1的值代表无论如何都会更新</param>
[ScriptableCall(@"
<summary>
指定多少个Update状态的UpdateTicks执行一次更新,不会影响到子物体
属于性能优化的高级选项
</summary>
<param name=""frame"">间隔帧数, 小于等于1的值代表无论如何都会更新</param>
")]
public void SetUpdatePerFrame(string frame)
{
UpdatePerFrame = Mathf.Max(1, int.Parse(frame));
}
}
/// <summary>
/// <para>使用<see cref="ScriptableCallAttribute"/>标记可编辑脚本所能够调用的函数,并附加注释</para>
/// <para>使用<see cref="DefaultScriptAttribute"/>标记派生类,并附加默认模板</para>
@@ -800,6 +891,7 @@ namespace Demo
//LateUpdate
}
[Content, SerializeField] private int ScriptUpdateCounter = 0;
public void ScriptUpdate(float currentTime, float deltaTime, TickType tickType)
{
if (IsEnableUpdate == false)
@@ -809,7 +901,13 @@ namespace Demo
#if UNITY_EDITOR
s_PreparePerfMarker.Begin(this);
#endif
UpdateTicks(currentTime, deltaTime, tickType);
// UpdateTicks
{
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);