Skip to content

Commit 3111d99

Browse files
authored
Merge pull request #64 from visualHFT/profiled-improvments
Profiled improvments
2 parents 9375d81 + 3cf5e97 commit 3111d99

9 files changed

Lines changed: 392 additions & 211 deletions

File tree

ViewModel/vmTile.cs

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ public vmTile(IStudy study)
5656
Title = _study.TileTitle;
5757
Tooltip = _study.TileToolTip;
5858

59-
_localModel.ValueFormatted = ".";
6059
_localModel.Tooltip = "Waiting for data...";
6160

6261
_study.OnCalculated += _study_OnCalculated;
@@ -94,7 +93,6 @@ public vmTile(IMultiStudy multiStudy)
9493
Title = _multiStudy.TileTitle;
9594
Tooltip = _multiStudy.TileToolTip;
9695

97-
_localModel.ValueFormatted = ".";
9896
_localModel.Tooltip = "Waiting for data...";
9997

10098
OpenSettingsCommand = new RelayCommand<vmTile>(OpenSettings);
@@ -159,9 +157,10 @@ private void _study_OnCalculated(object? sender, BaseStudyModel e)
159157
_localModel.copyFrom(e);
160158
}
161159

162-
if (_localModel.ValueFormatted == ".")
160+
161+
if (!_localModel.HasData && !_localModel.HasError && !_localModel.IsStale)
163162
_localModel.Tooltip = "Waiting for data...";
164-
else if (!string.IsNullOrEmpty(_localModel.Tooltip))
163+
else if (!string.IsNullOrEmpty(e.Tooltip))
165164
_localModel.Tooltip = e.Tooltip;
166165
else
167166
_localModel.Tooltip = null;
@@ -172,16 +171,16 @@ private void _study_OnCalculated(object? sender, BaseStudyModel e)
172171

173172
~vmTile() { Dispose(false); }
174173

174+
// In uiUpdaterAction - format on demand:
175175
private void uiUpdaterAction()
176176
{
177177
if (_localModel == null || !_DATA_AVAILABLE)
178178
return;
179179
lock (_lock)
180180
{
181-
Value = _localModel.ValueFormatted;
181+
Value = GetDisplayValue(_localModel);
182182
ValueTooltip = _localModel.Tooltip;
183183

184-
//update color if set or has changed
185184
if (_localModel.ValueColor != null)
186185
{
187186
if (_valueColor == null || _valueColor.ToString() != _localModel.ValueColor)
@@ -191,6 +190,33 @@ private void uiUpdaterAction()
191190
_DATA_AVAILABLE = true;
192191
}
193192
}
193+
/// <summary>
194+
/// Gets the display value based on model state.
195+
/// Formatting happens here (UI layer) only when needed.
196+
/// </summary>
197+
private static string GetDisplayValue(BaseStudyModel model)
198+
{
199+
// Priority: Error > Stale > No Data > Normal
200+
if (model.HasError)
201+
return "Err";
202+
203+
if (model.IsStale)
204+
return "...";
205+
206+
if (!model.HasData)
207+
return ".";
208+
209+
// Normal case: format the value
210+
if (model.CustomFormatter != null)
211+
return model.CustomFormatter(model.Value);
212+
213+
if (string.IsNullOrEmpty(model.Format))
214+
return model.Value.ToString();
215+
216+
return model.Value.ToString(model.Format);
217+
}
218+
219+
194220
public void UpdateAllUI()
195221
{
196222
_DATA_AVAILABLE = true;
@@ -341,7 +367,31 @@ protected virtual void Dispose(bool disposing)
341367
}
342368
}
343369
ChildTiles.Clear();
370+
ChildTiles = null;
344371
}
372+
373+
// Dispose the multi-study itself
374+
foreach (var study in _multiStudy.Studies)
375+
{
376+
try
377+
{
378+
study.StopAsync();
379+
study.Dispose();
380+
}
381+
catch (Exception ex)
382+
{
383+
System.Diagnostics.Debug.WriteLine($"Error disposing study: {ex.Message}");
384+
}
385+
}
386+
_multiStudy.Dispose();
387+
_multiStudy = null;
388+
}
389+
390+
// Dispose plugin
391+
if (_plugin != null)
392+
{
393+
// Note: Plugin disposal handled by PluginManager
394+
_plugin = null;
345395
}
346396

347397
// Dispose UI updater

VisualHFT.Commons/Model/BaseStudyModel.cs

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ public partial class BaseStudyModel
66
{
77
private DateTime _timestamp;
88
private decimal _value;
9-
private string _valueFormatted;
109
private string _format;
1110
private string _valueColor = null;
1211
private decimal _marketMidPrice;
12+
private bool _hasData = false;
13+
14+
/// <summary>
15+
/// Optional custom formatter. When set, UI uses this instead of Format string.
16+
/// </summary>
17+
public Func<decimal, string> CustomFormatter { get; set; }
1318

1419
public BaseStudyModel()
1520
{
@@ -20,57 +25,91 @@ public DateTime Timestamp
2025
get => _timestamp;
2126
set => _timestamp = value;
2227
}
28+
2329
public decimal Value
2430
{
2531
get => _value;
26-
set => _value = value;
32+
set
33+
{
34+
_value = value;
35+
_hasData = true;
36+
}
2737
}
2838

39+
/// <summary>
40+
/// Standard .NET format string (e.g., "n1", "F2").
41+
/// Ignored if CustomFormatter is set.
42+
/// </summary>
2943
public string Format
3044
{
3145
get => _format;
3246
set => _format = value;
3347
}
34-
public string ValueFormatted
35-
{
36-
get => _valueFormatted;
37-
set => _valueFormatted = value;
38-
}
48+
49+
/// <summary>
50+
/// Indicates whether real data has been received.
51+
/// False = waiting for data (".")
52+
/// True = has valid data or had data but now stale ("...")
53+
/// </summary>
54+
public bool HasData => _hasData;
55+
56+
/// <summary>
57+
/// Indicates an error state ("Err").
58+
/// When true, UI should display error indicator.
59+
/// </summary>
60+
public bool HasError { get; set; }
61+
62+
/// <summary>
63+
/// Indicates stale data state ("...").
64+
/// When true, data was received but is now stale.
65+
/// </summary>
66+
public bool IsStale { get; set; }
67+
3968
public string ValueColor
4069
{
4170
get => _valueColor;
4271
set => _valueColor = value;
4372
}
73+
4474
public decimal MarketMidPrice
4575
{
4676
get => _marketMidPrice;
4777
set => _marketMidPrice = value;
4878
}
79+
4980
public string Tooltip { get; set; }
5081
public string Tag { get; set; }
5182
public bool AddItemSkippingAggregation { get; set; }
5283

5384
public void copyFrom(BaseStudyModel e)
5485
{
55-
_timestamp = e.Timestamp;
56-
_value = e.Value;
57-
_format = e.Format;
58-
_valueFormatted = e.ValueFormatted;
59-
_valueColor = e.ValueColor;
60-
_marketMidPrice = e.MarketMidPrice;
86+
_timestamp = e._timestamp;
87+
_value = e._value;
88+
_format = e._format;
89+
_hasData = e._hasData;
90+
CustomFormatter = e.CustomFormatter;
91+
_valueColor = e._valueColor;
92+
_marketMidPrice = e._marketMidPrice;
93+
HasError = e.HasError;
94+
IsStale = e.IsStale;
6195
Tooltip = e.Tooltip;
96+
Tag = e.Tag;
6297
AddItemSkippingAggregation = false;
6398
}
6499

65100
public void Reset()
66101
{
67102
_timestamp = DateTime.MinValue;
68103
_value = 0;
69-
_format = "";
70-
_valueFormatted = "";
71-
_valueColor = "";
104+
_format = null;
105+
_hasData = false;
106+
CustomFormatter = null;
107+
_valueColor = null;
72108
_marketMidPrice = 0;
73-
Tooltip = "";
109+
HasError = false;
110+
IsStale = false;
111+
Tooltip = null;
112+
Tag = null;
74113
AddItemSkippingAggregation = false;
75114
}
76115
}

0 commit comments

Comments
 (0)