fix initialization, throttle operations

day/winter/night switcher fixes
This commit is contained in:
Alex Bezdieniezhnykh
2025-02-19 23:07:16 +02:00
parent c314268d1e
commit d1af7958f8
17 changed files with 170 additions and 88 deletions
+4 -3
View File
@@ -51,7 +51,8 @@
CanUserResizeRows="False"
CanUserResizeColumns="False"
SelectionChanged="DetectionDataGrid_SelectionChanged"
x:FieldModifier="public">
x:FieldModifier="public"
>
<DataGrid.Columns>
<DataGridTemplateColumn Width="50" Header="Клавіша" CanUserSort="False">
<DataGridTemplateColumn.HeaderStyle>
@@ -90,13 +91,13 @@
IsChecked="True"
Style="{StaticResource ButtonRadioButtonStyle}"/>
<RadioButton x:Name="EveningModeRadioButton"
Tag="1"
Tag="20"
Content="Зима"
GroupName="Mode"
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
Style="{StaticResource ButtonRadioButtonStyle}"/>
<RadioButton x:Name="NightModeRadioButton"
Tag="2"
Tag="40"
Content="Ніч"
GroupName="Mode"
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
@@ -4,16 +4,26 @@ using Azaion.Common.DTO;
namespace Azaion.Common.Controls;
public class DetectionClassChangedEventArgs(DetectionClass? detectionClass, int classNumber) : EventArgs
public class DetectionClassChangedEventArgs(DetectionClass detectionClass, int classNumber) : EventArgs
{
public DetectionClass? DetectionClass { get; } = detectionClass;
public DetectionClass DetectionClass { get; } = detectionClass;
public int ClassNumber { get; } = classNumber;
}
public partial class DetectionClasses
{
public event EventHandler<DetectionClassChangedEventArgs>? DetectionClassChanged;
public DetectionClasses() => InitializeComponent();
public DetectionClasses()
{
InitializeComponent();
}
public void Init(List<DetectionClass> detectionClasses)
{
DetectionDataGrid.ItemsSource = detectionClasses;
DetectionDataGrid.SelectedIndex = 0;
}
public int CurrentClassNumber { get; private set; } = 0;
public DetectionClass? CurrentDetectionClass { get; set; }
@@ -27,26 +37,25 @@ public partial class DetectionClasses
private void RaiseDetectionClassChanged()
{
var detClass = (DetectionClass)DetectionDataGrid.SelectedItem;
var baseClassNumber = detClass?.Id ?? 0;
if (detClass == null)
return;
var modeAmplifier = 0;
foreach (var child in ModeSwitcherPanel.Children)
if (child is RadioButton { IsChecked: true } rb)
if (int.TryParse(rb.Tag?.ToString(), out int modeIndex))
{
if (detClass != null)
detClass.PhotoMode = (PhotoMode)modeIndex;
modeAmplifier += modeIndex * 20;
detClass.PhotoMode = (PhotoMode)modeIndex;
modeAmplifier += modeIndex;
}
CurrentDetectionClass = detClass;
CurrentClassNumber = baseClassNumber + modeAmplifier;
CurrentClassNumber = detClass.Id + modeAmplifier;
DetectionClassChanged?.Invoke(this, new DetectionClassChangedEventArgs(detClass, CurrentClassNumber));
}
public void SelectNum(int keyNumber)
{
DetectionDataGrid.SelectedIndex = keyNumber;
+2 -2
View File
@@ -50,7 +50,7 @@ public class DetectionControl : Border
_resizeStart = resizeStart;
_classNameLabel = new TextBlock
{
Text = detectionClass.Name,
Text = detectionClass.UIName,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(0, 15, 0, 0),
@@ -120,7 +120,7 @@ public class DetectionControl : Border
public YoloLabel GetLabel(Size canvasSize, Size? videoSize = null)
{
var label = new CanvasLabel(DetectionClass.Id, Canvas.GetLeft(this), Canvas.GetTop(this), Width, Height);
var label = new CanvasLabel(DetectionClass.YoloId, Canvas.GetLeft(this), Canvas.GetTop(this), Width, Height);
return new YoloLabel(label, canvasSize, videoSize);
}
}
+2 -2
View File
@@ -41,8 +41,8 @@ public class AnnotationResult
var detectionClasses = detections.Select(x => x.ClassNumber).Distinct().ToList();
ClassName = detectionClasses.Count > 1
? string.Join(", ", detectionClasses.Select(x => allDetectionClasses[x].ShortName))
: allDetectionClasses[detectionClasses.FirstOrDefault()].Name;
? string.Join(", ", detectionClasses.Select(x => allDetectionClasses[x].UIName))
: allDetectionClasses[detectionClasses.FirstOrDefault()].UIName;
ClassColor0 = GetAnnotationClass(detectionClasses, 0);
ClassColor1 = GetAnnotationClass(detectionClasses, 1);
+22 -2
View File
@@ -4,12 +4,32 @@ namespace Azaion.Common.DTO.Config;
public class AnnotationConfig
{
public List<DetectionClass> AnnotationClasses { get; set; } = null!;
public List<DetectionClass> DetectionClasses { get; set; } = null!;
[JsonIgnore]
private Dictionary<int, DetectionClass>? _detectionClassesDict;
[JsonIgnore]
public Dictionary<int, DetectionClass> DetectionClassesDict => _detectionClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
public Dictionary<int, DetectionClass> DetectionClassesDict
{
get
{
if (_detectionClassesDict != null)
return _detectionClassesDict;
var photoModes = Enum.GetValues(typeof(PhotoMode)).Cast<PhotoMode>().ToList();
_detectionClassesDict = DetectionClasses.SelectMany(cls => photoModes.Select(mode => new DetectionClass
{
Id = cls.Id,
Name = cls.Name,
ShortName = cls.ShortName,
PhotoMode = mode
}))
.ToDictionary(x => x.YoloId, x => x);
return _detectionClassesDict;
}
}
public List<string> VideoFormats { get; set; } = null!;
public List<string> ImageFormats { get; set; } = null!;
+1 -1
View File
@@ -41,7 +41,7 @@ public class ConfigUpdater : IConfigUpdater
{
AnnotationConfig = new AnnotationConfig
{
AnnotationClasses = Constants.DefaultAnnotationClasses,
DetectionClasses = Constants.DefaultAnnotationClasses,
VideoFormats = Constants.DefaultVideoFormats,
ImageFormats = Constants.DefaultImageFormats,
+20
View File
@@ -11,6 +11,23 @@ public class DetectionClass
public string Name { get; set; } = null!;
public string ShortName { get; set; } = null!;
public string UIName
{
get
{
var mode = PhotoMode switch
{
PhotoMode.Night => "(ніч)",
PhotoMode.Winter => "(зим)",
PhotoMode.Regular => "",
_ => ""
};
return ShortName + mode;
}
}
[JsonIgnore]
public PhotoMode PhotoMode { get; set; }
[JsonIgnore]
@@ -19,6 +36,9 @@ public class DetectionClass
[JsonIgnore] //For UI
public int ClassNumber => Id + 1;
[JsonIgnore]
public int YoloId => (int)PhotoMode + Id;
[JsonIgnore]
public SolidColorBrush ColorBrush => new(Color);
}
+35 -14
View File
@@ -1,34 +1,55 @@
namespace Azaion.Common.Extensions;
using System.Collections.Concurrent;
namespace Azaion.Common.Extensions;
public static class ThrottleExt
{
private static bool _throttleRunFirstOn;
public static async Task ThrottleRunFirst(this Func<Task> func, TimeSpan? throttleTime = null, CancellationToken cancellationToken = default)
private static ConcurrentDictionary<Guid, bool> _taskStates = new();
public static async Task ThrottleRunFirst(Func<Task> func, Guid actionId, TimeSpan? throttleTime = null, CancellationToken cancellationToken = default)
{
if (_throttleRunFirstOn)
if (_taskStates.ContainsKey(actionId) && _taskStates[actionId])
return;
_throttleRunFirstOn = true;
await func();
_taskStates[actionId] = true;
try
{
await func();
}
catch (Exception e)
{
Console.WriteLine(e);
}
_ = Task.Run(async () =>
{
await Task.Delay(throttleTime ?? TimeSpan.FromMilliseconds(500), cancellationToken);
_throttleRunFirstOn = false;
_taskStates[actionId] = false;
}, cancellationToken);
}
private static bool _throttleRunAfter;
public static async Task ThrottleRunAfter(this Func<Task> func, TimeSpan? throttleTime = null, CancellationToken cancellationToken = default)
public static async Task ThrottleRunAfter(Func<Task> func, Guid actionId, TimeSpan? throttleTime = null, CancellationToken cancellationToken = default)
{
if (_throttleRunAfter)
if (_taskStates.ContainsKey(actionId) && _taskStates[actionId])
return;
_throttleRunAfter = true;
_taskStates[actionId] = true;
_ = Task.Run(async () =>
{
await Task.Delay(throttleTime ?? TimeSpan.FromMilliseconds(500), cancellationToken);
await func();
_throttleRunAfter = false;
try
{
await Task.Delay(throttleTime ?? TimeSpan.FromMilliseconds(500), cancellationToken);
await func();
}
catch (Exception ex)
{
_taskStates[actionId] = false;
}
finally
{
_taskStates[actionId] = false;
}
}, cancellationToken);
await Task.CompletedTask;
}
+3 -2
View File
@@ -30,6 +30,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
private readonly IAuthProvider _authProvider;
private readonly QueueConfig _queueConfig;
private Consumer _consumer = null!;
private static readonly Guid SaveTaskId = Guid.NewGuid();
public AnnotationService(
IResourceLoader resourceLoader,
@@ -95,7 +96,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
{
_dbFactory.SaveToDisk();
return Task.CompletedTask;
}, TimeSpan.FromSeconds(3), cancellationToken);
}, SaveTaskId, TimeSpan.FromSeconds(3), cancellationToken);
}
});
@@ -184,7 +185,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
{
_dbFactory.SaveToDisk();
return Task.CompletedTask;
}, TimeSpan.FromSeconds(5), token);
}, SaveTaskId, TimeSpan.FromSeconds(5), token);
return annotation;
}