using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; namespace Uestc.Auto6.Dso.Core { public abstract class MulticastPrsnt : IDisposable, IBroadcaster where V : IView { private protected abstract INotifyPropertyChanged? Model { get; } private readonly List _Views = new(); public IEnumerable GetViewList() { return _Views.ToList(); } public Boolean TryAddView(V vu) { Boolean res = false; lock ((_Views as ICollection).SyncRoot) { if (!_Views.Contains(vu)) { _Views.Add(vu); res = true; } } return res; } public void AddViewList(IEnumerable vuList) { lock ((_Views as ICollection).SyncRoot) { foreach (var vu in vuList) { if (!_Views.Contains(vu)) { _Views.Add(vu); } } } } public Boolean TryRemoveView(V vu) { Boolean res = false; lock ((_Views as ICollection).SyncRoot) { var idx = _Views.IndexOf(vu); if (idx >= 0) { _Views.RemoveAt(idx); res = true; } } return res; } public void RemoveViewList(IEnumerable vuList) { lock ((_Views as ICollection).SyncRoot) { foreach (var vu in vuList) { var idx = _Views.IndexOf(vu); if (idx >= 0) { _Views.RemoveAt(idx); } } } } public Boolean FrozenVu { get; set; } = false; public event EventHandler? PublisherChanged; protected void OnRaiseCustomEvent(CustomEventArg e) { PublisherChanged?.Invoke(this, e); } protected internal void OnPropertyChanged(Object? sender, PropertyChangedEventArgs e) { OnRaiseCustomEvent(new CustomEventArg(e.PropertyName ?? "")); if (!FrozenVu) { lock ((_Views as ICollection).SyncRoot) { //foreach (var vu in GetViewList()) try { foreach (var vu in _Views) { vu.UpdateView(this, e.PropertyName ?? ""); } } catch { throw; } } } } #region Dispose private Boolean _Disposed = false; public void Dispose() { Dispose(true); //标记gc不在调用析构函数 GC.SuppressFinalize(this); } ~MulticastPrsnt() { Dispose(false); } private protected virtual void Dispose(Boolean disposing) { //如果已经被回收,就中断执行 if (_Disposed) { return; } if (disposing) { //TODO:释放本对象中管理的托管资源 _Views.Clear(); var m = Model; if (m != null) { m.PropertyChanged -= OnPropertyChanged; } } //TODO:释放非托管资源 _Disposed = true; } #endregion } }