using System;
using System.Collections.Generic;
using UnityEngine;
namespace LazyPan.Tool {
public enum ClockType {
DateTimeClock,
UnityTimeClock,
}
public class Clock {
Action onAlarm;
public readonly ClockType type;
public readonly float alarmTime1;
public readonly DateTime alarmTime2 = DateTime.Now;
readonly bool repeat = false;
readonly float interval = 10;
float nextAlarmSecond = 0f;
public bool IsStopped { get; private set; }
public Clock(float time, Action callBack) {
type = ClockType.UnityTimeClock;
alarmTime1 = time;
onAlarm = callBack;
}
public Clock(float time, float interval, Action callBack) {
type = ClockType.UnityTimeClock;
alarmTime1 = time;
repeat = true;
this.interval = interval;
nextAlarmSecond = time + interval;
onAlarm = callBack;
}
public Clock(DateTime time, Action callBack) {
type = ClockType.DateTimeClock;
alarmTime2 = time;
onAlarm = callBack;
}
public void Invoke() {
switch (type) {
case ClockType.DateTimeClock:
if (DateTime.Now >= alarmTime2) {
Alarm(true);
IsStopped = true;
}
break;
case ClockType.UnityTimeClock:
if (repeat) {
if (Time.time >= nextAlarmSecond) {
Alarm(false);
nextAlarmSecond += interval;
}
} else {
if (Time.time >= alarmTime1) {
Alarm(true);
IsStopped = true;
}
}
break;
}
}
public void Abandon() {
if (IsStopped) {
return;
}
IsStopped = true;
onAlarm = null;
}
private void Alarm(bool once) {
try {
onAlarm?.Invoke();
} catch (Exception e) {
IsStopped = true;
onAlarm = null;
Logger.PrintE(e.ToString());
} finally {
if (once) {
onAlarm = null;
}
}
}
}
public class ClockUtil : Singleton<ClockUtil> {
readonly List<Clock> clocks = new List<Clock>();
public Clock AlarmAt(DateTime dateTime, Action callBack) {
if (dateTime < DateTime.Now) {
Logger.PrintE($"不合理的报警时间:dateTime-->{dateTime}");
return null;
}
var clock = new Clock(dateTime, callBack);
clocks.Add(clock);
return clock;
}
public Clock AlarmAfter(float second, Action callBack) {
if (second < 0f) {
Logger.PrintE($"不合理的报警时间:second-->{second}");
return null;
}
var clock = new Clock(Time.time + second, callBack);
if (second == 0f) {
clock.Invoke();
return clock;
}
clocks.Add(clock);
return clock;
}
public Clock AlarmRepeat(float delay, float repeatInterval, Action callBack) {
if (delay < 0f) {
Logger.PrintE($"不合理的延迟时间:delay-->{delay}");
return null;
}
if (repeatInterval <= 0f) {
Logger.PrintE($"不合理的重复间隔:repeatInterval-->{repeatInterval}");
return null;
}
var clock = new Clock(Time.time + delay, repeatInterval, callBack);
clocks.Add(clock);
return clock;
}
public void Stop(Clock clock) {
clock?.Abandon();
}
public void Dispose() {
foreach (var clock in clocks) {
clock.Abandon();
}
}
private void Update() {
for (var i = clocks.Count - 1; i >= 0; i--) {
var clock = clocks[i];
if (clock.IsStopped) {
clocks.RemoveAt(i);
} else {
clock.Invoke();
}
}
}
}
}
using UnityEngine;
namespace LazyPan.Tool {
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
static T instance = null;
public static T Instance {
get {
if (instance != null) {
return instance;
}
instance = new GameObject(typeof(T).Name).AddComponent<T>();
if (Application.isPlaying) {
DontDestroyOnLoad(instance.gameObject);
}
return instance;
}
}
private void Awake() {
instance = this as T;
}
}
}