using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; using Artemis.Core.Modules; using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.DataModelVisualization.Shared; using Artemis.UI.Shared.Services; using Avalonia.Threading; using DynamicData; using ReactiveUI; namespace Artemis.UI.Screens.Debugger.DataModel; public class DataModelDebugViewModel : ActivatableViewModelBase { private readonly IDataModelUIService _dataModelUIService; private readonly IPluginManagementService _pluginManagementService; private readonly DispatcherTimer _updateTimer; private bool _isModuleFilterEnabled; private DataModelPropertiesViewModel? _mainDataModel; private string? _propertySearch; private Module? _selectedModule; private bool _slowUpdates; public DataModelDebugViewModel(IDataModelUIService dataModelUIService, IPluginManagementService pluginManagementService) { _dataModelUIService = dataModelUIService; _pluginManagementService = pluginManagementService; _updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(40), DispatcherPriority.Background, (_, _) => Update()); DisplayName = "Data Model"; Modules = new ObservableCollection(); this.WhenActivated(disposables => { Observable.FromEventPattern(x => pluginManagementService.PluginFeatureEnabled += x, x => pluginManagementService.PluginFeatureEnabled -= x) .Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature)) .DisposeWith(disposables); Observable.FromEventPattern(x => pluginManagementService.PluginFeatureDisabled += x, x => pluginManagementService.PluginFeatureDisabled -= x) .Subscribe(d => PluginFeatureToggled(d.EventArgs.PluginFeature)) .DisposeWith(disposables); GetDataModel(); _updateTimer.Start(); Disposable.Create(() => { _updateTimer.Stop(); MainDataModel?.Dispose(); MainDataModel = null; }).DisposeWith(disposables); }); } public DataModelPropertiesViewModel? MainDataModel { get => _mainDataModel; set => RaiseAndSetIfChanged(ref _mainDataModel, value); } public string? PropertySearch { get => _propertySearch; set => RaiseAndSetIfChanged(ref _propertySearch, value); } public bool SlowUpdates { get => _slowUpdates; set { RaiseAndSetIfChanged(ref _slowUpdates, value); _updateTimer.Interval = TimeSpan.FromMilliseconds(_slowUpdates ? 500 : 25); } } public ObservableCollection Modules { get; } public Module? SelectedModule { get => _selectedModule; set { RaiseAndSetIfChanged(ref _selectedModule, value); GetDataModel(); } } public bool IsModuleFilterEnabled { get => _isModuleFilterEnabled; set { RaiseAndSetIfChanged(ref _isModuleFilterEnabled, value); if (!IsModuleFilterEnabled) SelectedModule = null; else GetDataModel(); } } private void Update() { if (MainDataModel == null) return; lock (MainDataModel) { MainDataModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(true)); } } private void PluginFeatureToggled(PluginFeature pluginFeature) { if (pluginFeature is Module) PopulateModules(); } private void GetDataModel() { MainDataModel = SelectedModule != null ? _dataModelUIService.GetPluginDataModelVisualization(new List {SelectedModule}, false) : _dataModelUIService.GetMainDataModelVisualization(); } private void PopulateModules() { Modules.Clear(); Modules.AddRange(_pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled).OrderBy(m => m.Info.Name)); if (MainDataModel == null) return; if (SelectedModule == null) { if (MainDataModel != null) _dataModelUIService.UpdateModules(MainDataModel); } else if (!SelectedModule.IsEnabled) { SelectedModule = null; } } }