using System; using System.Collections.Generic; namespace CommonLang { public delegate void TickHandler(TimeTaskMS task); public class TimeInterval { public T Tag; private int mIntervalTimeMS; private int mPassTimeMS = 0; private int mTickCount = 0; private bool mFirstTimeEnable = true; /// /// 间隔时间 /// public int IntervalTimeMS { get { return mIntervalTimeMS; } } /// /// 触发过多少次 /// public int TotalTickCount { get { return mTickCount; } } /// /// 总共经过时间 /// public int TotalPassTimeMS { get { return mPassTimeMS; } } public bool FirstTimeEnable { set { mFirstTimeEnable = value; } private get { return mFirstTimeEnable; } } public TimeInterval(int intervalMS) { this.mIntervalTimeMS = intervalMS; } public TimeInterval(T tag, int intervalMS) { this.mIntervalTimeMS = intervalMS; this.Tag = tag; } public void SetPassTime(int passtimeMS) { mPassTimeMS = passtimeMS; } /// /// 记录归零 /// public void Reset() { mPassTimeMS = 0; mTickCount = 0; } public void Reset(int intervalMS) { mIntervalTimeMS = intervalMS; mPassTimeMS = 0; mTickCount = 0; } /// /// 更新 /// /// 间隔时间 /// 是否应该触发 //public bool Update(int intervalMS) //{ // if (mIntervalTimeMS > 0) // { // if (mIntervalTimeMS <= mPassTimeMS) // { // this.mPassTimeMS += intervalMS; // this.mPassTimeMS -= mIntervalTimeMS; // this.mTickCount++; // return true; // } // else if (mPassTimeMS == 0 && FirstTimeEnable) // { // this.mPassTimeMS += intervalMS; // return true; // } // else // { // this.mPassTimeMS += intervalMS; // } // } // return false; //} public bool Update(int intervalMS) { bool isTrigger = false; if (mIntervalTimeMS > 0) { this.mPassTimeMS += intervalMS; if (FirstTimeEnable && this.mTickCount == 0) { this.mTickCount++; isTrigger = true; } else if(mIntervalTimeMS <= mPassTimeMS) { this.mPassTimeMS -= mIntervalTimeMS; this.mTickCount++; isTrigger = true; } } return isTrigger; } public TimeInterval ChangeTiming(int intervalMs) { TimeInterval rlt = new TimeInterval(intervalMs); rlt.mPassTimeMS = this.mPassTimeMS; rlt.mTickCount = this.mTickCount; rlt.Tag = this.Tag; return rlt; } } public class TimeExpire { public T Tag { get; set; } public int TotalTimeMS { get { return mTotalTimeMS; } } public int PassTimeMS { get { return mPassTimeMS; } } public int ExpireTimeMS { get { return mTotalTimeMS - mPassTimeMS; } } private int mTotalTimeMS; private int mPassTimeMS; public TimeExpire(int totalMS) { this.mTotalTimeMS = totalMS; this.mPassTimeMS = 0; } public TimeExpire(T tag, int totalMS) : this(totalMS) { this.Tag = tag; } /// /// 记录归零 /// public void Reset() { this.mPassTimeMS = 0; } public void Reset(int totalTimeMS) { this.mPassTimeMS = 0; this.mTotalTimeMS = totalTimeMS; } public void End() { this.mPassTimeMS = mTotalTimeMS; } /// /// 更新 /// /// 间隔时间 /// 是否到期 public bool Update(int intervalMS) { this.mPassTimeMS += intervalMS; return mPassTimeMS >= mTotalTimeMS; } /// /// 是否结束 /// public bool IsEnd { get { return mPassTimeMS >= mTotalTimeMS; } } /// /// 剩余百分比 /// public float Percent { get { return Math.Min((float)mPassTimeMS / (float)mTotalTimeMS, 1); } } } public class TimeTaskMS { private TickHandler Handler; readonly private int IntervalTimeMS; readonly private int DelayTimeMS; readonly private int RepeatCount; public object UserData; private bool mRunning = false; private bool mExit = false; private int PassTimeMS = 0; private int DelayTimer = 0; private int RepeatTick = 0; private bool mInvoking = false; public TimeTaskMS(int intervalMS, int delayMS, int repeat, TickHandler handler) { this.Handler = handler; this.IntervalTimeMS = intervalMS; this.DelayTimeMS = delayMS; this.RepeatCount = repeat; Reset(); } internal void Start() { this.PassTimeMS = 0; this.mRunning = true; } /// /// 更新 /// /// 间隔时间 internal void Update(int intervalMS) { if (!mExit && mRunning) { this.PassTimeMS += intervalMS; if (DelayTimer > 0) { if (DelayTimer <= PassTimeMS) { mInvoking = true; PassTimeMS -= DelayTimer; DelayTimer = 0; } else { return; } } if (IntervalTimeMS <= PassTimeMS) { mInvoking = true; PassTimeMS -= IntervalTimeMS; if (RepeatCount > 0) { RepeatTick++; if (RepeatTick >= RepeatCount) { mExit = true; } } } } } internal void TryInvoke() { if (mInvoking) { mInvoking = false; Handler.Invoke(this); } } public void Reset() { this.mRunning = true; this.mExit = false; this.PassTimeMS = 0; this.RepeatTick = 0; this.DelayTimer = DelayTimeMS; } public void Stop() { mExit = true; } public void Dispose() { mExit = true; this.Handler = null; } public void Pause() { mRunning = false; } public void Resume() { mRunning = true; } public bool IsRunning { get { return mRunning; } } public bool IsExit { get { return mExit; } } internal bool IsInvoking { get { return mInvoking; } } } public class TimeTaskQueue : IDisposable { private LinkedList mTimeTasks = new LinkedList(); private List> removed = new List>(2); private List invoking = new List(2); public void Dispose() { mTimeTasks.Clear(); removed.Clear(); invoking.Clear(); } public void Update(int intervalMS) { removed.Clear(); invoking.Clear(); lock (mTimeTasks) { for (LinkedListNode it = mTimeTasks.Last; it != null; it = it.Previous) { TimeTaskMS t = it.Value; t.Update(intervalMS); if (t.IsInvoking) { invoking.Add(t); } if (t.IsExit) { removed.Add(it); } } if (removed.Count > 0) { for (int i = removed.Count - 1; i >= 0; --i) { mTimeTasks.Remove(removed[i]); } } } if (invoking.Count > 0) { for (int i = invoking.Count - 1; i >= 0; --i) { TimeTaskMS task = invoking[i]; task.TryInvoke(); } } // 手动调用一下dispose if (removed.Count > 0) { for (int i = removed.Count - 1; i >= 0; --i) { removed[i].Value.Dispose(); } } } /// /// 增加时间任务 /// /// /// /// /// public TimeTaskMS AddTimeTask(int intervalMS, int delayMS, int repeat, TickHandler handler) { TimeTaskMS time = new TimeTaskMS(intervalMS, delayMS, repeat, handler); lock (mTimeTasks) { mTimeTasks.AddLast(time); } time.Start(); return time; } /// /// 增加延时回调方法 /// /// /// public TimeTaskMS AddTimeDelayMS(int delayMS, TickHandler handler) { TimeTaskMS time = new TimeTaskMS(0, delayMS, 1, handler); lock (mTimeTasks) { mTimeTasks.AddLast(time); } time.Start(); return time; } /// /// 增加定时回调方法 /// /// /// public TimeTaskMS AddTimePeriodicMS(int intervalMS, TickHandler handler) { TimeTaskMS time = new TimeTaskMS(intervalMS, 0, 0, handler); lock (mTimeTasks) { mTimeTasks.AddLast(time); } time.Start(); return time; } } public delegate void MultiTimeLineRefresh(bool isAdd); /// /// 同时执行多个Timer /// public class MultiTimeLine { private List> Times = new List>(); private MultiTimeLineRefresh mRefeshNotify; public MultiTimeLine(MultiTimeLineRefresh notify) { this.mRefeshNotify = notify; } public TimeExpire Add(int timeMS) { TimeExpire ret = new TimeExpire(timeMS); Times.Add(ret); if(this.mRefeshNotify != null) { this.mRefeshNotify.Invoke(true); } return ret; } public bool Remove(TimeExpire task) { task.End(); if (this.mRefeshNotify != null) { this.mRefeshNotify.Invoke(false); } return Times.Remove(task); } public void Clear() { for (int i = Times.Count - 1; i >= 0; --i) { TimeExpire task = Times[i]; task.End(); } Times.Clear(); } public void Disposing() { this.Clear(); this.mRefeshNotify = null; } public bool Update(int intervalMS) { for (int i = Times.Count - 1; i >= 0; --i) { TimeExpire task = Times[i]; if (task.Update(intervalMS)) { Times.RemoveAt(i); } } return Times.Count > 0; } public bool Enable { get { return Times.Count > 0; } } } //-------------------------------------------------------------------------------------------- #region SystemTime public class SystemTimeInterval : TimeInterval { private long lastUpdateTime = CUtils.CurrentTimeMS; public SystemTimeInterval(int intervalMS) : base(intervalMS) { } public bool Update() { long curTime = CUtils.CurrentTimeMS; int interval = (int)(curTime - lastUpdateTime); lastUpdateTime = curTime; return base.Update(interval); } } public class SystemTimeExpire : TimeExpire { private long lastUpdateTime = CUtils.CurrentTimeMS; public SystemTimeExpire(int timeMS) : base(timeMS) { } public bool Update() { long curTime = CUtils.CurrentTimeMS; int interval = (int)(curTime - lastUpdateTime); lastUpdateTime = curTime; return base.Update(interval); } } public class SystemTimeTaskQueue : TimeTaskQueue { private long lastUpdateTime = CUtils.CurrentTimeMS; public void Update() { long curTime = CUtils.CurrentTimeMS; int interval = (int)(curTime - lastUpdateTime); lastUpdateTime = curTime; base.Update(interval); } } //public class SystemMultiTimeLine : MultiTimeLine //{ // private long lastUpdateTime = CUtils.CurrentTimeMS; // public SystemMultiTimeLine() : base(null) { } // public void Update() // { // long curTime = CUtils.CurrentTimeMS; // int interval = (int)(curTime - lastUpdateTime); // lastUpdateTime = curTime; // base.Update(interval); // } //} #endregion //-------------------------------------------------------------------------------------------- public class SystemTimeRecoder { private long last_update_time; private int current_interval; public long LastUpdateTimeMS { get { return last_update_time; } } public int CurrentIntervalMS { get { return current_interval; } } public SystemTimeRecoder() { this.last_update_time = CUtils.CurrentTimeMS; this.current_interval = 0; } public void Reset() { this.last_update_time = CUtils.CurrentTimeMS; this.current_interval = 0; } public int Update() { long curtime = CUtils.CurrentTimeMS; current_interval =(int)(curtime - last_update_time); return current_interval; } } public class TimeUtil { //使用替代方案: CommonLang.CUtils.localTimeMS public static long GetTimestampMS() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return (long)ts.TotalMilliseconds; //return CommonLang.CUtils.CurrentTimeMS; } } }