当前位置: 首页 > news >正文

Fantasy中定时器得驱动原理

一、服务器框架启动

    public static async FTask Start(){// 启动ProcessStartProcess().Coroutine();await FTask.CompletedTask;while (true){ThreadScheduler.Update();Thread.Sleep(1);}}

二、主线程

Fantasy.ThreadScheduler.Update

   internal static void Update(){MainScheduler.Update();}

三、每个Scene的调度

Fantasy.MainScheduler.Update

 public void Update(){ThreadSynchronizationContext.Update();var initialCount = _queue.Count;while (initialCount-- > 0){if(!_queue.TryDequeue(out var scene)){continue;}if (scene.IsDisposed){continue;}scene.Update();_queue.Enqueue(scene);}}

四、Scene执行一下Update

Fantasy.Scene.Update

     internal void Update(){try{SceneUpdate.Update();}catch (Exception e){Log.Error(e);}}

五、下面的儿子每个执行一下

Fantasy.Net\Runtime\Core\Entitas\Component\EntityComponent.cs:413

/// <summary>/// 执行实体系统的更新逻辑/// </summary>public void Update(){var updateQueueCount = _updateQueue.Count;while (updateQueueCount-- > 0){var updateQueueStruct = _updateQueue.Dequeue();if (updateQueueStruct.IsStop){continue;}if (!_updateSystems.TryGetValue(updateQueueStruct.Type, out var updateSystem)){continue;}var entity = Scene.GetEntity(updateQueueStruct.RunTimeId);if (entity == null || entity.IsDisposed){_updateQueueDic.Remove(updateQueueStruct.RunTimeId);continue;}_updateQueue.Enqueue(updateQueueStruct);try{updateSystem.Invoke(entity);}catch (Exception e){Log.Error($"{updateQueueStruct.Type.FullName} Update Error {e}");}}}

六、定时器执行一下

Fantasy.Timer.TimerComponentUpdateSystem.Update

  public sealed class TimerComponentUpdateSystem : UpdateSystem<TimerComponent>{protected override void Update(TimerComponent self){self.Update();}}

Fantasy.Timer.TimerComponent.Update

 public void Update(){Net.Update();
#if FANTASY_UNITYUnity.Update();
#endif}

Fantasy.Net\Runtime\Core\Entitas\Component\TimerComponent\TimerScheduler\TimerSchedulerNet.cs:43

 /// <summary>/// 驱动方法,只有调用这个方法任务系统才会正常运转。/// </summary>public void Update(){if (_timeId.Count == 0){ return;}var currentTime = Now(); if (currentTime < _minTime){ return;}// 遍历时间ID列表,查找超时的计时器任务foreach (var (key, _) in _timeId){if (key > currentTime){_minTime = key;break;}_timeOutTime.Enqueue(key);}// 处理超时的计时器任务while (_timeOutTime.TryDequeue(out var time)){var timerIds = _timeId[time];for (var i = 0; i < timerIds.Count; ++i){_timeOutTimerIds.Enqueue(timerIds[i]);}_timeId.Remove(time);// _timeId.RemoveKey(time);}if (_timeId.Count == 0){_minTime = long.MaxValue;}// 执行超时的计时器任务的回调操作while (_timeOutTimerIds.TryDequeue(out var timerId)){if (!_timerActions.Remove(timerId, out var timerAction)){continue;}// 根据计时器类型执行不同的操作switch (timerAction.TimerType){case TimerType.OnceWaitTimer:{var tcs = (FTask<bool>)timerAction.Callback;tcs.SetResult(true);break;}case TimerType.OnceTimer:{if (timerAction.Callback is not Action action){Log.Error($"timerAction {timerAction.ToJson()}");break;}action();break;}case TimerType.RepeatedTimer:{if (timerAction.Callback is not Action action){Log.Error($"timerAction {timerAction.ToJson()}");break;}timerAction.StartTime = Now();AddTimer(ref timerAction);action();break;}}}}

http://www.lryc.cn/news/494235.html

相关文章:

  • 【反转链表】力扣 445. 两数相加 II
  • SpringBoot 项目中使用 spring-boot-starter-amqp 依赖实现 RabbitMQ
  • Uniapp 安装安卓、IOS模拟器并调试
  • JavaScript 中的原型和原型链
  • 数组变换(两倍)
  • GBN协议、SR协议
  • 三维扫描检测仪3d扫描测量尺寸-自动蓝光测量
  • 大模型翻译能力评测
  • MySQL隐式转换造成索引失效
  • SuperMap Objects组件式GIS开发技术浅析
  • 多组数输入a+b:JAVA
  • R语言结构方程模型(SEM)在生态学领域中的应用
  • 架构-微服务-服务调用Dubbo
  • 【SpringBoot问题】IDEA中用Service窗口展示所有服务及端口的办法
  • OpenCV 图像轮廓查找与绘制全攻略:从函数使用到实战应用详解
  • 电机驱动MCU介绍
  • 人工智能学习框架详解及代码使用案例
  • 修改Textview中第一个字的字体,避免某些机型人民币¥不显示
  • 彻底理解quadtree四叉树、Octree八叉树 —— 点云的空间划分的标准做法
  • Python时间序列优化之道滑动与累积窗口的应用技巧
  • Buffered 和 BuffWrite
  • 【娱乐项目】基于cnchar库与JavaScript的汉字查询工具
  • 泷羽sec-蓝队基础之网络七层杀伤链 (下)学习笔记
  • FPGA 开发工程师
  • 【Leetcode 每日一题】3250. 单调数组对的数目 I
  • 较类中的方法和属性比较
  • nVisual可视化资源管理工具
  • 自动类型推导(auto 和 decltype)
  • 新型大语言模型的预训练与后训练范式,谷歌的Gemma 2语言模型
  • 基于投影寻踪博弈论-云模型的滑坡风险评价