项目里有代码专门监听网络环境的变化,特别是在下载中,如果遇到断网或者切换为移动网络,可能需要触发提醒等等。这种需求可能是通用的,于是便写了一个通用的监听代码。是
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;public delegate T XValueGetter<T>();public interface IValueObserver
{long GetId();bool Check(long checkTime);bool ReachCheckTime(long checkTime);void NotifyChange();
}public class XValueObserve<T> : IValueObserver
{public T CurrentValue;public long LastCheckTime;public XValueGetter<T> Getter { get; set; }public Action<T> OnValueChangeCallback { get; set; }public long CheckInterval;public long Id;public XValueObserve(long id, XValueGetter<T> getter, Action<T> onValueChangeCallback, long checkInterval){Id = id;Getter = getter;OnValueChangeCallback = onValueChangeCallback;CheckInterval = checkInterval;LastCheckTime = 0;CurrentValue = getter();}public long GetId(){return Id;}public bool ReachCheckTime(long checkTime){return checkTime - LastCheckTime >= CheckInterval;}public bool Check(long checkTime){T currentValue = Getter();LastCheckTime = checkTime;if (!currentValue.Equals(CurrentValue)){CurrentValue = currentValue;return true;}return false;}public void NotifyChange(){OnValueChangeCallback?.Invoke(CurrentValue);}
}public class XValueObserveManager
{private static Stopwatch s_stopWatch;private static long s_observerId;private static List<IValueObserver> s_observers;public static void Init(){s_observers = new List<IValueObserver>();s_stopWatch = new Stopwatch();s_observerId = 0;}public static void Start(){s_stopWatch.Start();}public static void Update(){foreach (IValueObserver observer in s_observers){if (observer.ReachCheckTime(s_stopWatch.ElapsedMilliseconds)){if (observer.Check(s_stopWatch.ElapsedMilliseconds)){observer.NotifyChange();}}}}public static long AddObserve<T>(XValueGetter<T> getter, Action<T> onValueChangeCallback, long checkInterval){XValueObserve<T> observe = new XValueObserve<T>(s_observerId++, getter, onValueChangeCallback, checkInterval);s_observers.Add(observe);return observe.Id;}public static void RemoveObserve(long id){s_observers.RemoveAll(observe => observe.GetId() == id);}
}
使用起来,也比较方便
void Start()
{XValueObserveManager.Init();XValueObserveManager.Start();int posObserverId = XValueObserveManager.AddObserve(() => transform.position, pos =>{Debug.Log(pos);}, 1000);int netObserverId = XValueObserveManager.AddObserve(() => Application.internetReachability, reach =>{Debug.Log(reach.ToString());}, 1000);
}
注意,这种变化观察都是非及时性质的,也就是并不会在变化发生的瞬间通知,而是最少要延迟一帧(基于Update执行)。
如果需要的是实时的,则需要另外的设计了,比如用事件管理器,但对于一些通用的数值则可能需要封装为属性,重载set方法,广播事件了。
翻译
搜索
复制