Created
August 29, 2022 05:26
-
-
Save kornman00/629c47dcfe10d6d9aedcfcf505c3a830 to your computer and use it in GitHub Desktop.
TraceListViewModel for Gemini PR #328
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.ComponentModel; | |
using System.ComponentModel.Composition; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Caliburn.Micro; | |
using Gemini.Framework; | |
using Gemini.Framework.Services; | |
using Gemini.Modules.Inspector; | |
namespace SomeRedactedAppName.Modules.TraceList | |
{ | |
[Export(typeof(ITraceList))] | |
[PartCreationPolicy(CreationPolicy.Shared)] | |
public sealed class TraceListViewModel | |
: Tool | |
, ITraceList | |
, IHandle<TracedItemEventArgs> | |
{ | |
public override PaneLocation PreferredLocation => PaneLocation.Bottom; | |
#region Imports | |
private readonly IEventAggregator mEventAggregator; | |
private readonly IInspectorTool mInspectorTool; | |
private readonly SomeRedactedAppNameUserSettings mSomeRedactedAppNameUserSettings; | |
[ImportingConstructor] | |
public TraceListViewModel( | |
IEventAggregator eventAggregator, | |
IInspectorTool inspectorTool, | |
SomeRedactedAppNameUserSettings userSettings) | |
{ | |
mEventAggregator = eventAggregator; | |
mInspectorTool = inspectorTool; | |
mSomeRedactedAppNameUserSettings = userSettings; | |
PostConstruction(); | |
} | |
#endregion | |
private int mItemNumber; | |
BindableCollection<TraceListItem> mItems; | |
public IObservableCollection<TraceListItem> Items => mItems; | |
public ICollectionView ItemsView { get; private set; } | |
#region PauseTracing | |
bool mPauseTracing; | |
public bool PauseTracing | |
{ | |
get { return mPauseTracing; } | |
set { this.SetFieldVal(ref mPauseTracing, value); } | |
} | |
#endregion | |
#region TotalNumberOfTraces | |
int mTotalNumberOfTraces; | |
public int TotalNumberOfTraces | |
{ | |
get { return mTotalNumberOfTraces; } | |
set { this.SetFieldVal(ref mTotalNumberOfTraces, value); } | |
} | |
#endregion | |
#region ShowCritical | |
bool mShowCritical = true; | |
public bool ShowCritical | |
{ | |
get { return mShowCritical; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowCritical, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowError | |
bool mShowError = true; | |
public bool ShowError | |
{ | |
get { return mShowError; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowError, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowWarning | |
bool mShowWarning = true; | |
public bool ShowWarning | |
{ | |
get { return mShowWarning; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowWarning, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowInformation | |
bool mShowInformation = true; | |
public bool ShowInformation | |
{ | |
get { return mShowInformation; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowInformation, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowVerbose | |
bool mShowVerbose = Constants.IsDebugBuild; | |
public bool ShowVerbose | |
{ | |
get { return mShowVerbose; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowVerbose, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowStart | |
bool mShowStart = Constants.IsDebugBuild; | |
public bool ShowStart | |
{ | |
get { return mShowStart; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowStart, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowStop | |
bool mShowStop = Constants.IsDebugBuild; | |
public bool ShowStop | |
{ | |
get { return mShowStop; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowStop, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowSuspend | |
bool mShowSuspend = true; | |
public bool ShowSuspend | |
{ | |
get { return mShowSuspend; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowSuspend, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowResume | |
bool mShowResume = true; | |
public bool ShowResume | |
{ | |
get { return mShowResume; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowResume, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region ShowTransfer | |
bool mShowTransfer = true; | |
public bool ShowTransfer | |
{ | |
get { return mShowTransfer; } | |
set | |
{ | |
if (this.SetFieldVal(ref mShowTransfer, value)) | |
{ | |
OnShowFiltersChanged(); | |
} | |
} | |
} | |
#endregion | |
#region TailTraces | |
bool mTailTraces = true; | |
[Description("When enabled, UI will snap to new traces as they come in")] | |
public bool TailTraces | |
{ | |
get { return mTailTraces; } | |
set { this.SetFieldVal(ref mTailTraces, value); } | |
} | |
#endregion | |
private void PostConstruction() | |
{ | |
DisplayName = "Trace List"; | |
ToolBarDefinition = ToolBarDefinitions.TraceListToolBar; | |
mItems = new BindableCollection<TraceListItem>(); | |
ItemsView = System.Windows.Data.CollectionViewSource.GetDefaultView(Items); | |
} | |
protected override async Task OnActivateAsync( | |
CancellationToken cancellationToken) | |
{ | |
await base.OnActivateAsync(cancellationToken) | |
.ConfigureAwait(false); | |
mEventAggregator.SubscribeOnUIThread(this); | |
} | |
protected override async Task OnDeactivateAsync( | |
bool close, | |
CancellationToken cancellationToken) | |
{ | |
await base.OnDeactivateAsync(close, cancellationToken) | |
.ConfigureAwait(false); | |
mEventAggregator.Unsubscribe(this); | |
} | |
public void OnMainModuleClosing() | |
{ | |
PauseTracing = true; | |
IsNotifying = false; // we still attempt to track TotalNumberOfTraces even when paused | |
} | |
private void OnShowFiltersChanged() | |
=> ItemsView.Refresh(); | |
Task IHandle<TracedItemEventArgs>.HandleAsync( | |
TracedItemEventArgs message, | |
CancellationToken cancellationToken) | |
{ | |
AddItem(message.Type, message.TimeStamp, message.SourceName, message.Message, message.Data, message.OnClickAction); | |
return Task.CompletedTask; | |
} | |
public void AddItem( | |
TraceListItemType type, | |
long timeStamp, | |
string sourceName, | |
string message, | |
object[] data = null, | |
System.Action onClick = null) | |
{ | |
if (PauseTracing) | |
{ | |
// #NOTE I think I still want to track the total number of would-be traces | |
++mItemNumber; | |
TotalNumberOfTraces = mItemNumber; | |
return; | |
} | |
SomeRedactedAppNameUserSettings settings = mSomeRedactedAppNameUserSettings; | |
TraceSourceSettings traceSettings = settings.TraceSourceOptions; | |
if (traceSettings != null) | |
{ | |
if (traceSettings.MaxTraceListItems.IsNotNone()) | |
{ | |
int surplus_count = Items.Count; | |
surplus_count += 1; // we're adding one | |
surplus_count -= traceSettings.MaxTraceListItems; | |
while (surplus_count-- > 0) | |
{ | |
Items.RemoveAt(0); | |
} | |
} | |
} | |
var item = new TraceListItem | |
{ | |
ItemType = type, | |
Number = ++mItemNumber, | |
TimeStamp = timeStamp, | |
SourceName = sourceName, | |
Message = message, | |
Data = data, | |
OnClick = onClick, | |
}; | |
Items.Add(item); | |
TotalNumberOfTraces = mItemNumber; | |
} | |
public void ClearAll() => Items.Clear(); | |
public void OnSelectedItemChanged( | |
TraceListItem selectedItem) | |
{ | |
if (mInspectorTool == null) | |
return; | |
if (selectedItem == null) | |
{ | |
mInspectorTool.SelectedObject = null; | |
return; | |
} | |
var item_inspector = new InspectableObjectBuilder() | |
.WithObjectProperties(selectedItem, TraceListItemPropertyFilter); | |
if (selectedItem.HasData) | |
{ | |
_ = item_inspector | |
#pragma warning disable CA2000 // Dispose objects before losing scope | |
.WithEditor(selectedItem, x => x.Data, new Inspectors.TraceDataEditorViewModel()); | |
#pragma warning restore CA2000 // Dispose objects before losing scope | |
} | |
mInspectorTool.SelectedObject = item_inspector.ToInspectableObject(); | |
} | |
private static bool TraceListItemPropertyFilter( | |
PropertyDescriptor pd) | |
{ | |
switch (pd.Name) | |
{ | |
case nameof(TraceListItem.SourceName): | |
case nameof(TraceListItem.Message): | |
return true; | |
default: | |
return false; | |
} | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment