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. [开发技巧]·AttributeError: module 'pywt' has no attribute 'wavedec'解决方法

    [开发技巧]·AttributeError: module 'pywt' has no attribute 'wavedec'解决方法 1.卸载 pywt pip uninstall pywt 2.安 ...

  2. Pots POJ - 3414【状态转移bfs+回溯】

    典型的倒水问题: 即把两个水杯的每种状态视为bfs图中的点,如果两种状态可以转化,即可认为二者之间可以连一条边. 有3种倒水的方法,对应2个杯子,共有6种可能的状态转移方式.即相当于图中想走的方法有6 ...

  3. Linux网络课程学习第四天

    课程内容包括:管道符.重定向与环境变量. 学习心得:个人感觉本章节还是不太好理解,尤其是对自己的基础还不是特别的扎实课余时间还是要反复的复习.

  4. json转dataset的另外一种解析方式自动生成guid强关联

    /// <summary> /// 将json字符串自动转成dataset,并且自动补全主子关联关系, /// Guid,FKGuid /// Author:lijia /// date: ...

  5. 《Photoshop 2020》初心版_v6 21.0.2.57

    <Phtoshop 2020>初心版_v6 下载地址(5245) SHA1:E926A1B99D147A27A44050A5BCE2E69E2CDAEEAE 版本信息    发行版本 20 ...

  6. 850. Dijkstra求最短路 II(堆优化模板)

    给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为非负值. 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1. 输入格式 第一行包含整数n和m. 接下来m行每行 ...

  7. 【你不知道的javaScript 上卷 笔记5】javaScript中的this词法

    function foo() { console.log( a ); } function bar() { var a = 3; foo(); } var a = 2; bar(); 上面这段代码为什 ...

  8. SSH、telnet配置以及它们之间区别

    命令: SSH ip domain-name www.baidu.com --配置主机名(用来远程访问) user privilege secret --配置账户名和密码 line vty --配置端 ...

  9. Day5 多线程 锁

    synchronized保证操作原子性 这是因为对变量进行读取和写入时,结果要正确,必须保证是原子操作.原子操作是指不能被中断的一个或一系列操作. 通过加锁和解锁的操作,就能保证3条指令总是在一个线程 ...

  10. [CF3B] Lorry - 贪心

    有一辆载重量为 v 的货车, 准备运送两种物品. 物品 A 的重量为 1, 物体 B 的重量为 2, 每个物品都有一个价值. 求货车可以运送的物品的最大价值. Solution 考虑把物品分为两类,枚 ...