1.代码结构图

2.SmartTimer 模块Entity:

 using System;

 namespace ETModel
{
[ObjectSystem]
public class SmartTimerAwakeSystem: AwakeSystem<SmartTimer, float, uint, Action>
{
public override void Awake(SmartTimer self, float a, uint b, Action c)
{
self.Awake(a, b, c);
}
} public sealed class SmartTimer: Entity
{
public const uint INFINITE = uint.MaxValue; private float m_Interval = ;
private bool m_InfiniteLoops = false;
private uint m_LoopsCount = ;
private Action m_Action = null;
private Action m_Delegate = null;
private bool m_bIsPaused = false;
private uint m_CurrentLoopsCount = ;
private float m_ElapsedTime = ;
private long m_TickedTime = ;
private float m_CurrentCycleElapsedTime = ; public void Awake(float interval, uint loopsCount, Action action)
{
if (m_Interval < )
m_Interval = ; m_TickedTime = DateTime.Now.Ticks;
m_Interval = interval;
m_LoopsCount = Math.Max(loopsCount, );
m_Delegate = action;
} public override void Dispose()
{
if (this.IsDisposed) return;
this.m_Delegate = null;
this.m_Action = null;
base.Dispose();
} internal void UpdateActionFromAction()
{
if (m_InfiniteLoops)
m_LoopsCount = INFINITE; if (m_Action != null)
m_Delegate = delegate { m_Action.Invoke(); };
} internal void UpdateTimer()
{
if (m_bIsPaused)
return; if (m_Delegate == null || m_Interval < )
{
m_Interval = ;
return;
} if (m_CurrentLoopsCount >= m_LoopsCount && m_LoopsCount != INFINITE)
{
m_ElapsedTime = m_Interval * m_LoopsCount;
m_CurrentCycleElapsedTime = m_Interval;
}
else
{
m_ElapsedTime += (DateTime.Now.Ticks - this.m_TickedTime) / 10000000f;
m_TickedTime = DateTime.Now.Ticks;
m_CurrentCycleElapsedTime = m_ElapsedTime - m_CurrentLoopsCount * m_Interval; if (m_CurrentCycleElapsedTime > m_Interval)
{
m_CurrentCycleElapsedTime -= m_Interval;
m_CurrentLoopsCount++;
m_Delegate.Invoke();
}
}
} /// <summary>
/// Get interval
/// </summary>
public float Interval() { return m_Interval; } /// <summary>
/// Get total loops count (INFINITE (which is uint.MaxValue) if is constantly looping)
/// </summary>
public uint LoopsCount() { return m_LoopsCount; } /// <summary>
/// Get how many loops were completed
/// </summary>
public uint CurrentLoopsCount() { return m_CurrentLoopsCount; } /// <summary>
/// Get how many loops remained to completion
/// </summary>
public uint RemainingLoopsCount() { return m_LoopsCount - m_CurrentLoopsCount; } /// <summary>
/// Get total duration, (INFINITE if it's constantly looping)
/// </summary>
public float Duration() { return (m_LoopsCount == INFINITE) ? INFINITE : (m_LoopsCount * m_Interval); } /// <summary>
/// Get the delegate to execute
/// </summary>
public Action Delegate() { return m_Delegate; } /// <summary>
/// Get total remaining time
/// </summary>
public float RemainingTime() { return (m_LoopsCount == INFINITE && m_Interval > 0f) ? INFINITE : Math.Max(m_LoopsCount * m_Interval - m_ElapsedTime, 0f); } /// <summary>
/// Get total elapsed time
/// </summary>
public float ElapsedTime() { return m_ElapsedTime; } /// <summary>
/// Get elapsed time in current loop
/// </summary>
public float CurrentCycleElapsedTime() { return m_CurrentCycleElapsedTime; } /// <summary>
/// Get remaining time in current loop
/// </summary>
public float CurrentCycleRemainingTime() { return Math.Max(m_Interval - m_CurrentCycleElapsedTime, ); } /// <summary>
/// Checks whether this timer is ok to be removed
/// </summary>
public bool ShouldClear() { return (m_Delegate == null || RemainingTime() == ); } /// <summary>
/// Checks if the timer is paused
/// </summary>
public bool IsPaused() { return m_bIsPaused; } /// <summary>
/// Pause / Inpause timer
/// </summary>
public void SetPaused(bool bPause) { m_bIsPaused = bPause; } /// <summary>
/// Compare frequency (calls per second)
/// </summary>
public static bool operator >(SmartTimer A, SmartTimer B) { return (A == null || B == null) || A.Interval() < B.Interval(); } /// <summary>
/// Compare frequency (calls per second)
/// </summary>
public static bool operator <(SmartTimer A, SmartTimer B) { return (A == null || B == null) || A.Interval() > B.Interval(); } /// <summary>
/// Compare frequency (calls per second)
/// </summary>
public static bool operator >=(SmartTimer A, SmartTimer B) { return (A == null || B == null) || A.Interval() <= B.Interval(); } /// <summary>
/// Compare frequency (calls per second)
/// </summary>
public static bool operator <=(SmartTimer A, SmartTimer B) { return (A == null || B == null) || A.Interval() >= B.Interval(); }
}
}

3.SmartTimerComponent 模块Manager:

 using System;
using System.Collections.Generic;
using System.Linq; namespace ETModel
{
[ObjectSystem]
public class SmartTimerComponentAwakeSystem: AwakeSystem<SmartTimerComponent>
{
public override void Awake(SmartTimerComponent self)
{
self.Awake();
}
} [ObjectSystem]
public class SmartTimerComponentUpdateSystem: UpdateSystem<SmartTimerComponent>
{
public override void Update(SmartTimerComponent self)
{
self.Update();
}
} public class SmartTimerComponent: Component
{
// Ensure we only have a single instance of the SmartTimerComponent loaded (singleton pattern).
public static SmartTimerComponent Instance = null;
private IList<SmartTimer> smartTimers = new List<SmartTimer>(); // Whether the game is paused
public bool Paused { get; set; } = false; public void Awake()
{
Instance = this;
} public void Update()
{
if (this.Paused)
return; foreach (SmartTimer smartTimer in this.smartTimers.ToArray())
{
smartTimer.UpdateTimer();
if (smartTimer.ShouldClear() || smartTimer.IsDisposed)
{
this.smartTimers.Remove(smartTimer);
}
}
} public void Add(SmartTimer smartTimer)
{
this.smartTimers.Add(smartTimer);
} public SmartTimer Get(Action action)
{
foreach (SmartTimer smartTimer in this.smartTimers)
{
if (smartTimer.Delegate() == action) return smartTimer;
} return null;
} public void Remove(SmartTimer smartTimer)
{
this.smartTimers.Remove(smartTimer);
smartTimer.Dispose();
} public void Remove(Action action)
{
foreach (SmartTimer smartTimer in this.smartTimers.ToArray())
{
if (smartTimer.Delegate() == action)
{
Remove(smartTimer);
break;
}
}
} public int Count => this.smartTimers.Count; public override void Dispose()
{
if (this.IsDisposed) return;
base.Dispose(); foreach (SmartTimer smartTimer in this.smartTimers)
{
smartTimer.Dispose();
}
this.smartTimers.Clear();
Instance = null;
} /// <summary>
/// Get timer interval. Returns 0 if not found.
/// </summary>
/// <param name="action">Delegate name</param>
public float Interval(Action action) { SmartTimer timer = this.Get(action); return timer?.Interval() ?? 0f; } /// <summary>
/// Get total loops count (INFINITE (which is uint.MaxValue) if is constantly looping)
/// </summary>
/// <param name="action">Delegate name</param>
public uint LoopsCount(Action action) { SmartTimer timer = this.Get(action); return timer?.LoopsCount() ?? ; } /// <summary>
/// Get how many loops were completed
/// </summary>
/// <param name="action">Delegate name</param>
public uint CurrentLoopsCount(Action action) { SmartTimer timer = this.Get(action); return timer?.CurrentLoopsCount() ?? ; } /// <summary>
/// Get how many loops remained to completion
/// </summary>
/// <param name="action">Delegate name</param>
public uint RemainingLoopsCount(Action action) { SmartTimer timer = this.Get(action); return timer?.RemainingLoopsCount() ?? ; } /// <summary>
/// Get total remaining time
/// </summary>
/// <param name="action">Delegate name</param>
public float RemainingTime(Action action) { SmartTimer timer = this.Get(action); return timer?.RemainingTime() ?? -1f; } /// <summary>
/// Get total elapsed time
/// </summary>
/// <param name="action">Delegate name</param>
public float ElapsedTime(Action action) { SmartTimer timer = this.Get(action); return timer?.ElapsedTime() ?? -1f; } /// <summary>
/// Get elapsed time in current loop
/// </summary>
/// <param name="action">Delegate name</param>
public float CurrentCycleElapsedTime(Action action) { SmartTimer timer = this.Get(action); return timer?.CurrentCycleElapsedTime() ?? -1f; } /// <summary>
/// Get remaining time in current loop
/// </summary>
/// <param name="action">Delegate name</param>
public float CurrentCycleRemainingTime(Action action) { SmartTimer timer = this.Get(action); return timer?.CurrentCycleRemainingTime() ?? -1f; } /// <summary>
/// Verifies whether the timer exits
/// </summary>
/// <param name="action">Delegate name</param>
public bool IsTimerActive(Action action) { SmartTimer timer = this.Get(action); return timer != null; } /// <summary>
/// Checks if the timer is paused
/// </summary>
/// <param name="action">Delegate name</param>
public bool IsTimerPaused(Action action) { SmartTimer timer = this.Get(action); return timer?.IsPaused() ?? false; } /// <summary>
/// Pause / Unpause timer
/// </summary>
/// <param name="action">Delegate name</param>
/// <param name="bPause">true - pause, false - unpause</param>
public void SetPaused(Action action, bool bPause) { SmartTimer timer = this.Get(action); if (timer != null) timer.SetPaused(bPause); } /// <summary>
/// Get total duration, (INFINITE if it's constantly looping)
/// </summary>
/// <param name="action">Delegate name</param>
public float Duration(Action action) { SmartTimer timer = this.Get(action); return timer?.Duration() ?? 0f; }
}
}

4.SmartTimerFactory 模块工厂:

 using System;

 namespace ETModel
{
public static class SmartTimerFactory
{
public static SmartTimer Create(float interval, uint loopsCount, Action action)
{
SmartTimer smartTimer = ComponentFactory.Create<SmartTimer, float, uint, Action>(interval, loopsCount, action);
SmartTimerComponent smartTimerComponent = Game.Scene.GetComponent<SmartTimerComponent>();
smartTimerComponent.Add(smartTimer);
return smartTimer;
}
}
}

5.Example:

ET框架之自写模块SmartTimerModule的更多相关文章

  1. 基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

    最近一直很多事情,博客停下来好久没写了,整理下思路,把最近研究的基于Metronic的Bootstrap开发框架进行经验的总结出来和大家分享下,同时也记录自己对Bootstrap开发的学习研究的点点滴 ...

  2. 第三百零四节,Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器

    Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...

  3. 二 Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器

    Django框架,urls.py模块,views.py模块,路由映射与路由分发以及逻辑处理——url控制器 这一节主讲url控制器 一.urls.py模块 这个模块是配置路由映射的模块,当用户访问一个 ...

  4. 微信公众帐号开发。大家是用框架还是自己写的流程。现在遇到若干问题。请教各路大仙 - V2EX

    微信公众帐号开发.大家是用框架还是自己写的流程.现在遇到若干问题.请教各路大仙 - V2EX 微信公众帐号开发.大家是用框架还是自己写的流程.现在遇到若干问题.请教各路大仙

  5. robot framework 如何自己写模块下的方法或者库

    一.写模块(RF能识别的模块) 例如:F:\Python3.4\Lib\site-packages\robot\libraries这个库(包)下面的模块(.py),我们可以看下源码 注意:这种是以方法 ...

  6. TP3.2框架,实现空模块、空控制器、空操作的页面404替换||同步实现apache报错404页面替换

    一,前言 一.1)以下代码是在TP3.0版本之后,URL的默认模式=>PATHINFO的前提下进行的.(通俗点,URL中index.php必须存在且正确) 代码和讲解如下: 1.空模块解决:ht ...

  7. WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程

    最近在重学OpenGL,之所以说重学是因为上次接触OpenGL还是在学校里,工作之后就一直在搞D3D,一转眼已经毕业6年了.OpenGL这门手艺早就完全荒废了,现在只能是重学.学习程序最有效的办法是动 ...

  8. Python高级进阶(二)Python框架之Django写图书管理系统(LMS)

    正式写项目准备前的工作 Django是一个Web框架,我们使用它就是因为它能够把前后端解耦合而且能够与数据库建立ORM,这样,一个Python开发工程师只需要干自己开发的事情就可以了,而在使用之前就我 ...

  9. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

随机推荐

  1. Elasticsearch操作Document文档

    1.利用客户端操作Document文档数据        1.1 创建一个文档(创建数据的过程,向表中去添加数据)            请求方式:Post    请求地址:es所在IP:9200/索 ...

  2. SSM开发健康信息管理系统

    Spring+Spring MVC+MyBatis基于MVC架构的个人健康信息管理系统 采用ssm框架,包含 健康档案.健康预警(用户输入数据,系统根据范围自动判断给出不同颜色箭头显示). 健康分析. ...

  3. spring boot的一些常用注解

    spring boot的一些常用注解: 使用@SpringBootApplication注释: 许多Spring Boot开发人员喜欢他们的应用程序使用自动配置,组件扫描,并能够在其“应用程序类”上定 ...

  4. 手动安装 saltshaker-plus 版本选择特别说明(后期重点讲解Docker安装方式)

    前后端都建议使用1.12版本

  5. CF718C Sasha and Array [线段树+矩阵]

    我们考虑线性代数上面的矩阵知识 啊呸,是基础数学 斐波那契的矩阵就不讲了 定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵 因为 \(f_i * f_j = f_{i+j}\) 然后又因为 ...

  6. 0009 基于DRF框架开发(02 创建模型)

    上一节介绍了DRF开发的基本流程,共五个步骤: 1 创建模型 2 创建序列化器 3 编写视图 4 配置URL 5 运行测试 本节主要讲解创建模型. 构建学校,教师,学生三个模型,这三个模型之间的关系是 ...

  7. CCS 5.5下载地址http://www.dianyuan.com/bbs/1492792.html

    http://www.dianyuan.com/bbs/1492792.html https://pan.baidu.com/s/1eQtIRK2?errno=0&errmsg=Auth%20 ...

  8. 树hash/树哈希 刷题记录

    不同hash姿势: 树的括号序列最小表示法  s[i] 如果i为叶子节点:() 如果i的子节点为j1~jn:(s[j1]...s[jn]),注意s[j]要按照字典序排列

  9. 使用U盘装Windows10系统

    一.装备工作 使用U盘装系统需要准备以下工具: 8G左右的U盘一个.由于制作启动盘会删除U盘的所有数据,所以重要资料请提前备份. 系统的镜像文件.这里我推荐MSDN, 我告诉你.这里下载的镜像和官方的 ...

  10. 2019-08-22 纪中NOIP模拟A&B组

    T1 [JZOJ3229] 回文子序列 题目描述 回文序列是指左右对称的序列.我们会给定一个N×M的矩阵,你需要从这个矩阵中找出一个P×P的子矩阵,使得这个子矩阵的每一列和每一行都是回文序列. 数据范 ...