public async ETTask <bool> WaitTillAsync(long tillTime, ETCancellationToken cancellationToken = null) { if (TimeHelper.ServerNow() >= tillTime) { return(true); } ETTaskCompletionSource <bool> tcs = new ETTaskCompletionSource <bool>(); TimerAction timer = EntityFactory.CreateWithParent <TimerAction, TimerClass, long, object>(this, TimerClass.OnceWaitTimer, 0, tcs, true); this.AddTimer(tillTime, timer); long timerId = timer.Id; void CancelAction() { if (this.Remove(timerId)) { tcs.SetResult(false); } } bool 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 { long timerId = TimerComponent.Instance.NewOnceTimer(TimeHelper.ServerNow() + timeout, () => { Notify(new T() { Error = WaitTypeError.Timeout }); }); ResultCallback <T> tcs = new ResultCallback <T>(timerId); 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); }
public async ETTask <bool> WaitTillAsync(long tillTime, ETCancellationToken cancellationToken) { if (TimeHelper.Now() > tillTime) { return(true); } ETTaskCompletionSource <bool> tcs = new ETTaskCompletionSource <bool>(); OnceWaitTimer timer = Entity.CreateWithParent <OnceWaitTimer /*, ETTaskCompletionSource<bool>*/>(this, tcs); this.timers[timer.Id] = timer; AddToTimeId(tillTime, timer.Id); long instanceId = timer.InstanceId; cancellationToken.Register(() => { if (instanceId != timer.InstanceId) { return; } timer.Run(false); this.Remove(timer.Id); }); return(await tcs.Task); }
public static async ETTask <bool> WaitAny(ETTask[] tasks, ETCancellationToken cancellationToken = null) { if (tasks.Length == 0) { return(false); } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(2); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } await coroutineBlocker.WaitAsync(); if (cancellationToken == null) { return(true); } return(!cancellationToken.IsCancel()); }
public async ETTask <bool> WaitTillAsync(long tillTime, ETCancellationToken cancellationToken = null) { if (TimeHelper.ServerNow() >= tillTime) { return(true); } ETTask <bool> tcs = ETTask <bool> .Create(true); TimerAction timer = this.AddChild <TimerAction, TimerClass, long, object>(TimerClass.OnceWaitTimer, 0, tcs, true); this.AddTimer(tillTime, timer); long timerId = timer.Id; void CancelAction() { if (this.Remove(timerId)) { tcs.SetResult(false); } } bool ret; try { cancellationToken?.Add(CancelAction); ret = await tcs; } finally { cancellationToken?.Remove(CancelAction); } return(ret); }
public async ETTask <bool> WaitAsync(long time, ETCancellationToken cancellationToken) { long tillTime = TimeHelper.Now() + time; if (TimeHelper.Now() > tillTime) { return(true); } ETTaskCompletionSource <bool> tcs = new ETTaskCompletionSource <bool>(); OnceWaitTimer timer = TimerFactory.Create <OnceWaitTimer, ETTaskCompletionSource <bool> >(tcs); this.timers[timer.InstanceId] = timer; AddToTimeId(tillTime, timer.InstanceId); long instanceId = timer.InstanceId; cancellationToken.Register(() => { if (instanceId != timer.InstanceId) { return; } timer.Run(false); this.Remove(timer.InstanceId); }); return(await tcs.Task); }
public static async ETTask <bool> StartMoveImp(this PathComponent self, ETCancellationToken cancellationToken) { DUnit unit = self.GetParent <DUnit>(); float speed = unit.GetComponent <NumericComponent>().GetAsFloat(NumericType.Speed); for (int i = 0; i < self.Path.List.Count; ++i) { Vector3 v = self.Path.List[i]; if (i == 0) { float serverf = (self.ServerPos - v).magnitude; if (serverf > 0.1f) { float clientf = (unit.Position - v).magnitude; speed = clientf / serverf * speed; } } unit.GetComponent <TurnComponent>().Turn(v); if (await unit.GetComponent <DMoveComponent>().MoveToAsync(v, speed, cancellationToken) == false) { return(false); } } return(true); }
public static async ETTask <T> Wait <T>(this ObjectWait self, ETCancellationToken cancellationToken = null) where T : struct, IWaitType { ResultCallback <T> tcs = new ResultCallback <T>(); Type type = typeof(T); self.tcss.Add(type, tcs); void CancelAction() { self.Notify(new T() { Error = WaitTypeError.Cancel }); } T ret; try { cancellationToken?.Add(CancelAction); ret = await tcs.Task; } finally { cancellationToken?.Remove(CancelAction); } return(ret); }
public static async ETTask MoveToAsync(this Unit unit, List <Vector3> path, ETCancellationToken cancellationToken = null) { float speed = unit.GetComponent <NumericComponent>().GetAsFloat(NumericType.Speed); if (speed < 0.01) { unit.SendStop(-1); return; } // 广播寻路路径 M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult(); m2CPathfindingResult.Id = unit.Id; for (int i = 0; i < path.Count; ++i) { Vector3 vector3 = path[i]; m2CPathfindingResult.Xs.Add(vector3.x); m2CPathfindingResult.Ys.Add(vector3.y); m2CPathfindingResult.Zs.Add(vector3.z); } MessageHelper.Broadcast(unit, m2CPathfindingResult); bool ret = await unit.GetComponent <MoveComponent>().MoveToAsync(path, speed); if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop { unit.SendStop(0); } }
public static async ETTask <bool> WaitAll(List <ETTask> tasks, ETCancellationToken cancellationToken = null) { if (tasks.Count == 0) { return(false); } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Count + 1); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } if (cancellationToken == null) { return(true); } return(!cancellationToken.IsCancel()); }
// 开启协程移动,每100毫秒移动一次,并且协程取消的时候会计算玩家真实移动 // 比方说玩家移动了2500毫秒,玩家有新的目标,这时旧的移动协程结束,将计算250毫秒移动的位置,而不是300毫秒移动的位置 public async ETTask StartMove(ETCancellationToken cancellationToken) { Unit unit = this.GetParent <Unit>(); this.StartPos = unit.Position; this.StartTime = TimeHelper.ClientNow(); float distance = (this.Target - this.StartPos).magnitude; if (Math.Abs(distance) < 0.1f) { return; } this.needTime = (long)(distance / this.Speed * 1000); TimerComponent timerComponent = Game.Scene.GetComponent <TimerComponent>(); // 协程如果取消,将算出玩家的真实位置,赋值给玩家 cancellationToken?.Add(() => { long timeNow = TimeHelper.ClientNow(); if (timeNow - this.StartTime >= this.needTime) { unit.Position = this.Target; } else { float amount = (timeNow - this.StartTime) * 1f / this.needTime; unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount); } }); while (true) { //新版TimerComponent实现不同于5.0的TimerComponent,需要自己判断是取消还是自然结束,并且return,否则将不会取消任务,并可能会造成cancellationToken泄漏 if (!await timerComponent.WaitAsync(50, cancellationToken)) { return; } long timeNow = TimeHelper.ClientNow(); if (timeNow - this.StartTime >= this.needTime) { unit.Position = this.Target; break; } float amount = (timeNow - this.StartTime) * 1f / this.needTime; unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount); } }
// 开启协程移动,每100毫秒移动一次,并且协程取消的时候会计算玩家真实移动 // 比方说玩家移动了2500毫秒,玩家有新的目标,这时旧的移动协程结束,将计算250毫秒移动的位置,而不是300毫秒移动的位置 public async ETTask StartMove(ETCancellationToken cancellationToken) { Unit unit = this.GetParent <Unit>(); this.StartPos = unit.Position; this.StartTime = TimeHelper.Now(); float distance = (this.Target - this.StartPos).magnitude; if (Math.Abs(distance) < 0.1f) { return; } this.needTime = (long)(distance / this.Speed * 1000); TimerComponent timerComponent = Game.Scene.GetComponent <TimerComponent>(); // 协程如果取消,将算出玩家的真实位置,赋值给玩家 cancellationToken.Register(() => { long timeNow = TimeHelper.Now(); if (timeNow - this.StartTime >= this.needTime) { unit.Position = this.Target; } else { float amount = (timeNow - this.StartTime) * 1f / this.needTime; unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount); } }); while (true) { await timerComponent.WaitAsync(50, cancellationToken); long timeNow = TimeHelper.Now(); if (timeNow - this.StartTime >= this.needTime) { unit.Position = this.Target; break; } float amount = (timeNow - this.StartTime) * 1f / this.needTime; unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount); } }
public static async ETTask <T> Wait <T>(this ObjectWait self, 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; } self.Notify(new T() { Error = WaitTypeError.Timeout }); } WaitTimeout().Coroutine(); self.tcss.Add(typeof(T), tcs); void CancelAction() { self.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 MoveToAsync(Vector3 target, ETCancellationToken cancellationToken) { // 新目标点离旧目标点太近,不设置新的 if ((target - this.Target).sqrMagnitude < 0.01f) { return; } // 距离当前位置太近 if ((this.GetParent <Unit>().Position - target).sqrMagnitude < 0.01f) { return; } this.Target = target; // 开启协程移动 await StartMove(cancellationToken); }
public static void Check(this AIComponent self) { if (self.Parent == null) { TimerComponent.Instance.Remove(ref self.Timer); return; } SortedDictionary <int, AIConfig> oneAI = AIConfigCategory.Instance.AIConfigs[self.AIConfigId]; foreach (AIConfig aiConfig in oneAI.Values) { AIDispatcherComponent.Instance.AIHandlers.TryGetValue(aiConfig.Name, out AAIHandler aaiHandler); if (aaiHandler == null) { Log.Error($"not found aihandler: {aiConfig.Name}"); continue; } int ret = aaiHandler.Check(self, aiConfig); if (ret != 0) { continue; } if (self.Current == aiConfig.Id) { break; } self.Cancel(); // 取消之前的行为 ETCancellationToken cancellationToken = new ETCancellationToken(); self.CancellationToken = cancellationToken; self.Current = aiConfig.Id; aaiHandler.Execute(self, aiConfig, cancellationToken).Coroutine(); return; } }
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 { if (cancellationToken != null) { if (!cancellationToken.IsCancel()) { cancellationToken?.Add(CancelAction); } else { Log.Error("cancellationToken 已经取消过了"); } } ret = await tcs.Task; } finally { cancellationToken?.Remove(CancelAction); } return(ret); }
public async ETTask <IResponse> Call(IRequest request, ETCancellationToken cancellationToken) { int rpcId = ++RpcId; RpcInfo rpcInfo = new RpcInfo(request); this.requestCallbacks[rpcId] = rpcInfo; request.RpcId = rpcId; this.Send(request); void CancelAction() { if (!this.requestCallbacks.TryGetValue(rpcId, out RpcInfo action)) { return; } this.requestCallbacks.Remove(rpcId); Type responseType = OpcodeTypeComponent.Instance.GetResponseType(action.Request.GetType()); IResponse response = (IResponse)Activator.CreateInstance(responseType); response.Error = ErrorCore.ERR_Cancel; action.Tcs.SetResult(response); } IResponse ret; try { cancellationToken?.Add(CancelAction); ret = await rpcInfo.Tcs; } finally { cancellationToken?.Remove(CancelAction); } return(ret); }
private static async ETTask StartMove_Internal(this UnitPathComponent self, ETCancellationToken cancellationToken) { for (int i = 0; i < self.Path.Count; ++i) { Vector3 v = self.Path[i]; float speed = 5; if (i == 0) { // 矫正移动速度 Vector3 clientPos = self.GetParent <Unit>().Position; float serverf = (self.ServerPos - v).magnitude; if (serverf > 0.1f) { float clientf = (clientPos - v).magnitude; speed = clientf / serverf * speed; } } self.Parent.GetComponent <TurnComponent>().Turn(v); await self.Parent.GetComponent <MoveComponent>().MoveToAsync(v, speed, cancellationToken); } }
public static async ETTask <bool> WaitAsync(this TimerComponent self, long time, ETCancellationToken cancellationToken = null) { if (time == 0) { return(true); } long tillTime = TimeHelper.ServerNow() + time; ETTask <bool> tcs = ETTask <bool> .Create(true); TimerAction timer = self.AddChild <TimerAction, TimerClass, long, int, object>(TimerClass.OnceWaitTimer, time, 0, tcs, true); self.AddTimer(tillTime, timer); long timerId = timer.Id; void CancelAction() { if (self.Remove(timerId)) { tcs.SetResult(false); } } bool ret; try { cancellationToken?.Add(CancelAction); ret = await tcs; } finally { cancellationToken?.Remove(CancelAction); } return(ret); }
// 可以多次调用,多次调用的话会取消上一次的协程 public static async ETTask FindPathMoveToAsync(this Unit unit, Vector3 target, ETCancellationToken cancellationToken = null) { float speed = unit.GetComponent <NumericComponent>().GetAsFloat(NumericType.Speed); if (speed < 0.001) { unit.SendStop(-1); return; } using (var list = ListComponent <Vector3> .Create()) { unit.Domain.GetComponent <RecastPathComponent>().SearchPath(10001, unit.Position, target, list.List); List <Vector3> path = list.List; if (path.Count < 2) { unit.SendStop(-2); return; } // 广播寻路路径 M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult(); m2CPathfindingResult.Id = unit.Id; for (int i = 0; i < list.List.Count; ++i) { Vector3 vector3 = list.List[i]; m2CPathfindingResult.Xs.Add(vector3.x); m2CPathfindingResult.Ys.Add(vector3.y); m2CPathfindingResult.Zs.Add(vector3.z); } MessageHelper.Broadcast(unit, m2CPathfindingResult); bool ret = await unit.GetComponent <MoveComponent>().MoveToAsync(path, speed); if (ret) // 如果返回false,说明被其它移动取消了,这时候不需要通知客户端stop { unit.SendStop(0); } } }
public static async ETTask <bool> WaitFrameAsync(this TimerComponent self, ETCancellationToken cancellationToken = null) { bool ret = await self.WaitAsync(1, cancellationToken); return(ret); }
// 可以多次调用,多次调用的话会取消上一次的协程 public static async ETTask <int> MoveToAsync(this Unit unit, Vector3 targetPos, ETCancellationToken cancellationToken = null) { C2M_PathfindingResult msg = new C2M_PathfindingResult(); unit.Domain.GetComponent <SessionComponent>().Session.Send(msg); ObjectWait objectWait = unit.GetComponent <ObjectWait>(); // 要取消上一次的移动协程 objectWait.Notify(new WaitType.Wait_UnitStop() { Error = WaitTypeError.Cancel }); // 一直等到unit发送stop WaitType.Wait_UnitStop waitUnitStop = await objectWait.Wait <WaitType.Wait_UnitStop>(); return(waitUnitStop.Error); }
public static async ETTask <bool> MoveToAsync(this MoveComponent self, List <Vector3> target, float speed, int turnTime = 100, ETCancellationToken cancellationToken = null) { self.Stop(); foreach (Vector3 v in target) { self.Targets.Add(v); } self.IsTurnHorizontal = true; self.TurnTime = turnTime; self.Speed = speed; ETTask <bool> tcs = ETTask <bool> .Create(); self.Callback = (ret) => { tcs.SetResult(ret); }; Game.EventSystem.Publish(new EventType.MoveStart() { Unit = self.GetParent <Unit>() }).Coroutine(); self.StartMove(); void CancelAction() { self.Stop(); } bool moveRet; try { cancellationToken?.Add(CancelAction); moveRet = await tcs; } finally { cancellationToken?.Remove(CancelAction); } if (moveRet) { Game.EventSystem.Publish(new EventType.MoveStop() { Unit = self.GetParent <Unit>() }).Coroutine(); } return(moveRet); }
public static async ETTask<int> MoveActionAsync(DUnit unit, Vector3 targetPos, ETCancellationToken cancellationToken = null) { NavMeshPath meshPath = new NavMeshPath(); NavMesh.CalculatePath(unit.Position, targetPos, 1, meshPath); if (unit.DomainScene().GetComponent<PVPComponent>().bePVP) { if (OperationerComponentSystem.IsOperationer(unit) == false) { return WaitTypeError.Success; } // PVP 发送移动消息,封包发送 C2M_DPathfindingResult msg = new C2M_DPathfindingResult(); msg.Id = unit.Id; msg.X = unit.Position.x; msg.Y = unit.Position.y; msg.Z = unit.Position.z; for (int i = 0; i < meshPath.corners.Length; i++) { msg.Xs.Add(meshPath.corners[i].x); msg.Ys.Add(meshPath.corners[i].y); msg.Zs.Add(meshPath.corners[i].z); } unit.Domain.GetComponent<SessionComponent>().Session.Send(msg); ObjectWait objectWait = unit.GetComponent<ObjectWait>(); objectWait.Notify(new WaitType.Wait_UnitStop() { Error = WaitTypeError.Cancel }); WaitType.Wait_UnitStop waitUnitStop = await objectWait.Wait<WaitType.Wait_UnitStop>(cancellationToken); return waitUnitStop.Error; } else { return await DMoveAction.MoveActionImpAsync(unit, meshPath.corners, unit.Position, cancellationToken); } }
public static async ETTask<int> MoveActionImpAsync(DUnit unit, Vector3[] paths, Vector3 serverpos, ETCancellationToken cancellationToken = null) { PathComponent pathComponent = unit.GetComponent<PathComponent>(); if (await pathComponent.StartMove(paths, serverpos, cancellationToken)) { ObjectWait objectWait = unit.GetComponent<ObjectWait>(); objectWait.Notify(new WaitType.Wait_UnitStop() { Error = WaitTypeError.Success }); return WaitTypeError.Success; } else { return WaitTypeError.Cancel; } }
// 协程编写必须可以取消 public abstract ETTask Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken);
public static async ETTask <bool> StartMove(this PathComponent self, Vector3[] paths, Vector3 servierpos, ETCancellationToken cancellationToken = null) { self.Path.List.Clear(); // 取消之前的移动协程 self.CancellationTokenSource?.Cancel(); if (cancellationToken == null) { self.CancellationTokenSource = new ETCancellationToken(); } else { self.CancellationTokenSource = cancellationToken; } // 新数据初始化 for (int i = 0; i < paths.Length; ++i) { self.Path.List.Add(paths[i]); } self.ServerPos = servierpos; await Game.EventSystem.Publish(new AppEventType.MoveStart() { Unit = self.GetParent <DUnit>() }); bool res = await self.StartMoveImp(self.CancellationTokenSource); await Game.EventSystem.Publish(new AppEventType.MoveStop() { Unit = self.GetParent <DUnit>() }); self.CancellationTokenSource = null; return(res); }
public override async ETVoid Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken) { Scene zoneScene = aiComponent.DomainScene(); Unit myUnit = zoneScene.GetComponent <UnitComponent>().MyUnit; if (myUnit == null) { return; } // 停在当前位置 zoneScene.GetComponent <SessionComponent>().Session.Send(new C2M_Stop()); Log.Debug("开始攻击"); for (int i = 0; i < 100000; ++i) { Log.Debug($"攻击: {i}次"); // 因为协程可能被中断,任何协程都要传入cancellationToken,判断如果是中断则要返回 bool timeRet = await TimerComponent.Instance.WaitAsync(1000, cancellationToken); if (!timeRet) { return; } } }
public override async ETTask Execute(AIComponent aiComponent, AIConfig aiConfig, ETCancellationToken cancellationToken) { Scene zoneScene = aiComponent.DomainScene(); Unit myUnit = UnitHelper.GetMyUnitFromZoneScene(zoneScene); if (myUnit == null) { return; } Log.Debug("开始巡逻"); while (true) { XunLuoPathComponent xunLuoPathComponent = myUnit.GetComponent <XunLuoPathComponent>(); Vector3 nextTarget = xunLuoPathComponent.GetCurrent(); int ret = await myUnit.MoveToAsync(nextTarget, cancellationToken); if (ret != 0) { return; } xunLuoPathComponent.MoveNext(); } }
public async ETTask <bool> WaitFrameAsync(ETCancellationToken cancellationToken = null) { return(await WaitAsync(1, cancellationToken)); }