private SessionTiming(TimingDataViewModel timingDataViewModel, ISessionTelemetryController sessionTelemetryController) { PaceLaps = 4; DisplayBindTimeRelative = false; TimingDataViewModel = timingDataViewModel; SessionTelemetryController = sessionTelemetryController; }
private void DataGridRow_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) { DataGridRow Row = sender as DataGridRow; TimingDataViewModel File = Row.DataContext as TimingDataViewModel; File.OpenCommand.Execute(null); }
private void RemoveTab_Click(object sender, RoutedEventArgs e) { Button RemoveTabButton = (Button)e.Source; TimingDataViewModel TabToRemove = (TimingDataViewModel)RemoveTabButton.DataContext; CloseTab(TabToRemove); }
private TreeGridModel GenerateGroupedModel(TreeGridModel UngroupedModel) { IEnumerable <TimingDataViewModel> TimingDataModel = UngroupedModel.Cast <TimingDataViewModel>(); double OverrideDuration = TimingDataModel.ElementAt(0).ParentDurationOverride ?? TimingDataModel.Sum(d => d.InclusiveDuration); List <TimingDataViewModel> ClonedChildren = new List <TimingDataViewModel>(); foreach (TimingDataViewModel Child in TimingDataModel) { TimingDataViewModel ClonedChild = Child.Clone(); if (ClonedChild.HasChildren) { IEnumerable <TimingDataViewModel> GroupedChildren = GroupChildren(ClonedChild.Children.Cast <TimingDataViewModel>()); ClonedChild.Children.Clear(); foreach (TimingDataViewModel GroupedChild in GroupedChildren) { ClonedChild.Children.Add(GroupedChild); } } ClonedChildren.Add(ClonedChild); } IEnumerable <TimingDataViewModel> GroupedClonedChildren = GroupChildren(ClonedChildren); foreach (TimingDataViewModel Child in GroupedClonedChildren) { Child.ParentDurationOverride = OverrideDuration; } return(new TreeGridModel(GroupedClonedChildren)); }
private void UpdateUIForAggregate(TimingDataViewModel TimingData) { FilesModel = GenerateTreeGridModel(TimingData.Children[0]); IncludesModel = GenerateTreeGridModel(TimingData.Children[1]); ClassesModel = GenerateTreeGridModel(TimingData.Children[2]); FunctionsModel = GenerateTreeGridModel(TimingData.Children[3]); FlattenedIncludesModel = null; GroupedClassesModel = null; GroupedFunctionsModel = null; UpdateTabVisibility(FilesModel.FlatModel, FilesTab, FilesGrid); UpdateTabVisibility(IncludesModel.FlatModel, IncludesTab, IncludesGrid); UpdateTabVisibility(ClassesModel.FlatModel, ClassesTab, ClassesGrid); UpdateTabVisibility(FunctionsModel.FlatModel, FunctionsTab, FunctionsGrid); FlattenIncludes.IsEnabled = false; GroupClassTemplates.IsEnabled = false; GroupFunctionTemplates.IsEnabled = false; FilesGrid.CountColumn.Visibility = Visibility.Collapsed; IncludesGrid.CountColumn.Visibility = Visibility.Visible; IncludesGrid.ExclusiveDurationColumn.Visibility = Visibility.Collapsed; ClassesGrid.ExclusiveDurationColumn.Visibility = Visibility.Collapsed; FunctionsGrid.ExclusiveDurationColumn.Visibility = Visibility.Collapsed; }
private void StackPanel_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { if (e.ChangedButton == System.Windows.Input.MouseButton.Middle) { StackPanel TabStackPanel = (StackPanel)sender; TimingDataViewModel TabToRemove = (TimingDataViewModel)TabStackPanel.DataContext; CloseTab(TabToRemove); } }
private SessionTiming(TimingDataViewModel timingDataViewModel, ISessionTelemetryController sessionTelemetryController, IRatingProvider ratingProvider, ITrackRecordsController trackRecordsController, IChampionshipCurrentEventPointsProvider championshipCurrentEventPointsProvider, ISessionEventProvider sessionEventProvider) { _ratingProvider = ratingProvider; _trackRecordsController = trackRecordsController; _championshipCurrentEventPointsProvider = championshipCurrentEventPointsProvider; _sessionEventProvider = sessionEventProvider; PaceLaps = 4; DisplayBindTimeRelative = false; TimingDataViewModel = timingDataViewModel; SessionTelemetryController = sessionTelemetryController; _ratingUpdateStopwatch = Stopwatch.StartNew(); }
private void LoadTimingFile(string FilePath) { if (!File.Exists(FilePath)) { string ErrorString = "Unable to load file \"" + FilePath + "\""; Console.WriteLine(ErrorString); MessageBox.Show(ErrorString + Environment.NewLine + "(File not found)", "File Not Found", MessageBoxButton.OK, MessageBoxImage.Question); return; } JumpList.AddToRecentCategory(FilePath); try { TimingDataViewModel NewTimingData = TimingDataViewModel.FromBinaryFile(FileReference.FromString(FilePath)); // If this is an aggregate, hook up the open commands for the file rows. if (NewTimingData.Type == UnrealBuildTool.TimingDataType.Aggregate) { foreach (TimingDataViewModel File in NewTimingData.Children[0].Children.Cast <TimingDataViewModel>()) { OpenTimingDataCommand FileOpenCommand = new OpenTimingDataCommand(File); FileOpenCommand.OpenAction = (ViewModel) => { TimingDataViewModel FileTimingData = NewTimingData.LoadTimingDataFromBinaryBlob(File.Name); Dispatcher.BeginInvoke(new Action(() => { AddTimingDataViewModelToTabs(FileTimingData); })); }; File.OpenCommand = FileOpenCommand; } } AddTimingDataViewModelToTabs(NewTimingData); } catch (System.IO.EndOfStreamException e) { string ErrorString = "Unable to load file \"" + FilePath + "\""; Console.WriteLine(ErrorString); Console.WriteLine(e.ToString()); MessageBox.Show(ErrorString + Environment.NewLine + "(may be corrupted)", "Error Loading Timing File", MessageBoxButton.OK, MessageBoxImage.Error); } }
private void CloseTab(TimingDataViewModel TabToRemove) { int IndexToSelect = OpenedFiles.Items.IndexOf(TabToRemove) - 1; OpenedFiles.Items.Remove(TabToRemove); if (IndexToSelect == 0 && OpenedFiles.Items.Count == 1) { NoOpenTabsTab.Visibility = Visibility.Visible; } else { IndexToSelect = 1; } OpenedFiles.SelectedIndex = IndexToSelect; }
private void LoadTimingFile(string FilePath) { TimingDataViewModel NewTimingData = TimingDataViewModel.FromBinaryFile(FileReference.FromString(FilePath)); // If this is an aggregate, hook up the open commands for the file rows. if (NewTimingData.Type == UnrealBuildTool.TimingDataType.Aggregate) { foreach (TimingDataViewModel File in NewTimingData.Children[0].Children.Cast <TimingDataViewModel>()) { OpenTimingDataCommand FileOpenCommand = new OpenTimingDataCommand(File); FileOpenCommand.OpenAction = (ViewModel) => { TimingDataViewModel FileTimingData = NewTimingData.LoadTimingDataFromBinaryBlob(File.Name); Dispatcher.BeginInvoke(new Action(() => { AddTimingDataViewModelToTabs(FileTimingData); })); }; File.OpenCommand = FileOpenCommand; } } AddTimingDataViewModelToTabs(NewTimingData); }
private void FlattenIncludesInternal(Dictionary <string, TimingDataViewModel> FlattenedIncludes, IEnumerable <TimingDataViewModel> ViewModels, double ParentDurationOverride) { foreach (TimingDataViewModel TimingData in ViewModels) { if (FlattenedIncludes.ContainsKey(TimingData.Name)) { FlattenedIncludes[TimingData.Name].ExclusiveDuration += TimingData.ExclusiveDuration; } else { TimingDataViewModel FlattenedInclude = new TimingDataViewModel() { Name = TimingData.Name, Type = TimingData.Type, ParentDurationOverride = ParentDurationOverride, ExclusiveDuration = TimingData.ExclusiveDuration }; FlattenedIncludes.Add(FlattenedInclude.Name, FlattenedInclude); } FlattenIncludesInternal(FlattenedIncludes, TimingData.Children.Cast <TimingDataViewModel>(), ParentDurationOverride); } }
private void UpdateUIForSingleFile(TimingDataViewModel TimingData) { FilesModel = null; IncludesModel = GenerateTreeGridModel(TimingData.Children[0]); ClassesModel = GenerateTreeGridModel(TimingData.Children[1]); FunctionsModel = GenerateTreeGridModel(TimingData.Children[2]); FlattenedIncludesModel = GenerateFlattenedModel(IncludesModel); GroupedClassesModel = GenerateGroupedModel(ClassesModel); GroupedFunctionsModel = GenerateGroupedModel(FunctionsModel); UpdateTabVisibility(null, FilesTab, FilesGrid); UpdateTabVisibility(FlattenIncludes.IsChecked == true ? FlattenedIncludesModel.FlatModel : IncludesModel.FlatModel, IncludesTab, IncludesGrid); UpdateTabVisibility(GroupClassTemplates.IsChecked == true ? GroupedClassesModel.FlatModel : ClassesModel.FlatModel, ClassesTab, ClassesGrid); UpdateTabVisibility(GroupFunctionTemplates.IsChecked == true ? GroupedFunctionsModel.FlatModel : FunctionsModel.FlatModel, FunctionsTab, FunctionsGrid); FlattenIncludes.IsEnabled = true; GroupClassTemplates.IsEnabled = true; GroupFunctionTemplates.IsEnabled = true; IncludesGrid.CountColumn.Visibility = Visibility.Collapsed; IncludesGrid.ExclusiveDurationColumn.Visibility = Visibility.Visible; ClassesGrid.ExclusiveDurationColumn.Visibility = Visibility.Visible; FunctionsGrid.ExclusiveDurationColumn.Visibility = Visibility.Visible; }
private void AddTimingDataViewModelToTabs(TimingDataViewModel NewViewModel) { NoOpenTabsTab.Visibility = Visibility.Collapsed; OpenedFiles.Items.Add(NewViewModel); OpenedFiles.SelectedItem = NewViewModel; }
#pragma warning restore CS0067 public OpenTimingDataCommand(TimingDataViewModel TimingData) { ViewModelToOpen = TimingData; }
private void TimingDataTab_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) { FilesModel?.Clear(); IncludesModel?.Clear(); ClassesModel?.Clear(); FunctionsModel?.Clear(); GroupedClassesModel?.Clear(); GroupedFunctionsModel?.Clear(); IncludesGrid.DataContext = null; ClassesGrid.DataContext = null; FunctionsGrid.DataContext = null; return; } // Save off current relevant state for the old tab if needed. if (e.OldValue != null) { TimingDataViewModel OldTimingData = e.OldValue as TimingDataViewModel; if (!TabStates.ContainsKey(OldTimingData)) { TabStates.Add(OldTimingData, new TabState()); } TabState TabState = TabStates[OldTimingData]; TabState.SetTabState(FilesTab, FilesGrid.Grid); TabState.SetTabState(IncludesTab, IncludesGrid.Grid); TabState.SetTabState(ClassesTab, ClassesGrid.Grid); TabState.SetTabState(FunctionsTab, FunctionsGrid.Grid); TabState.FlattenIncludes = FlattenIncludes.IsChecked; TabState.GroupClasses = GroupClassTemplates.IsChecked; TabState.GroupFunctions = GroupFunctionTemplates.IsChecked; } TimingDataViewModel NewTimingData = e.NewValue as TimingDataViewModel; // Determine whether we loaded a single file's data or a summary file. if (NewTimingData.Type == TimingDataType.Aggregate) { UpdateUIForAggregate(NewTimingData); } else { UpdateUIForSingleFile(NewTimingData); } SummaryTabs.SelectedItem = FilesModel == null ? IncludesTab : FilesTab; if (TabStates.TryGetValue(NewTimingData, out TabState State)) { if (NewTimingData.Type != TimingDataType.Aggregate) { FlattenIncludes.IsChecked = State.FlattenIncludes; GroupClassTemplates.IsChecked = State.GroupClasses; GroupFunctionTemplates.IsChecked = State.GroupFunctions; } RefreshTabState(FilesTab, State); RefreshTabState(IncludesTab, State); RefreshTabState(ClassesTab, State); RefreshTabState(FunctionsTab, State); } else { FilesGrid.Grid.Columns[0].SortDirection = ListSortDirection.Ascending; IncludesGrid.Grid.Columns[2].SortDirection = ListSortDirection.Descending; ClassesGrid.Grid.Columns[2].SortDirection = ListSortDirection.Descending; FunctionsGrid.Grid.Columns[2].SortDirection = ListSortDirection.Descending; } SortModel(FilesGrid.Grid); SortModel(IncludesGrid.Grid); SortModel(ClassesGrid.Grid); SortModel(FunctionsGrid.Grid); }
private IEnumerable <TimingDataViewModel> GroupChildren(IEnumerable <TimingDataViewModel> Children) { List <TimingDataViewModel> GroupedChildren = new List <TimingDataViewModel>(); Dictionary <string, List <TimingDataViewModel> > ChildGroups = new Dictionary <string, List <TimingDataViewModel> >(); foreach (TimingDataViewModel Child in Children) { if (Child.HasChildren) { IEnumerable <TimingDataViewModel> ChildsGroupedChildren = GroupChildren(Child.Children.Cast <TimingDataViewModel>()); Child.Children.Clear(); foreach (TimingDataViewModel ChildChild in ChildsGroupedChildren) { Child.Children.Add(ChildChild); } } // See if this is a templated class. If not, add it as is. Match Match = Regex.Match(Child.Name, @"^([^<]*)(?<Template><.*>)"); if (!Match.Success) { // Check to see if we've seen this name before. If so, group them together. string DuplicateGroupName = $"{Child.Name} (Duplicates)"; if (ChildGroups.ContainsKey(DuplicateGroupName)) { ChildGroups[DuplicateGroupName].Add(Child); } else { ChildGroups.Add(DuplicateGroupName, new List <TimingDataViewModel>()); ChildGroups[DuplicateGroupName].Add(Child); } } else { // Generate group name from template. int TemplateParamCount = Match.Groups["Template"].Value.Count(c => c == ',') + 1; List <string> TemplateParamSig = new List <string>(TemplateParamCount); for (int i = 0; i < TemplateParamCount; ++i) { TemplateParamSig.Add("..."); } string GroupName = Child.Name.Replace(Match.Groups["Template"].Value, $"<{string.Join(", ", TemplateParamSig)}>"); // See if we have a group for this template already. If not, add it. if (!ChildGroups.ContainsKey(GroupName)) { ChildGroups.Add(GroupName, new List <TimingDataViewModel>()); } ChildGroups[GroupName].Add(Child); } } // Add grouped children. foreach (KeyValuePair <string, List <TimingDataViewModel> > Group in ChildGroups) { if (Group.Value.Count == 1) { GroupedChildren.Add(Group.Value.First()); continue; } TimingDataViewModel NewViewModel = new TimingDataViewModel() { Name = Group.Key, HasChildren = true, }; foreach (TimingDataViewModel Child in Group.Value) { NewViewModel.Children.Add(Child); } GroupedChildren.Add(NewViewModel); } return(GroupedChildren); }