Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Clients.Hive.JobManager/3.3/Views/HiveResourceSelector.cs @ 9426

Last change on this file since 9426 was 8165, checked in by abeham, 12 years ago

#1762: Some changes to progress handling, see the ticket for more details

File size: 13.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Text;
27using System.Windows.Forms;
28using HeuristicLab.Clients.Hive.JobManager.ExtensionMethods;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33
34namespace HeuristicLab.Clients.Hive.JobManager.Views {
35  [View("Hive Resource Selector View")]
36  [Content(typeof(IItemList<Resource>), true)]
37  public partial class HiveResourceSelector : ItemView, IDisposable {
38    private const int slaveImageIndex = 0;
39    private const int slaveGroupImageIndex = 1;
40    private string currentSearchString;
41    private ISet<TreeNode> mainTreeNodes;
42    private ISet<TreeNode> filteredTreeNodes;
43    private ISet<TreeNode> nodeStore;
44    private Progress progress;
45    private ProgressView progressView;
46
47    private ISet<Resource> selectedResources;
48    public ISet<Resource> SelectedResources {
49      get { return selectedResources; }
50      set { selectedResources = value; }
51    }
52
53    public new IItemList<Resource> Content {
54      get { return (IItemList<Resource>)base.Content; }
55      set { base.Content = value; }
56    }
57
58    public HiveResourceSelector() {
59      InitializeComponent();
60      mainTreeNodes = new HashSet<TreeNode>();
61      filteredTreeNodes = new HashSet<TreeNode>();
62      nodeStore = new HashSet<TreeNode>();
63      selectedResources = new HashSet<Resource>();
64      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.MonitorLarge);
65      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.NetworkCenterLarge);
66      progress = new Progress() {
67        CanBeCanceled = false,
68        ProgressState = ProgressState.Finished
69      };
70    }
71
72    protected override void DeregisterContentEvents() {
73      if (progressView != null) {
74        progressView.Content = null;
75        progressView.Dispose();
76        progressView = null;
77      }
78      base.DeregisterContentEvents();
79    }
80
81    protected override void RegisterContentEvents() {
82      base.RegisterContentEvents();
83      progressView = new ProgressView(this, progress);
84    }
85
86    public void StartProgressView() {
87      if (InvokeRequired) {
88        Invoke(new Action(StartProgressView));
89      } else {
90        progress.Status = "Downloading resources. Please be patient.";
91        progress.ProgressState = ProgressState.Started;
92      }
93    }
94
95    public void FinishProgressView() {
96      if (InvokeRequired) {
97        Invoke(new Action(FinishProgressView));
98      } else {
99        progress.Finish();
100      }
101    }
102
103    protected override void OnContentChanged() {
104      base.OnContentChanged();
105
106      if (Content != null) {
107        selectedResources = new HashSet<Resource>(Content.Where(x => selectedResources.Any(y => x.Id == y.Id)));
108        UpdateMainTree();
109        ExtractStatistics();
110      } else {
111        mainTreeNodes.Clear();
112        UpdateFilteredTree();
113      }
114    }
115
116    #region MainTree Methods
117    private void UpdateMainTree() {
118      mainTreeNodes.Clear();
119
120      foreach (Resource g in Content) {
121        if (g.GetType() == typeof(SlaveGroup)) {
122          //root node
123          if (g.ParentResourceId == null) {
124            TreeNode tn = new TreeNode();
125            tn.ImageIndex = slaveGroupImageIndex;
126            tn.SelectedImageIndex = tn.ImageIndex;
127
128            tn.Tag = g;
129            tn.Text = g.Name;
130            tn.Checked = selectedResources.Any(x => x.Id == g.Id);
131
132            BuildMainTree(tn);
133            mainTreeNodes.Add(tn);
134          }
135        }
136      }
137      UpdateFilteredTree();
138    }
139
140    private void BuildMainTree(TreeNode tn) {
141      foreach (Resource r in Content.Where(s => s.ParentResourceId != null && s.ParentResourceId == ((Resource)tn.Tag).Id)) {
142        TreeNode stn = new TreeNode(r.Name);
143        if (r is Slave) stn.ImageIndex = slaveImageIndex;
144        else if (r is SlaveGroup) stn.ImageIndex = slaveGroupImageIndex;
145        stn.SelectedImageIndex = stn.ImageIndex;
146        stn.Tag = r;
147        stn.Checked = selectedResources.Any(x => x.Id == r.Id);
148        tn.Nodes.Add(stn);
149        mainTreeNodes.Add(stn);
150
151        BuildMainTree(stn);
152      }
153    }
154    #endregion
155
156    #region FilteredTree Methods
157    private void UpdateFilteredTree() {
158      filteredTreeNodes.Clear();
159      foreach (TreeNode n in mainTreeNodes) {
160        n.BackColor = SystemColors.Window;
161        if (currentSearchString == null || ((Resource)n.Tag).Name.ToLower().Contains(currentSearchString)) {
162          n.BackColor = string.IsNullOrEmpty(currentSearchString) ? SystemColors.Window : Color.LightBlue;
163          filteredTreeNodes.Add(n);
164          TraverseParentNodes(n);
165        }
166      }
167      UpdateResourceTree();
168    }
169
170    private void TraverseParentNodes(TreeNode node) {
171      if (node != null) {
172        for (TreeNode parent = node.Parent; parent != null; parent = parent.Parent)
173          filteredTreeNodes.Add(parent);
174      }
175    }
176    #endregion
177
178    #region ResourceTree Methods
179    private void UpdateResourceTree() {
180      resourcesTreeView.Nodes.Clear();
181      nodeStore.Clear();
182
183      foreach (TreeNode node in filteredTreeNodes) {
184        var clone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
185        if (clone == null) {
186          clone = (TreeNode)node.Clone();
187          nodeStore.Add(clone);
188          clone.Nodes.Clear();
189        }
190        foreach (TreeNode child in node.Nodes)
191          if (filteredTreeNodes.Any(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id)) {
192            var childClone = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)child.Tag).Id);
193            if (childClone == null) {
194              childClone = (TreeNode)child.Clone();
195              nodeStore.Add(childClone);
196              childClone.Nodes.Clear();
197            }
198            clone.Nodes.Add(childClone);
199          }
200      }
201      resourcesTreeView.Nodes.AddRange(nodeStore.Where(x => ((Resource)x.Tag).ParentResourceId == null).ToArray());
202      if (string.IsNullOrEmpty(currentSearchString)) ExpandSlaveGroupNodes();
203      else resourcesTreeView.ExpandAll();
204    }
205    #endregion
206
207    #region Events
208    private void resourcesTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
209      if (e.Action != TreeViewAction.Unknown) {
210        if (e.Node.Checked) {
211          IncludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
212          IncludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
213        } else {
214          ExcludeChildNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
215          ExcludeParentNodes(mainTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)e.Node.Tag).Id));
216        }
217        ExtractStatistics();
218      }
219    }
220
221    private void resourcesTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
222      if (e.Action != TreeViewAction.Unknown) {
223        ExtractStatistics(e.Node);
224      }
225    }
226
227    private void searchTextBox_TextChanged(object sender, System.EventArgs e) {
228      currentSearchString = searchTextBox.Text.ToLower();
229      UpdateFilteredTree();
230    }
231    #endregion
232
233    #region Helpers
234    private void IncludeChildNodes(TreeNode node) {
235      if (node != null) {
236        node.Checked = true;
237        selectedResources.Add((Resource)node.Tag);
238        AdjustNodeCheckedState(node);
239        foreach (TreeNode n in node.Nodes) IncludeChildNodes(n);
240      }
241    }
242
243    private void IncludeParentNodes(TreeNode node) {
244      if (node != null && node.Parent != null) {
245        TreeNode parent = node.Parent;
246        if (parent.Nodes.OfType<TreeNode>().All(x => x.Checked)) {
247          parent.Checked = true;
248          selectedResources.Add((Resource)parent.Tag);
249          AdjustNodeCheckedState(parent);
250          IncludeParentNodes(parent);
251        }
252      }
253    }
254
255    private void ExcludeChildNodes(TreeNode node) {
256      if (node != null) {
257        node.Checked = false;
258        selectedResources.Remove((Resource)node.Tag);
259        AdjustNodeCheckedState(node);
260        foreach (TreeNode n in node.Nodes) ExcludeChildNodes(n);
261      }
262    }
263
264    private void ExcludeParentNodes(TreeNode node) {
265      if (node != null) {
266        node.Checked = false;
267        selectedResources.Remove((Resource)node.Tag);
268        AdjustNodeCheckedState(node);
269        ExcludeParentNodes(node.Parent);
270      }
271    }
272
273    private void AdjustNodeCheckedState(TreeNode node) {
274      var filterdNode = filteredTreeNodes.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
275      var storedNode = nodeStore.SingleOrDefault(x => ((Resource)x.Tag).Id == ((Resource)node.Tag).Id);
276      if (filterdNode != null) filterdNode.Checked = node.Checked;
277      if (storedNode != null) storedNode.Checked = node.Checked;
278    }
279
280    private void ExpandSlaveGroupNodes() {
281      foreach (TreeNode n in nodeStore.Where(x => x.Tag is SlaveGroup)) {
282        TreeNode[] children = new TreeNode[n.Nodes.Count];
283        n.Nodes.CopyTo(children, 0);
284        if (children.Any(x => x.Tag is SlaveGroup)) n.Expand();
285      }
286    }
287
288    private void ExtractStatistics(TreeNode treeNode = null) {
289      StringBuilder sb = new StringBuilder();
290      Resource resource = treeNode == null ? null : treeNode.Tag as Resource;
291      ISet<Resource> resources = treeNode == null ? selectedResources : new HashSet<Resource>(treeNode.DescendantNodes().Select(x => x.Tag as Resource)); ;
292      IEnumerable<SlaveGroup> slaveGroups = resources.OfType<SlaveGroup>();
293      IEnumerable<Slave> slaves = resources.OfType<Slave>();
294      int cpuSpeed = 0, cores = 0, freeCores = 0, memory = 0, freeMemory = 0;
295      string contextString = treeNode == null ? "Selected" : "Included";
296
297      if (resources.Any() || resource != null) {
298        foreach (Slave s in slaves) {
299          cpuSpeed += s.CpuSpeed.GetValueOrDefault();
300          cores += s.Cores.GetValueOrDefault();
301          freeCores += s.FreeCores.GetValueOrDefault();
302          memory += s.Memory.GetValueOrDefault();
303          freeMemory += s.FreeMemory.GetValueOrDefault();
304        }
305        if (resource != null) {
306          if (resource is SlaveGroup) sb.Append("Slave group: ");
307          else if (resource is Slave) {
308            sb.Append("Slave: ");
309            if (!resources.Any()) {
310              Slave s = resource as Slave;
311              cpuSpeed = s.CpuSpeed.GetValueOrDefault();
312              cores = s.Cores.GetValueOrDefault();
313              freeCores = s.FreeCores.GetValueOrDefault();
314              memory = s.Memory.GetValueOrDefault();
315              freeMemory = s.FreeMemory.GetValueOrDefault();
316            }
317          }
318          sb.AppendLine(string.Format("{0}", resource.Name));
319        }
320        if (resource == null || resource is SlaveGroup) {
321          if (resources.Any()) {
322            sb.AppendFormat("{0} slave groups ({1}): ", contextString, slaveGroups.Count());
323            foreach (SlaveGroup sg in slaveGroups) sb.AppendFormat("{0}; ", sg.Name);
324            sb.AppendLine();
325            sb.AppendFormat("{0} slaves ({1}): ", contextString, slaves.Count());
326            foreach (Slave s in slaves) sb.AppendFormat("{0}; ", s.Name);
327            sb.AppendLine();
328          } else {
329            sb.Append("The selection does not inlcude any further resources.");
330          }
331        }
332        sb.AppendLine();
333        sb.AppendLine(string.Format("CPU speed: {0} MHz", cpuSpeed));
334        if (resources.Any()) sb.AppendLine(string.Format("Avg. CPU speed: {0:0.00} MHz", (double)cpuSpeed / resources.Count()));
335        sb.AppendLine(string.Format("Cores: {0}", cores));
336        sb.AppendLine(string.Format("Free cores: {0}", freeCores));
337        if (resources.Any()) sb.AppendLine(string.Format("Avg. free cores: {0:0.00}", (double)freeCores / resources.Count()));
338        sb.AppendLine(string.Format("Memory: {0} MB", memory));
339        sb.AppendFormat("Free memory: {0} MB", freeMemory);
340        if (resources.Any()) sb.Append(string.Format("{0}Avg. free memory: {1:0.00} MB", Environment.NewLine, (double)freeMemory / resources.Count()));
341      } else {
342        sb.Append("No resources selected.");
343      }
344
345      descriptionTextBox.Text = sb.ToString();
346    }
347    #endregion
348  }
349}
Note: See TracBrowser for help on using the repository browser.