private void Run(TimerAction timerAction) { switch (timerAction.TimerClass) { case TimerClass.OnceWaitTimer: { ETTask <bool> tcs = timerAction.Callback as ETTask <bool>; this.Remove(timerAction.Id); tcs.SetResult(true); break; } case TimerClass.OnceTimer: { Action action = timerAction.Callback as Action; this.Remove(timerAction.Id); action?.Invoke(); break; } case TimerClass.RepeatedTimer: { Action action = timerAction.Callback as Action; long tillTime = TimeHelper.ServerNow() + timerAction.Time; this.AddTimer(tillTime, timerAction); action?.Invoke(); break; } } }
private static void Run(this TimerComponent self, TimerAction timerAction) { switch (timerAction.TimerClass) { case TimerClass.OnceTimer: { int type = timerAction.Type; Game.EventSystem.Callback(type, timerAction.Object); break; } case TimerClass.OnceWaitTimer: { ETTask <bool> tcs = timerAction.Object as ETTask <bool>; self.Remove(timerAction.Id); tcs.SetResult(true); break; } case TimerClass.RepeatedTimer: { int type = timerAction.Type; long tillTime = TimeHelper.ServerNow() + timerAction.Time; self.AddTimer(tillTime, timerAction); Game.EventSystem.Callback(type, timerAction.Object); break; } } }
/// <summary> /// 释放对点技能 /// </summary> /// <param name="self"></param> /// <param name="spellSkill"></param> /// <param name="point"></param> public static void SpellWithPoint(this SpellComponent self, SkillAbility spellSkill, Vector3 point) { if (!self.Enable) { return; } if (self.CurSkillConfigId != 0) { return; } if (!spellSkill.CanUse()) { return; } self.CurSkillConfigId = spellSkill.ConfigId; var nowpos = self.GetParent <CombatUnitComponent>().unit.Position; if (Vector2.Distance(new Vector2(nowpos.x, nowpos.z), new Vector2(point.x, point.z)) > spellSkill.SkillConfig.PreviewRange[0]) { var dir = new Vector3(point.x - nowpos.x, 0, point.z - nowpos.z).normalized; point = nowpos + dir * spellSkill.SkillConfig.PreviewRange[0]; } self.Para = new SkillPara(); self.Para.Position = point; self.Para.From = self.GetParent <CombatUnitComponent>(); self.Para.Ability = spellSkill; self.GetSkill().LastSpellTime = TimeHelper.ServerNow(); self.PlayNextSkillStep(0); }
/// <summary> /// 释放对目标技能 /// </summary> /// <param name="self"></param> /// <param name="spellSkill"></param> /// <param name="targetEntity"></param> public static void SpellWithTarget(this SpellComponent self, SkillAbility spellSkill, CombatUnitComponent targetEntity) { if (!self.Enable) { return; } if (self.CurSkillConfigId != 0) { return; } if (!spellSkill.CanUse()) { return; } self.CurSkillConfigId = spellSkill.ConfigId; var nowpos = self.GetParent <CombatUnitComponent>().unit.Position; var nowpos2 = targetEntity.unit.Position; if (Vector2.Distance(new Vector2(nowpos.x, nowpos.z), new Vector2(nowpos2.x, nowpos2.z)) > spellSkill.SkillConfig.PreviewRange[0]) { return; } self.Para = new SkillPara(); self.Para.From = self.GetParent <CombatUnitComponent>(); self.Para.Ability = spellSkill; self.Para.To = targetEntity; self.GetSkill().LastSpellTime = TimeHelper.ServerNow(); self.PlayNextSkillStep(0); }
public static void Check(this ActorMessageSenderComponent self) { long timeNow = TimeHelper.ServerNow(); foreach ((int key, ActorMessageSender value) in self.requestCallback) { // 因为是顺序发送的,所以,检测到第一个不超时的就退出 if (timeNow < value.CreateTime + ActorMessageSenderComponent.TIMEOUT_TIME) { break; } self.TimeoutActorMessageSenders.Add(key); } foreach (int rpcId in self.TimeoutActorMessageSenders) { ActorMessageSender actorMessageSender = self.requestCallback[rpcId]; self.requestCallback.Remove(rpcId); try { IActorResponse response = ActorHelper.CreateResponse((IActorRequest)actorMessageSender.MemoryStream.ToActorMessage(), ErrorCore.ERR_ActorTimeout); Run(actorMessageSender, response); } catch (Exception e) { Log.Error(e.ToString()); } } self.TimeoutActorMessageSenders.Clear(); }
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 = 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); }
private void Run(TimerAction timerAction) { switch (timerAction.TimerClass) { case TimerClass.OnceTimer: { ETTask <bool> tcs = timerAction.Object as ETTask <bool>; this.Remove(timerAction.Id); tcs.SetResult(true); break; } case TimerClass.RepeatedTimer: { int type = timerAction.Type; long tillTime = TimeHelper.ServerNow() + timerAction.Time; this.AddTimer(tillTime, timerAction); ITimer timer = this.timerActions[type]; if (timer == null) { Log.Error($"not found timer action: {type}"); return; } timer.Handle(timerAction.Object); break; } } }
/// <summary> /// 释放方向技能 /// </summary> /// <param name="self"></param> /// <param name="spellSkill"></param> /// <param name="point"></param> public static void SpellWithDirect(this SpellComponent self, SkillAbility spellSkill, Vector3 point) { if (!self.Enable) { return; } if (self.CurSkillConfigId != 0) { return; } if (!spellSkill.CanUse()) { return; } self.CurSkillConfigId = spellSkill.ConfigId; var nowpos = self.GetParent <CombatUnitComponent>().unit.Position; point = new Vector3(point.x, nowpos.y, point.z); var Rotation = Quaternion.LookRotation(point - nowpos, Vector3.up); self.Para = new SkillPara(); self.Para.Position = point; self.Para.Rotation = Rotation; self.Para.From = self.GetParent <CombatUnitComponent>(); self.Para.Ability = spellSkill; self.GetSkill().LastSpellTime = TimeHelper.ServerNow(); self.PlayNextSkillStep(0); }
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 void Update() { if (this.TimeId.Count == 0) { return; } timeNow = TimeHelper.ServerNow(); #region 每帧执行的timer,不用foreach TimeId,减少GC int count = this.everyFrameTimer.Count; for (int i = 0; i < count; ++i) { long timerId = this.everyFrameTimer.Dequeue(); TimerAction timerAction = this.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } Run(timerAction); } #endregion if (timeNow < this.minTime) { return; } this.TimeId.ForEachFunc(this.foreachFunc); while (this.timeOutTime.Count > 0) { long time = this.timeOutTime.Dequeue(); var list = this.TimeId[time]; for (int i = 0; i < list.Count; ++i) { long timerId = list[i]; this.timeOutTimerIds.Enqueue(timerId); } this.TimeId.Remove(time); } while (this.timeOutTimerIds.Count > 0) { long timerId = this.timeOutTimerIds.Dequeue(); TimerAction timerAction = this.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } Run(timerAction); } }
public ActorMessageSender(long actorId, MemoryStream memoryStream, ETTaskCompletionSource <IActorResponse> tcs, bool needException) { this.ActorId = actorId; this.MemoryStream = memoryStream; this.CreateTime = TimeHelper.ServerNow(); this.Tcs = tcs; this.NeedException = needException; }
public override void Update(TimerComponent self) { #region 每帧执行的timer,不用foreach TimeId,减少GC int count = self.everyFrameTimer.Count; for (int i = 0; i < count; ++i) { long timerId = self.everyFrameTimer.Dequeue(); TimerAction timerAction = self.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } self.Run(timerAction); } #endregion if (self.TimeId.Count == 0) { return; } self.timeNow = TimeHelper.ServerNow(); if (self.timeNow < self.minTime) { return; } self.TimeId.ForEachFunc(self.foreachFunc); while (self.timeOutTime.Count > 0) { long time = self.timeOutTime.Dequeue(); var list = self.TimeId[time]; for (int i = 0; i < list.Count; ++i) { long timerId = list[i]; self.timeOutTimerIds.Enqueue(timerId); } self.TimeId.Remove(time); } while (self.timeOutTimerIds.Count > 0) { long timerId = self.timeOutTimerIds.Dequeue(); TimerAction timerAction = self.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } self.Run(timerAction); } }
public static async ETTask Remove(this LocationProxyComponent self, long key) { Log.Info($"location proxy add {key}, {TimeHelper.ServerNow()}"); await MessageHelper.CallActor(GetLocationSceneId(key), new ObjectRemoveRequest() { Key = key }); }
public static async ETTask Lock(this LocationProxyComponent self, long key, long instanceId, int time = 1000) { Log.Info($"location proxy lock {key}, {instanceId} {TimeHelper.ServerNow()}"); await MessageHelper.CallActor(GetLocationSceneId(key), new ObjectLockRequest() { Key = key, InstanceId = instanceId, Time = time }); }
public static async ETTask UnLock(this LocationProxyComponent self, long key, long oldInstanceId, long instanceId) { Log.Info($"location proxy unlock {key}, {instanceId} {TimeHelper.ServerNow()}"); await MessageHelper.CallActor(GetLocationSceneId(key), new ObjectUnLockRequest() { Key = key, OldInstanceId = oldInstanceId, InstanceId = instanceId }); }
public long NewOnceTimer(long tillTime, Action action) { if (tillTime < TimeHelper.ServerNow()) { Log.Error($"new once time too small: {tillTime}"); } TimerAction timer = EntityFactory.CreateWithParent <TimerAction, TimerClass, long, object>(this, TimerClass.OnceTimer, 0, action, true); this.AddTimer(tillTime, timer); return(timer.Id); }
public long NewOnceTimer(long tillTime, Action action) { if (tillTime < TimeHelper.ServerNow()) { Log.Error($"new once time too small: {tillTime}"); } TimerAction timer = this.AddChild <TimerAction, TimerClass, long, object>(TimerClass.OnceTimer, 0, action, true); this.AddTimer(tillTime, timer); return(timer.Id); }
// 用这个优点是可以热更,缺点是回调式的写法,逻辑不连贯。WaitTillAsync不能热更,优点是逻辑连贯。 // wait时间短并且逻辑需要连贯的建议WaitTillAsync // wait时间长不需要逻辑连贯的建议用NewOnceTimer public static long NewOnceTimer(this TimerComponent self, long tillTime, int type, object args) { if (tillTime < TimeHelper.ServerNow()) { Log.Warning($"new once time too small: {tillTime}"); } TimerAction timer = self.AddChild <TimerAction, TimerClass, long, int, object>(TimerClass.OnceTimer, tillTime, type, args, true); self.AddTimer(tillTime, timer); return(timer.Id); }
/// <summary> /// 创建一个RepeatedTimer /// </summary> private long NewRepeatedTimerInner(long time, int type, object args) { #if NOT_UNITY if (time < 100) { throw new Exception($"repeated timer < 100, timerType: time: {time}"); } #endif long tillTime = TimeHelper.ServerNow() + time; TimerAction timer = this.AddChild <TimerAction, TimerClass, long, int, object>(TimerClass.RepeatedTimer, time, type, args, true); this.AddTimer(tillTime, timer); return(timer.Id); }
/// <summary> /// 创建一个RepeatedTimer /// </summary> private long NewRepeatedTimerInner(long time, Action action) { #if NOT_CLIENT if (time < 100) { throw new Exception($"repeated timer < 100, timerType: time: {time}"); } #endif long tillTime = TimeHelper.ServerNow() + time; TimerAction timer = EntityFactory.CreateWithParent <TimerAction, TimerClass, long, object>(this, TimerClass.RepeatedTimer, time, action, true); this.AddTimer(tillTime, timer); return(timer.Id); }
protected override void Update(TimerComponent self) { if (self.TimeId.Count == 0) { return; } long timeNow = TimeHelper.ServerNow(); if (timeNow < self.minTime) { return; } foreach (KeyValuePair <long, List <long> > kv in self.TimeId) { long k = kv.Key; if (k > timeNow) { self.minTime = k; break; } self.timeOutTime.Enqueue(k); } while (self.timeOutTime.Count > 0) { long time = self.timeOutTime.Dequeue(); var list = self.TimeId[time]; for (int i = 0; i < list.Count; ++i) { long timerId = list[i]; self.timeOutTimerIds.Enqueue(timerId); } self.TimeId.Remove(time); } while (self.timeOutTimerIds.Count > 0) { long timerId = self.timeOutTimerIds.Dequeue(); TimerAction timerAction = self.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } self.Run(timerAction); } }
public void Update() { if (this.TimeId.Count == 0) { return; } long timeNow = TimeHelper.ServerNow(); if (timeNow < this.minTime) { return; } foreach (KeyValuePair <long, List <long> > kv in this.TimeId) { long k = kv.Key; if (k > timeNow) { minTime = k; break; } this.timeOutTime.Enqueue(k); } while (this.timeOutTime.Count > 0) { long time = this.timeOutTime.Dequeue(); foreach (long timerId in this.TimeId[time]) { this.timeOutTimerIds.Enqueue(timerId); } this.TimeId.Remove(time); } while (this.timeOutTimerIds.Count > 0) { long timerId = this.timeOutTimerIds.Dequeue(); TimerAction timerAction = this.GetChild <TimerAction>(timerId); if (timerAction == null) { continue; } Run(timerAction); } }
/// <summary> /// 创建一个RepeatedTimer /// </summary> private static long NewRepeatedTimerInner(this TimerComponent self, long time, int type, object args) { #if NOT_UNITY if (time < 100) { throw new Exception($"repeated timer < 100, timerType: time: {time}"); } #endif long tillTime = TimeHelper.ServerNow() + time; TimerAction timer = self.AddChild <TimerAction, TimerClass, long, int, object>(TimerClass.RepeatedTimer, time, type, args, true); // 每帧执行的不用加到timerId中,防止遍历 self.AddTimer(tillTime, timer); return(timer.Id); }
public override void Awake(SkillColliderComponent self, SkillPara para) { int curIndex = para.CurIndex; var stepPara = para.StepPara[curIndex]; self.Cost = para.Cost; self.CostId = para.CostId; self.SkillConfigId = para.Ability.SkillConfig.Id; self.CreateTime = TimeHelper.ServerNow(); self.FromId = para.From.Id; self.Para = stepPara; if (int.TryParse(stepPara.Paras[0].ToString(), out var colliderId)) { self.ConfigId = colliderId; #region 添加触发器 int deltaTime = 0; if (stepPara.Paras.Length >= 6) { int.TryParse(stepPara.Paras[5].ToString(), out deltaTime); } if (deltaTime <= 0) { deltaTime = 1;//等下一帧 } if (self.Config.ColliderShape == SkillColliderShapeType.None) { return; } else if (self.Config.ColliderShape == SkillColliderShapeType.Sphere || self.Config.ColliderShape == SkillColliderShapeType.OBB) { TimerComponent.Instance.NewOnceTimer(self.CreateTime + deltaTime, TimerType.GenerateSkillCollider, self); } else { Log.Error("碰撞体形状未处理" + self.Config.ColliderType); return; } #endregion TimerComponent.Instance.NewOnceTimer(self.CreateTime + self.Config.Time, TimerType.SkillColliderRemove, self.Unit); } }
public static void Check(this ActorLocationSenderComponent self) { using (ListComponent <long> list = ListComponent <long> .Create()) { long timeNow = TimeHelper.ServerNow(); foreach ((long key, Entity value) in self.Children) { ActorLocationSender actorLocationMessageSender = (ActorLocationSender)value; if (timeNow > actorLocationMessageSender.LastSendOrRecvTime + ActorLocationSenderComponent.TIMEOUT_TIME) { list.Add(key); } } foreach (long id in list) { self.Remove(id); } } }
/// <summary> /// 播放下一个技能动画 /// </summary> /// <param name="self"></param> /// <param name="index"></param> public static void PlayNextSkillStep(this SpellComponent self, int index) { do { if (self.CurSkillConfigId == 0 || self.GetSkill().StepType == null || index >= self.GetSkill().StepType.Count) { if (self.CurSkillConfigId != 0) { self.GetSkill().LastSpellOverTime = TimeHelper.ServerNow(); } self.CurSkillConfigId = 0; self.Para = null; return; } var id = self.GetSkill().StepType[index]; self.Para.SetParaStep(index); SkillWatcherComponent.Instance.Run(id, self.Para); index++; }while (self.Para.StepPara[index - 1].Interval <= 0); self.NextSkillStep = index; self.TimerId = TimerComponent.Instance.NewOnceTimer( TimeHelper.ServerNow() + self.Para.StepPara[index - 1].Interval, TimerType.PlayNextSkillStep, self); }
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); }
private static async ETTask <IActorResponse> CallInner(this ActorLocationSenderComponent self, ActorLocationSender actorLocationSender, int rpcId, MemoryStream memoryStream) { int failTimes = 0; long instanceId = actorLocationSender.InstanceId; actorLocationSender.LastSendOrRecvTime = TimeHelper.ServerNow(); while (true) { if (actorLocationSender.ActorId == 0) { actorLocationSender.ActorId = await LocationProxyComponent.Instance.Get(actorLocationSender.Id); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout2, $"{memoryStream.ToActorMessage()}"); } } if (actorLocationSender.ActorId == 0) { IActorRequest iActorRequest = (IActorRequest)memoryStream.ToActorMessage(); return(ActorHelper.CreateResponse(iActorRequest, ErrorCore.ERR_NotFoundActor)); } IActorResponse response = await ActorMessageSenderComponent.Instance.Call(actorLocationSender.ActorId, rpcId, memoryStream, false); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout3, $"{memoryStream.ToActorMessage()}"); } switch (response.Error) { case ErrorCore.ERR_NotFoundActor: { // 如果没找到Actor,重试 ++failTimes; if (failTimes > 20) { Log.Debug($"actor send message fail, actorid: {actorLocationSender.Id}"); actorLocationSender.Error = ErrorCore.ERR_NotFoundActor; // 这里不能删除actor,要让后面等待发送的消息也返回ERR_NotFoundActor,直到超时删除 return(response); } // 等待0.5s再发送 await TimerComponent.Instance.WaitAsync(500); if (actorLocationSender.InstanceId != instanceId) { throw new RpcException(ErrorCore.ERR_ActorLocationSenderTimeout4, $"{memoryStream.ToActorMessage()}"); } actorLocationSender.ActorId = 0; continue; } case ErrorCore.ERR_ActorTimeout: { throw new RpcException(response.Error, $"{memoryStream.ToActorMessage()}"); } } if (ErrorCore.IsRpcNeedThrowException(response.Error)) { throw new RpcException(response.Error, $"Message: {response.Message} Request: {memoryStream.ToActorMessage()}"); } return(response); } }
protected override async ETTask Run(Session session, C2G_Ping request, G2C_Ping response, Action reply) { response.Time = TimeHelper.ServerNow(); reply(); await ETTask.CompletedTask; }