Unity架构之路-小试牛刀-3-TimerManager

10 篇文章 0 订阅

时间管理类

// Made by LCX.  Feel free to contact with us at ant time.Thanks
// QQ: 594721121
// ReSharper disable CheckNamespace
using System;
using System.Collections.Generic;
using UnityEngine;
namespace MyFrameWork.Managers
{
    public sealed class TimerManager : Singleton<TimerManager> ,IManager
    {
        private readonly List<Timer> _timers; //Timer池子
        public List<Timer> Timers
        {
            get { return _timers; }
        }

        public TimerManager()
        {
            _timers = new List<Timer>();
        }

        public override void Init()
        {
            base.Init();
            //Todo 
        }

        /// <summary>
        /// 注册时间
        /// </summary>
        /// <param name="duration">时间</param>
        /// <param name="useRealTime">是否使用真实时间 即受不受Time.scale影响</param>
        /// <param name="loopTimes">循环次数 默认为1若为0则是无线循环</param>
        /// <param name="onComplete"></param>
        /// <param name="onFinish"></param>
        /// <param name="onUpdate"></param>
        /// <returns></returns>
        public Timer RegisterTimer(float duration, bool useRealTime = true, uint loopTimes = 1, Action onComplete = null,
            Action onFinish = null, Action<float> onUpdate = null)
        {
            Timer timer = new Timer(duration, useRealTime, loopTimes, onComplete, onFinish, onUpdate);
            _timers.Add(timer);
            return timer;
        }

        // Update is called once per frame
        public void UpdateTimes()
        {
            _timers.ForEach(t => t.Update(t.OnEachDurationElapsedTime()));
        }

        public void Cancel(Timer timer)
        {
            _timers.RemoveAll(t => t == timer);
        }
    }

    /// <summary>
    /// 不考虑无线循环情况循环  时间为循环时切换场景会有问题 
    /// 必须从TimerManager获取Timer实例
    /// </summary>
    public class Timer
    {
        public Timer(float duration, bool usesRealTime, uint loopTimes, Action onComplete, Action onFinish,
            Action<float> onUpdate)
        {
            Duration = duration;
            UsesRealTime = usesRealTime;
            LoopTimes = loopTimes;
            _onComplete = onComplete;
            _onFinish = onFinish;
            _onUpdate = onUpdate;
            StartTime = GetWorldTime();
            TotalTime = duration*LoopTimes;
            OnEachLoopStartTime = StartTime;
            OnStartTime = StartTime;
        }

        public float Duration { get; private set; } //定时时间
        public bool UsesRealTime { get; private set; } // 是否使用真实时间
        public float OnEachLoopStartTime { get; private set; }

        /// <summary>
        /// 循环次数
        /// </summary>
        public uint LoopTimes { get; private set; } //必须为正数 循环次数
        public float StartTime { get; private set; } //开始时间

        /// <summary>
        /// 总时间
        /// </summary>
        public float TotalTime { get; private set; }

        public bool IsDone
        {
            get { return _isDone; }
        }

        private bool _isPause = false;

        public bool IsPause
        {
            get { return _isPause; }
            set
            {
                if (value && !_isPause && !IsDone)
                {
                    OnPauseTime = GetWorldTime();
                }
                _isPause = value;
            }
        }

        public float OnPauseTime { get; private set; }
        public float OnStartTime { get; private set; }
        private bool _isDone = false;
        private float _lastUpdateTime;

        private readonly Action _onComplete;
        private readonly Action _onFinish;
        private readonly Action<float> _onUpdate;

        public void Update(float elapsedTime)
        {
            if (_isDone)
            {
                TimerManager.Instance.Cancel(this);
                return;
            }
            if (CheckIsDone())
            {
                _lastUpdateTime = this.GetWorldTime();
                if (_onFinish != null) _onFinish();
                if (_onComplete != null) _onComplete();
                if (_onUpdate != null) _onUpdate(elapsedTime);
                return;
            }
            if (_isPause)
            {
                OnEachLoopStartTime += this.GetDelaTime();
                OnStartTime += this.GetDelaTime();
                this._lastUpdateTime = this.GetWorldTime();
                return;
            }
            if (_onUpdate != null) _onUpdate(elapsedTime);
            _lastUpdateTime = this.GetWorldTime();
            if (_lastUpdateTime >= FireTime())
            {
                if (_onComplete != null) _onComplete();
                OnEachLoopStartTime = GetWorldTime();
            }
        }

        private float GetDelaTime()
        {
            return this.GetWorldTime() - _lastUpdateTime;
        }

        private bool CheckIsDone()
        {
            _isDone = (_lastUpdateTime - OnStartTime) >= TotalTime;
            return _isDone;
        }

        private float FireTime()
        {
            return OnEachLoopStartTime + Duration;
        }

        public float OnEachDurationElapsedTime()
        {
            return _lastUpdateTime - OnEachLoopStartTime;
        }

        /// <summary>
        /// 获得从开始到现在执行的时间受暂停影响
        /// </summary>
        /// <returns></returns>
        public float GetElapsedTime()
        {
            if (IsDone)
            {
                return TotalTime;
            }
            return GetWorldTime() - OnStartTime;
        }

        /// <summary>
        /// 获得执行时间  不受暂停影响,只受是否
        /// </summary>
        /// <returns></returns>
        public float GetElapsedTimeSinceRegister()
        {
            return GetWorldTime() - StartTime;
        }

        /// <summary>
        /// 得到时间循环次数;
        /// </summary>
        /// <returns></returns>
        public uint GetElapsedLoopTime()
        {
            if (IsDone)
            {
                return LoopTimes;
            }
            else
            {
                return (uint) (GetElapsedTime()/Duration);
            }
        }

        /// <summary>
        /// 获取执行剩余时间
        /// </summary>
        /// <returns></returns>
        public float GetRemainTime()
        {
            if (IsDone)
            {
                return 0;
            }
            return TotalTime - GetElapsedTime();
        }

        private float GetWorldTime()
        {
            return this.UsesRealTime ? Time.realtimeSinceStartup : Time.time;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值