1.介绍
ObjectWait组件用于等待,锁住方法继续执行直到收到返回通知。
2.原理解析(ObjectWait.cs)
1.ResultCallback
返回IWaitType类型的ETTask
public class ResultCallback<K>: IDestroyRun where K : struct, IWaitType
{
private ETTask<K> tcs;
//从对象池获取ETTask<IWaitType>
public ResultCallback()
{
this.tcs = ETTask<K>.Create(true);
}
public bool IsDisposed
{
get
{
return this.tcs == null;
}
}
public ETTask<K> Task => this.tcs;
//返回ETTask结果
public void SetResult(K k)
{
var t = tcs;
this.tcs = null;
t.SetResult(k);
}
public void SetResult()
{
var t = tcs;
this.tcs = null;
t.SetResult(new K() { Error = WaitTypeError.Destroy });
}
}
2.Wait
等待通知
//支持取消等待
public async ETTask<T> Wait<T>(ETCancellationToken cancellationToken = null) where T : struct, IWaitType
{
ResultCallback<T> tcs = new ResultCallback<T>();
Type type = typeof (T);
this.tcss.Add(type, tcs);
void CancelAction()
{
this.Notify(new T() { Error = WaitTypeError.Cancel });
}
T ret;
try
{
cancellationToken?.Add(CancelAction);
ret = await tcs.Task;
}
finally
{
cancellationToken?.Remove(CancelAction);
}
return ret;
}
//超时或者取消等待
public async ETTask<T> Wait<T>(int timeout, ETCancellationToken cancellationToken = null) where T : struct, IWaitType
{
ResultCallback<T> tcs = new ResultCallback<T>();
async ETTask WaitTimeout()
{
bool retV = await TimerComponent.Instance.WaitAsync(timeout, cancellationToken);
if (!retV)
{
return;
}
if (tcs.IsDisposed)
{
return;
}
Notify(new T() { Error = WaitTypeError.Timeout });
}
WaitTimeout().Coroutine();
this.tcss.Add(typeof (T), tcs);
void CancelAction()
{
Notify(new T() { Error = WaitTypeError.Cancel });
}
T ret;
try
{
cancellationToken?.Add(CancelAction);
ret = await tcs.Task;
}
finally
{
cancellationToken?.Remove(CancelAction);
}
return ret;
}
3.Notify
通知取消等待
//通知返回IWaitType取消等待
public void Notify<T>(T obj) where T : struct, IWaitType
{
Type type = typeof (T);
if (!this.tcss.TryGetValue(type, out object tcs))
{
return;
}
this.tcss.Remove(type);
((ResultCallback<T>) tcs).SetResult(obj);
}
3.使用
1.在WaitType.cs创建结构体
public struct Wait_UnitStop: IWaitType
{
public int Error
{
get;
set;
}
}
2.等待
// 一直等到unit发送stop
WaitType.Wait_UnitStop waitUnitStop = await objectWait.Wait<WaitType.Wait_UnitStop>(cancellationToken);
3.通知返回结构体取消等待
// 要取消上一次的移动协程
objectWait.Notify(new WaitType.Wait_UnitStop() { Error = WaitTypeError.Cancel });