ro-webgl/Assets/Src/UI/CsUIPage/Core/ExecuteSequenceData.cs
2025-04-05 22:20:37 +08:00

245 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
namespace CSUI
{
public class ExecuteSequenceData
{
private bool? isExecuting;
private List<SequenceData> datas = new List<SequenceData>();
private FrameTimer timer;
public ExecuteSequenceData()
{
isExecuting = null;
datas = new List<SequenceData>();
}
public void Dispose()
{
isExecuting = null;
datas = null;
StopTimer();
}
public void Reset()
{
Dispose();
datas = new List<SequenceData>();
}
public void ClearDatas()
{
datas = new List<SequenceData>();
StopTimer();
}
// 核心数据结构
public enum ExecuteSequenceType
{
Func,
FuncAfterListener,
Listener,
UIViewFunc,
UIViewFuncAfterListener,
Interval
}
public class SequenceData
{
public ExecuteSequenceType type;
public bool forceAfterErr;
public object owner;
public Action<object> ownerFunc; // 可以是委托或方法名
public object[] args;
public int id;
public string eventName;
public string funcName;
public float duration;
public bool isFrame;
}
// 添加执行函数
public void AppendFunc(bool forceAfterErr, object owner, Action<object> ownerFunc, params object[] args)
{
if (ownerFunc == null) return;
var data = new SequenceData
{
type = ExecuteSequenceType.Func,
forceAfterErr = forceAfterErr,
owner = owner,
ownerFunc = ownerFunc,
args = args
};
AppendData(data);
}
public void InsertNextFunc(bool forceAfterErr, object owner, Action<object> ownerFunc, params object[] args)
{
if (ownerFunc == null) return;
var data = new SequenceData
{
type = ExecuteSequenceType.Func,
forceAfterErr = forceAfterErr,
owner = owner,
ownerFunc = ownerFunc,
args = args
};
InsertDataNext(data);
}
public int FindFunc(bool forceAfterErr, object owner, Delegate ownerFunc, params object[] args)
{
if (ownerFunc == null || datas == null) return 0;
for (int i = 0; i < datas.Count; i++)
{
var data = datas[i];
if (data.type == ExecuteSequenceType.Func &&
data.forceAfterErr == forceAfterErr &&
data.owner == owner &&
data.ownerFunc.Equals(ownerFunc))
{
if (CheckArgsSame(data.args, args))
{
return i;
}
}
}
return -1;
}
// 添加UI消息监听
public void AppendUIListener(int id, string eventName, float? timeOut = null)
{
if (string.IsNullOrEmpty(eventName)) return;
var data = new SequenceData
{
type = ExecuteSequenceType.Listener,
id = id,
eventName = eventName,
duration = timeOut ?? 0
};
AppendData(data);
}
// 添加延迟
public void AppendInterval(float duration)
{
if (duration <= 0) return;
var data = new SequenceData
{
type = ExecuteSequenceType.Interval,
duration = duration,
isFrame = false
};
AppendData(data);
}
// 添加帧延迟
public void AppendFrameInterval(int frameCount)
{
if (frameCount <= 0) return;
var data = new SequenceData
{
type = ExecuteSequenceType.Interval,
duration = frameCount,
isFrame = true
};
AppendData(data);
}
public bool HasDelayMethod()
{
if (datas == null) return false;
foreach (var data in datas)
{
if (data.type == ExecuteSequenceType.Interval ||
data.type == ExecuteSequenceType.Listener)
{
return true;
}
}
return false;
}
// 数据操作
private void AppendData(SequenceData data)
{
datas.Add(data);
}
private void InsertDataNext(SequenceData data)
{
datas.Insert(0, data);
}
private bool CheckArgsSame(object[] args1, object[] args2)
{
if (args1 == null || args2 == null) return args1 == args2;
if (args1.Length != args2.Length) return false;
for (int i = 0; i < args1.Length; i++)
{
if (!Equals(args1[i], args2[i]))
{
return false;
}
}
return true;
}
// 获取当前执行数据
public SequenceData GetCurExecuteData()
{
return datas.Count > 0 ? datas[0] : null;
}
public void RemoveCurExecuteData()
{
if (datas.Count > 0)
{
datas.RemoveAt(0);
}
}
// 计时器控制
public void StartTimer(Action func, SequenceData data)
{
StopTimer();
if (data.isFrame)
{
timer = new FrameTimer(func, (int)data.duration);
}
else
{
timer = new FrameTimer(func, (int)data.duration, 1);
}
timer.Start();
}
public void StopTimer()
{
timer.Stop();
timer = null;
}
public void InsertNextUIListener(int pageId, string eventName, float timeout = 0)
{
var data = new SequenceData
{
type = ExecuteSequenceType.Listener,
id = pageId,
eventName = eventName,
duration = timeout
};
InsertDataNext(data);
}
}
}