1118OPSSNew/Assets/SKFramework/Core/Timer/Chronometer.cs

153 lines
3.9 KiB
C#

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace SK.Framework
{
/// <summary>
/// 秒表
/// </summary>
public sealed class Chronometer : ITimer
{
public sealed class Record
{
public object context;
public float time;
public Record(object context, float time)
{
this.context = context;
this.time = time;
}
}
private float beginTime;
private float pausedTime;
private readonly bool isIgnoreTimeScale;
private readonly MonoBehaviour executer;
private Action onLaunch;
private Action<float> onExecute;
private Action onPause;
private Action onResume;
private Action onStop;
private Func<bool> stopWhen;
private Func<bool> shotWhen;
private readonly List<Record> records;
public float ElapsedTime { get; private set; }
public bool IsCompleted { get; private set; }
public bool IsPaused { get; private set; }
public ReadOnlyCollection<Record> Records
{
get
{
return new ReadOnlyCollection<Record>(records);
}
}
public Chronometer(bool isIgnoreTimeScale = false, MonoBehaviour executer = null)
{
this.isIgnoreTimeScale = isIgnoreTimeScale;
this.executer = executer;
records = new List<Record>();
}
public Chronometer OnLaunch(Action onLaunch)
{
this.onLaunch = onLaunch;
return this;
}
public Chronometer OnExecute(Action<float> onExecute)
{
this.onExecute = onExecute;
return this;
}
public Chronometer OnPause(Action onPause)
{
this.onPause = onPause;
return this;
}
public Chronometer OnResume(Action onResume)
{
this.onResume = onResume;
return this;
}
public Chronometer OnStop(Action onStop)
{
this.onStop = onStop;
return this;
}
public Chronometer StopWhen(Func<bool> predicate)
{
stopWhen = predicate;
return this;
}
public Chronometer ShotWhen(Func<bool> predicate)
{
shotWhen = predicate;
return this;
}
public void Shot(object context = null)
{
records.Add(new Record(context, ElapsedTime));
}
public void Launch()
{
beginTime = isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time;
onLaunch?.Invoke();
this.Begin(executer != null ? executer : Timer.Instance);
}
public void Pause()
{
IsPaused = true;
pausedTime = isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time;
onPause?.Invoke();
}
public void Resume()
{
IsPaused = false;
beginTime += (isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time) - pausedTime;
onResume?.Invoke();
}
public void Stop()
{
IsCompleted = true;
}
public bool Execute()
{
if (!IsCompleted && !IsPaused)
{
ElapsedTime = (isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time) - beginTime;
onExecute?.Invoke(ElapsedTime);
if (shotWhen != null && shotWhen.Invoke())
{
Shot();
}
}
if (!IsCompleted && stopWhen != null && stopWhen.Invoke())
{
IsCompleted = true;
}
if (IsCompleted)
{
onStop?.Invoke();
}
return IsCompleted;
}
}
}