PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/PingTracer/MainViewModel.cs

https://github.com/kanosaki/PingTracer
C# | 303 lines | 263 code | 40 blank | 0 comment | 29 complexity | 7c7dd98e998df93f721be0569384da57 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Collections.ObjectModel;
  6. using System.Reactive;
  7. using System.Reactive.Subjects;
  8. using System.Reactive.Linq;
  9. using System.Reactive.Threading.Tasks;
  10. using System.Reactive.Concurrency;
  11. using System.Windows;
  12. using Livet;
  13. using Livet.EventListeners;
  14. using System.Windows.Input;
  15. using Livet.Commands;
  16. using System.Windows.Media;
  17. namespace PingTracer
  18. {
  19. public class MainViewModel : ViewModel
  20. {
  21. public MainViewModel()
  22. {
  23. this.LoadDefaults();
  24. this.Init();
  25. }
  26. #region Initializers
  27. protected virtual void LoadDefaults()
  28. {
  29. this.PollInterval = TimeSpan.FromSeconds(2);
  30. this.RoundtripMaxItems = 30;
  31. this.Ttl = 30;
  32. this.TargetHost = "google.com";
  33. }
  34. public void Init()
  35. {
  36. _analyzer = new PingResultAnalyzer();
  37. _analyzerAdapter = new PropertyChangedEventListener(_analyzer, (s, e) => this.RaisePropertyChanged(e.PropertyName));
  38. this.StartTime = DateTime.Now;
  39. this.Roundtrips = new ObservableCollection<ChartEntry>();
  40. this.TogglePollCommand = new ViewModelCommand(this.TogglePoll);
  41. this.InitTracer();
  42. }
  43. public void InitTracer()
  44. {
  45. if (_nextPingResultSubscription != null)
  46. _nextPingResultSubscription.Dispose();
  47. _tracer = new Tracer(this.TargetHost, this.Ttl, this.PollInterval);
  48. _nextPingResultSubscription =
  49. _tracer.PingReplies
  50. .ObserveOnDispatcher()
  51. .Subscribe(this.OnNextPingResult);
  52. _analyzer.UpdateTracer(_tracer);
  53. }
  54. #endregion
  55. #region Configuration Properties
  56. #region RoundtripMaxItems
  57. private int _RoundtripMaxItems;
  58. public int RoundtripMaxItems
  59. {
  60. get
  61. { return _RoundtripMaxItems; }
  62. set
  63. {
  64. if (_RoundtripMaxItems == value)
  65. return;
  66. _RoundtripMaxItems = value;
  67. RaisePropertyChanged("RoundtripMaxItems");
  68. }
  69. }
  70. #endregion
  71. #region Ttl
  72. private int _Ttl;
  73. public int Ttl
  74. {
  75. get
  76. { return _Ttl; }
  77. set
  78. {
  79. if (_Ttl == value)
  80. return;
  81. _Ttl = value;
  82. RaisePropertyChanged("Ttl");
  83. }
  84. }
  85. #endregion
  86. #region PollInterval
  87. private TimeSpan _PollInterval;
  88. public TimeSpan PollInterval
  89. {
  90. get
  91. { return _PollInterval; }
  92. set
  93. {
  94. if (_PollInterval == value)
  95. return;
  96. _PollInterval = value;
  97. RaisePropertyChanged("PollInterval");
  98. }
  99. }
  100. #endregion
  101. #region TargetHost
  102. private string _TargetHost;
  103. public string TargetHost
  104. {
  105. get
  106. { return _TargetHost; }
  107. set
  108. {
  109. if (_TargetHost == value)
  110. return;
  111. _TargetHost = value;
  112. RaisePropertyChanged("TargetHost");
  113. }
  114. }
  115. #endregion
  116. #endregion
  117. #region Volatile Properties
  118. Tracer _tracer;
  119. IDisposable _nextPingResultSubscription;
  120. PingResultAnalyzer _analyzer;
  121. PropertyChangedEventListener _analyzerAdapter;
  122. #region Analyzer adapting properties
  123. public TimeSpan AnalyzerTargetRange { get { return _analyzer.TargetRange; } }
  124. public double RoundtripAverage { get { return _analyzer.RoundtripAverage; } }
  125. public double RoundtripVariance { get { return _analyzer.RoundtripVariance; } }
  126. public double RoundtripScore { get { return _analyzer.RoundtripScore; } }
  127. public double LastRoundtrip { get { return _analyzer.LastRoundtrip; } }
  128. public int IgnoredValuesCount { get { return _analyzer.IgnoredValuesCount; } }
  129. #endregion
  130. #region StateColor
  131. private Brush _stateColor;
  132. public Brush StateColor
  133. {
  134. get
  135. { return _stateColor; }
  136. set
  137. {
  138. if (_stateColor == value)
  139. return;
  140. _stateColor = value;
  141. RaisePropertyChanged("StateColor");
  142. }
  143. }
  144. #endregion
  145. #region ToggleButtonContent
  146. private string _ToggleButtonContent = "Start";
  147. public string ToggleButtonContent
  148. {
  149. get
  150. { return _ToggleButtonContent; }
  151. set
  152. {
  153. if (_ToggleButtonContent == value)
  154. return;
  155. _ToggleButtonContent = value;
  156. RaisePropertyChanged("ToggleButtonContent");
  157. }
  158. }
  159. #endregion
  160. #region StartTime
  161. private DateTime _StartTime;
  162. public DateTime StartTime
  163. {
  164. get
  165. { return _StartTime; }
  166. set
  167. {
  168. if (_StartTime == value)
  169. return;
  170. _StartTime = value;
  171. RaisePropertyChanged("StartTime");
  172. }
  173. }
  174. #endregion
  175. #region ElapsedTime
  176. public TimeSpan ElapsedTime
  177. {
  178. get
  179. { return DateTime.Now - this.StartTime; }
  180. }
  181. #endregion
  182. #region SignalLevel変更通知プロパティ
  183. private int _SignalLevel;
  184. public int SignalLevel
  185. {
  186. get
  187. { return _SignalLevel; }
  188. set
  189. {
  190. if (_SignalLevel == value)
  191. return;
  192. _SignalLevel = value;
  193. RaisePropertyChanged("SignalLevel");
  194. }
  195. }
  196. #endregion
  197. public ObservableCollection<ChartEntry> Roundtrips { get; private set; }
  198. public ICommand TogglePollCommand { get; private set; }
  199. #endregion
  200. public void TogglePoll()
  201. {
  202. _tracer.Enabled = !_tracer.Enabled;
  203. if (_tracer.Enabled)
  204. {
  205. this.StartTime = DateTime.Now;
  206. this.ToggleButtonContent = "Stop";
  207. }
  208. else
  209. {
  210. this.ToggleButtonContent = "Start";
  211. }
  212. }
  213. protected void OnNextPingResult(PingResult pr)
  214. {
  215. var label = pr.TimeStamp.ToString("mm:ss");
  216. var time = (int)pr.RoundtripTime;
  217. this.PushRoundtripItem(label, time);
  218. this.UpdateVisualizers(pr);
  219. this.RaisePropertyChanged(() => this.ElapsedTime);
  220. }
  221. public void UpdateVisualizers(PingResult result)
  222. {
  223. this.StateColor = this.GetScoreColor(this.RoundtripScore);
  224. this.SignalLevel = Math.Max(5 - (int)Math.Floor(this.RoundtripScore / 10), 0);
  225. }
  226. protected Brush GetScoreColor(double score)
  227. {
  228. if (score > 50)
  229. return Brushes.Red;
  230. else if (score > 40)
  231. return Brushes.OrangeRed;
  232. else if (score > 30)
  233. return Brushes.Orange;
  234. else if (score > 20)
  235. return Brushes.Gold;
  236. else if (score > 10)
  237. return Brushes.Green;
  238. else
  239. return Brushes.RoyalBlue;
  240. }
  241. public void PushRoundtripItem(string tag, int value)
  242. {
  243. if (this.Roundtrips.Count > this.RoundtripMaxItems)
  244. {
  245. this.Roundtrips.RemoveAt(0);
  246. }
  247. this.Roundtrips.Add(new ChartEntry()
  248. {
  249. Label = tag,
  250. Current = value,
  251. Average = this.RoundtripAverage,
  252. Score = this.RoundtripScore
  253. });
  254. }
  255. }
  256. public class ChartEntry
  257. {
  258. public string Label { get; set; }
  259. public double Current { get; set; }
  260. public double Average { get; set; }
  261. public double Score { get; set; }
  262. }
  263. }