Skip to content

Commit 696657a

Browse files
author
LoneWandererProductions
committed
Remove obsolete ObservableObject
1 parent 629bb63 commit 696657a

5 files changed

Lines changed: 123 additions & 106 deletions

File tree

CommonControls/DataItem.cs

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
namespace CommonControls
1616
{
17-
/// <inheritdoc cref="ObservableObject" />
17+
/// <inheritdoc cref="ViewModelBase" />
1818
/// <summary>
1919
/// Data Object
2020
/// </summary>
21-
public sealed class DataItem : ObservableObject, IEquatable<DataItem>
21+
public sealed class DataItem : ViewModelBase, IEquatable<DataItem>
2222
{
2323
/// <summary>
2424
/// The id.
@@ -28,24 +28,15 @@ public sealed class DataItem : ObservableObject, IEquatable<DataItem>
2828
/// <summary>
2929
/// The name.
3030
/// </summary>
31-
private string _name;
31+
private string _name = string.Empty;
3232

3333
/// <summary>
3434
/// Gets or sets the id.
3535
/// </summary>
3636
public int Id
3737
{
3838
get => _id;
39-
set
40-
{
41-
if (_id == value)
42-
{
43-
return;
44-
}
45-
46-
_id = value;
47-
RaisePropertyChangedEvent(nameof(Id));
48-
}
39+
set => SetProperty(ref _id, value);
4940
}
5041

5142
/// <summary>
@@ -54,16 +45,7 @@ public int Id
5445
public string Name
5546
{
5647
get => _name;
57-
set
58-
{
59-
if (_name == value)
60-
{
61-
return;
62-
}
63-
64-
_name = value;
65-
RaisePropertyChangedEvent(nameof(Name));
66-
}
48+
set => SetProperty(ref _name, value);
6749
}
6850

6951
/// <inheritdoc />
@@ -75,17 +57,10 @@ public string Name
7557
/// <see langword="true" /> if the current object is equal to the <paramref name="other" /> parameter; otherwise,
7658
/// <see langword="false" />.
7759
/// </returns>
78-
public bool Equals(DataItem other)
60+
public bool Equals(DataItem? other)
7961
{
80-
if (ReferenceEquals(null, other))
81-
{
82-
return false;
83-
}
84-
85-
if (ReferenceEquals(this, other))
86-
{
87-
return true;
88-
}
62+
if (other is null) return false;
63+
if (ReferenceEquals(this, other)) return true;
8964

9065
return _id == other._id && _name == other._name;
9166
}
@@ -98,7 +73,7 @@ public bool Equals(DataItem other)
9873
/// <returns>
9974
/// <c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.
10075
/// </returns>
101-
public override bool Equals(object obj)
76+
public override bool Equals(object? obj)
10277
{
10378
return ReferenceEquals(this, obj) || (obj is DataItem other && Equals(other));
10479
}
@@ -112,7 +87,9 @@ public override bool Equals(object obj)
11287
/// </returns>
11388
public override int GetHashCode()
11489
{
115-
return HashCode.Combine(_id);
90+
// Note: If Equals uses Name, HashCode should ideally include it too,
91+
// unless Id is guaranteed unique across all instances.
92+
return HashCode.Combine(_id, _name);
11693
}
11794

11895
/// <inheritdoc />

Debugger/Config.cs

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ namespace Debugger
2020
/// The config class.
2121
/// Only used for Data that is permanent and saved
2222
/// </summary>
23-
public class Config : ObservableObject
23+
public class Config : ViewModelBase
2424
{
25+
private long _maxFileSize = 5 * 1024 * 1024; // Default: 5 MB
26+
private int _maxFileCount = 10; // Default: 10
27+
2528
/// <summary>
2629
/// Gets or sets the debug path.
2730
/// </summary>
@@ -30,8 +33,9 @@ public string DebugPath
3033
get => DebugRegister.DebugPath;
3134
set
3235
{
36+
if (DebugRegister.DebugPath == value) return;
3337
DebugRegister.DebugPath = value;
34-
RaisePropertyChangedEvent(nameof(DebugPath));
38+
OnPropertyChanged();
3539
}
3640
}
3741

@@ -43,8 +47,9 @@ public int SecondsTick
4347
get => DebugRegister.SecondsTick;
4448
set
4549
{
50+
if (DebugRegister.SecondsTick == value) return;
4651
DebugRegister.SecondsTick = value;
47-
RaisePropertyChangedEvent(nameof(SecondsTick));
52+
OnPropertyChanged();
4853
}
4954
}
5055

@@ -56,8 +61,9 @@ public int MinutesTick
5661
get => DebugRegister.MinutesTick;
5762
set
5863
{
64+
if (DebugRegister.MinutesTick == value) return;
5965
DebugRegister.MinutesTick = value;
60-
RaisePropertyChangedEvent(nameof(MinutesTick));
66+
OnPropertyChanged();
6167
}
6268
}
6369

@@ -69,8 +75,9 @@ public int HourTick
6975
get => DebugRegister.HourTick;
7076
set
7177
{
78+
if (DebugRegister.HourTick == value) return;
7279
DebugRegister.HourTick = value;
73-
RaisePropertyChangedEvent(nameof(HourTick));
80+
OnPropertyChanged();
7481
}
7582
}
7683

@@ -82,26 +89,43 @@ public bool IsDumpActive
8289
get => DebugRegister.IsDumpActive;
8390
set
8491
{
92+
if (DebugRegister.IsDumpActive == value) return;
8593
DebugRegister.IsDumpActive = value;
86-
RaisePropertyChangedEvent(nameof(IsDumpActive));
94+
OnPropertyChanged();
8795
}
8896
}
8997

9098
/// <summary>
9199
/// Gets or sets a value indicating whether this instance is verbose.
92100
/// </summary>
93-
/// <value>
94-
/// <c>true</c> if this instance is verbose; otherwise, <c>false</c>.
95-
/// </value>
96101
public bool IsVerbose
97102
{
98103
get => DebugRegister.IsVerbose;
99104
set
100105
{
106+
if (DebugRegister.IsVerbose == value) return;
101107
DebugRegister.IsVerbose = value;
102-
RaisePropertyChangedEvent(nameof(IsVerbose));
108+
OnPropertyChanged();
103109
}
104110
}
111+
112+
/// <summary>
113+
/// Maximum size for each log file in bytes.
114+
/// </summary>
115+
public long MaxFileSize
116+
{
117+
get => _maxFileSize;
118+
set => SetProperty(ref _maxFileSize, value);
119+
}
120+
121+
/// <summary>
122+
/// Maximum number of log files to retain.
123+
/// </summary>
124+
public int MaxFileCount
125+
{
126+
get => _maxFileCount;
127+
set => SetProperty(ref _maxFileCount, value);
128+
}
105129
}
106130

107131
/// <inheritdoc />
@@ -119,8 +143,9 @@ public bool SuppressWindow
119143
get => DebugRegister.SuppressWindow;
120144
set
121145
{
146+
if (DebugRegister.SuppressWindow == value) return;
122147
DebugRegister.SuppressWindow = value;
123-
RaisePropertyChangedEvent(nameof(SuppressWindow));
148+
OnPropertyChanged();
124149
}
125150
}
126151

@@ -130,10 +155,11 @@ public bool SuppressWindow
130155
public bool IsRunning
131156
{
132157
get => DebugRegister.IsRunning;
133-
init
158+
set
134159
{
160+
if (DebugRegister.IsRunning == value) return;
135161
DebugRegister.IsRunning = value;
136-
RaisePropertyChangedEvent(nameof(IsRunning));
162+
OnPropertyChanged();
137163
}
138164
}
139165

@@ -145,8 +171,9 @@ public string ErrorColor
145171
get => DebugRegister.ErrorColor;
146172
set
147173
{
174+
if (DebugRegister.ErrorColor == value) return;
148175
DebugRegister.ErrorColor = value;
149-
RaisePropertyChangedEvent(nameof(ErrorColor));
176+
OnPropertyChanged();
150177
}
151178
}
152179

@@ -158,8 +185,9 @@ public string WarningColor
158185
get => DebugRegister.WarningColor;
159186
set
160187
{
188+
if (DebugRegister.WarningColor == value) return;
161189
DebugRegister.WarningColor = value;
162-
RaisePropertyChangedEvent(nameof(WarningColor));
190+
OnPropertyChanged();
163191
}
164192
}
165193

@@ -171,8 +199,9 @@ public string InformationColor
171199
get => DebugRegister.InformationColor;
172200
set
173201
{
202+
if (DebugRegister.InformationColor == value) return;
174203
DebugRegister.InformationColor = value;
175-
RaisePropertyChangedEvent(nameof(InformationColor));
204+
OnPropertyChanged();
176205
}
177206
}
178207

@@ -184,8 +213,9 @@ public string ExternalColor
184213
get => DebugRegister.ExternalColor;
185214
set
186215
{
216+
if (DebugRegister.ExternalColor == value) return;
187217
DebugRegister.ExternalColor = value;
188-
RaisePropertyChangedEvent(nameof(ExternalColor));
218+
OnPropertyChanged();
189219
}
190220
}
191221

@@ -197,35 +227,24 @@ public string StandardColor
197227
get => DebugRegister.StandardColor;
198228
set
199229
{
230+
if (DebugRegister.StandardColor == value) return;
200231
DebugRegister.StandardColor = value;
201-
RaisePropertyChangedEvent(nameof(StandardColor));
232+
OnPropertyChanged();
202233
}
203234
}
204235

205236
/// <summary>
206237
/// Gets or sets the color options.
207238
/// </summary>
208-
/// <value>
209-
/// The color options.
210-
/// </value>
211239
public List<ColorOption> ColorOptions
212240
{
213241
get => DebugRegister.ColorOptions;
214242
set
215243
{
244+
if (DebugRegister.ColorOptions == value) return;
216245
DebugRegister.ColorOptions = value;
217-
RaisePropertyChangedEvent(nameof(ColorOptions));
246+
OnPropertyChanged();
218247
}
219248
}
220-
221-
/// <summary>
222-
/// Maximum size for each log file in bytes.
223-
/// </summary>
224-
public long MaxFileSize { get; set; } = 5 * 1024 * 1024; // Default: 5 MB
225-
226-
/// <summary>
227-
/// Maximum number of log files to retain.
228-
/// </summary>
229-
public int MaxFileCount { get; set; } = 10; // Default: 10
230249
}
231250
}

ViewModel/AsyncDelegateCommand.cs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ public sealed class AsyncDelegateCommand<T> : ICommand
3333
/// </summary>
3434
private readonly Func<T, Task> _execute;
3535

36+
/// <summary>
37+
/// The on exception
38+
/// </summary>
39+
private readonly Action<Exception>? _onException;
40+
41+
/// <summary>
42+
/// The is executing
43+
/// </summary>
44+
private bool _isExecuting;
45+
3646
/// <summary>
3747
/// Initializes a new instance of the <see cref="AsyncDelegateCommand{T}" /> class.
3848
/// </summary>
@@ -55,7 +65,30 @@ public AsyncDelegateCommand(Func<T, Task> execute, Predicate<T>? canExecute = nu
5565
/// <param name="parameter">The parameter for the action.</param>
5666
public async void Execute(object? parameter)
5767
{
58-
await _execute((T)parameter);
68+
// 1. Safe Casting: Ensure parameter is actually T
69+
if (!IsValidParameter(parameter, out T validParam))
70+
return;
71+
72+
// 2. Concurrency Lock
73+
if (_isExecuting) return;
74+
75+
_isExecuting = true;
76+
RaiseCanExecuteChanged(); // Refreshes button state (disables it)
77+
78+
try
79+
{
80+
// 3. Exception Handling wrapper
81+
await _execute(validParam);
82+
}
83+
catch (Exception ex)
84+
{
85+
_onException?.Invoke(ex);
86+
}
87+
finally
88+
{
89+
_isExecuting = false;
90+
RaiseCanExecuteChanged(); // Re-enables button
91+
}
5992
}
6093

6194
/// <summary>
@@ -84,5 +117,31 @@ public event EventHandler CanExecuteChanged
84117
add => CommandManager.RequerySuggested += value;
85118
remove => CommandManager.RequerySuggested -= value;
86119
}
120+
121+
/// <summary>
122+
/// Safely casts the object to type T.
123+
/// </summary>
124+
/// <param name="parameter">The parameter.</param>
125+
/// <param name="result">The result.</param>
126+
/// <returns>
127+
/// <c>true</c> if [is valid parameter] [the specified parameter]; otherwise, <c>false</c>.
128+
/// </returns>
129+
private bool IsValidParameter(object? parameter, out T result)
130+
{
131+
result = default!;
132+
133+
// Case 1: T is a reference type or Nullable<T>, and parameter is null
134+
if (parameter is null && (default(T) == null))
135+
return true;
136+
137+
// Case 2: parameter is actually T
138+
if (parameter is T typedParam)
139+
{
140+
result = typedParam;
141+
return true;
142+
}
143+
144+
return false;
145+
}
87146
}
88147
}

0 commit comments

Comments
 (0)