进入RScript与this变量时期(未验证)
This commit is contained in:
@@ -23,6 +23,7 @@ namespace Demo.Editor
|
|||||||
// <20><><EFBFBD>ƹ<EFBFBD><C6B9>ߺ<EFBFBD>
|
// <20><><EFBFBD>ƹ<EFBFBD><C6B9>ߺ<EFBFBD>
|
||||||
stream.WriteLine("#define __build_in_pragma #");
|
stream.WriteLine("#define __build_in_pragma #");
|
||||||
stream.WriteLine("#define __build_in_to_text(x) #x");
|
stream.WriteLine("#define __build_in_to_text(x) #x");
|
||||||
|
stream.WriteLine("#define this");
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ඨ<EFBFBD><E0B6A8><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ඨ<EFBFBD><E0B6A8><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>
|
||||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
{
|
{
|
||||||
@@ -44,6 +45,10 @@ namespace Demo.Editor
|
|||||||
foreach (var method in typeof(Mathf).GetMethods())
|
foreach (var method in typeof(Mathf).GetMethods())
|
||||||
{
|
{
|
||||||
stream.WriteLine($"#define {method.Name}({string.Join(',', from param in method.GetParameters() select param.Name)})");
|
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}");
|
||||||
}
|
}
|
||||||
// <20><><EFBFBD><EFBFBD>label<65><6C>goto
|
// <20><><EFBFBD><EFBFBD>label<65><6C>goto
|
||||||
stream.Write(@"
|
stream.Write(@"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Convention;
|
using Convention;
|
||||||
|
using Convention.RScript;
|
||||||
using Convention.WindowsUI.Variant;
|
using Convention.WindowsUI.Variant;
|
||||||
using Demo.Game;
|
using Demo.Game;
|
||||||
using Flee.PublicTypes;
|
using Flee.PublicTypes;
|
||||||
@@ -252,23 +253,7 @@ namespace Demo
|
|||||||
case ProjectDefaultFileStyle.CPP:
|
case ProjectDefaultFileStyle.CPP:
|
||||||
{
|
{
|
||||||
fs.WriteLine($"#include \"{typeName}.helper.h\"");
|
fs.WriteLine($"#include \"{typeName}.helper.h\"");
|
||||||
if (attr == null)
|
if (attr != null)
|
||||||
{
|
|
||||||
var scriptCalls = (from info in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
|
|
||||||
where info is MethodInfo
|
|
||||||
where info.GetCustomAttribute<ScriptableCallAttribute>(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
|
|
||||||
{
|
{
|
||||||
var text = attr.DefaultScript;
|
var text = attr.DefaultScript;
|
||||||
fs.Write(text);
|
fs.Write(text);
|
||||||
@@ -649,6 +634,11 @@ namespace Demo
|
|||||||
public string ScriptPath;
|
public string ScriptPath;
|
||||||
public string ScriptTypename;
|
public string ScriptTypename;
|
||||||
|
|
||||||
|
// Hierarchy
|
||||||
|
|
||||||
|
public PropertiesWindow.ItemEntry MyHierarchyItem;
|
||||||
|
public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem;
|
||||||
|
|
||||||
public void EnableScript(string sourcePath, string scriptPath, string scriptType, ScriptableObject parent)
|
public void EnableScript(string sourcePath, string scriptPath, string scriptType, ScriptableObject parent)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR||Using_ProfilerMarker
|
#if UNITY_EDITOR||Using_ProfilerMarker
|
||||||
@@ -699,8 +689,204 @@ namespace Demo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ScriptableObject
|
public partial class ScriptableObject
|
||||||
{
|
{
|
||||||
|
public static Dictionary<string, Type> 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<ScriptableObject> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载子脚本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">指定类型</param>
|
||||||
|
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||||
|
[ScriptableCall(@"
|
||||||
|
<summary>
|
||||||
|
加载子脚本
|
||||||
|
</summary>
|
||||||
|
<param name=""type"">指定类型</param>
|
||||||
|
<param name=""path"">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||||
|
")]
|
||||||
|
public IEnumerator LoadSubScript([In] string type, [In] string path)
|
||||||
|
{
|
||||||
|
return DoLoadSubScriptAsync(type, path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已加载的脚本对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>无法找到时将返回空</returns>
|
||||||
|
[ScriptableCall(@"
|
||||||
|
<summary>
|
||||||
|
获取已加载的脚本对象
|
||||||
|
</summary>
|
||||||
|
<returns>无法找到时将返回空</returns>
|
||||||
|
")]
|
||||||
|
public ScriptableObject GetLoadedObject(string path)
|
||||||
|
{
|
||||||
|
return FindWithPath(path, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取父脚本对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[ScriptableCall(@"
|
||||||
|
<summary>
|
||||||
|
获取父脚本对象
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
")]
|
||||||
|
public ScriptableObject GetParentObject()
|
||||||
|
{
|
||||||
|
return Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取上一个加载的脚本对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[ScriptableCall(@"
|
||||||
|
<summary>
|
||||||
|
获取上一个加载的脚本对象
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
")]
|
||||||
|
public ScriptableObject GetLastLoadedScriptableObject()
|
||||||
|
{
|
||||||
|
return LastLoadedScriptableObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// <summary>
|
||||||
|
/// 异步加载子脚本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">指定类型</param>
|
||||||
|
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||||
|
[ScriptableCall(@"
|
||||||
|
<summary>
|
||||||
|
异步加载子脚本
|
||||||
|
</summary>
|
||||||
|
<param name=""type"">指定类型</param>
|
||||||
|
<param name=""path"">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
||||||
|
")]
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -710,12 +896,8 @@ namespace Demo
|
|||||||
public partial class ScriptableObject : SerializedMonoBehaviour, IHierarchyItemClickEventListener
|
public partial class ScriptableObject : SerializedMonoBehaviour, IHierarchyItemClickEventListener
|
||||||
{
|
{
|
||||||
|
|
||||||
public static Dictionary<string, Type> FastScriptableObjectTypen = new();
|
|
||||||
public static bool IsAutoPlay = false;
|
public static bool IsAutoPlay = false;
|
||||||
|
|
||||||
#if UNITY_EDITOR||Using_ProfilerMarker
|
|
||||||
public ProfilerMarker s_PreparePerfMarker;
|
|
||||||
#endif
|
|
||||||
public ScriptableObject Parent;
|
public ScriptableObject Parent;
|
||||||
|
|
||||||
public RootObject GetRoot()
|
public RootObject GetRoot()
|
||||||
@@ -729,16 +911,9 @@ namespace Demo
|
|||||||
|
|
||||||
public List<ScriptableObject> Childs = new();
|
public List<ScriptableObject> Childs = new();
|
||||||
|
|
||||||
// Hierarchy
|
|
||||||
|
|
||||||
public PropertiesWindow.ItemEntry MyHierarchyItem;
|
|
||||||
public static PropertiesWindow.ItemEntry AllScriptableObjectCounterHierarchyItem;
|
|
||||||
public static int AllScriptableObjectCounter = 0;
|
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
|
|
||||||
public static Dictionary<Type, Dictionary<string, MemberInfo>> MethodInvokerCache = new();
|
|
||||||
|
|
||||||
public const string RootObjectQuickPath = "project/";
|
public const string RootObjectQuickPath = "project/";
|
||||||
|
|
||||||
public ScriptableObject FindWithPath(string path, bool isMustExist = true)
|
public ScriptableObject FindWithPath(string path, bool isMustExist = true)
|
||||||
@@ -810,281 +985,6 @@ namespace Demo
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator DoLoadSubScriptAsync([In] string type, [In] string path, [Opt] Action<ScriptableObject> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载子脚本
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">指定类型</param>
|
|
||||||
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
|
||||||
[ScriptableCall(@"
|
|
||||||
<summary>
|
|
||||||
加载子脚本
|
|
||||||
</summary>
|
|
||||||
<param name=""type"">指定类型</param>
|
|
||||||
<param name=""path"">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
|
||||||
")]
|
|
||||||
public IEnumerator LoadSubScript([In] string type, [In] string path)
|
|
||||||
{
|
|
||||||
return DoLoadSubScriptAsync(type, path, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
/// <summary>
|
|
||||||
/// 异步加载子脚本
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">指定类型</param>
|
|
||||||
/// <param name="path">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
|
||||||
[ScriptableCall(@"
|
|
||||||
<summary>
|
|
||||||
异步加载子脚本
|
|
||||||
</summary>
|
|
||||||
<param name=""type"">指定类型</param>
|
|
||||||
<param name=""path"">指定脚本,可用决定路径或与当前脚本目录的相对路径</param>
|
|
||||||
")]
|
|
||||||
public void LoadSubScriptAsync([In] string type, [In] string path)
|
|
||||||
{
|
|
||||||
StartCoroutine(DoLoadSubScriptAsync(type, path, null));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private enum ParseStats
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Continue,
|
|
||||||
Break
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : 过多的逻辑都挤在这里, 需要拆分
|
|
||||||
// TODO : 如何统计整个游戏关卡是否加载完成, 尤其是此处的resultEnumerator与ILoadAssetBundle, 将会同时存在多条异步加载的时间线
|
|
||||||
private IEnumerator ParseScript2Expr(string script)
|
|
||||||
{
|
|
||||||
// 预处理
|
|
||||||
var lines = script.Split('\n');
|
|
||||||
string preprocessing = "";
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
var expr = line.Trim();
|
|
||||||
//注释语句(py风格与c风格)
|
|
||||||
if (expr.StartsWith('#') || expr.StartsWith("//"))
|
|
||||||
continue;
|
|
||||||
preprocessing += expr;
|
|
||||||
}
|
|
||||||
var exprs = preprocessing.Split(';');
|
|
||||||
|
|
||||||
ParseStats ParseCommandAndParamaterWords(int commandIterator, ref string command, ref string[] words, ref Dictionary<string,string> 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());
|
|
||||||
}
|
|
||||||
//函数解析
|
|
||||||
(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<string, int> commandLabels = new();
|
|
||||||
for (int commandIterator = 0; commandIterator < exprs.Length; commandIterator++)
|
|
||||||
{
|
|
||||||
string command = null;
|
|
||||||
string[] words = null;
|
|
||||||
Dictionary<string, string> 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<string, string> 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<string, float> originalVariables = new Dictionary<string, float>();
|
|
||||||
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<ScriptableCallAttribute>();
|
|
||||||
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)
|
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()
|
public virtual void ResetEnterGameStatus()
|
||||||
{
|
{
|
||||||
ResetScriptableObjectEnterGameStatus();
|
ResetScriptableObjectEnterGameStatus();
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ namespace Demo.Game
|
|||||||
{
|
{
|
||||||
x = childFilePath[path2.Length..].TrimStart('\\', '/');
|
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);
|
using var childFileStream = File.AppendText(childFile);
|
||||||
{
|
{
|
||||||
|
|||||||
Submodule Assets/Scripts/Framework/[RScript] updated: 90ae999ba2...4f358c9664
Reference in New Issue
Block a user