2026-01-26 14:51:28 +09:00

381 lines
11 KiB
C#

using Aurora;
using Aurora.Util.HislogPlus;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
namespace ILSOS_KS.Views.PopUP
{
public interface IPopupService : IDisposable
{
void Generation();
void Show();
void Hide();
void UpdateImages1(Mat LeftTop, OpenCvSharp.Rect roi);
void UpdateImages2(Mat RightTop, OpenCvSharp.Rect roi);
void UpdateImages3(Mat LeftBottom, OpenCvSharp.Rect roi);
void UpdateImages4(Mat RightBottom, OpenCvSharp.Rect roi);
void SetParameters1(List<double> step);
void SetParameters2(List<double> step);
void SetParameters3(List<double> step);
void SetParameters4(List<double> step);
void SetStepLBAD(string str);
void SetStepWELDING(string str);
}
public class PopupService : IPopupService
{
private static PopupService _instance;
private static readonly object _lock = new object();
public static PopupService Instance
{
get
{
if (_instance == null)
throw new InvalidOperationException("PopupService.Init() 먼저 호출하세요.");
return _instance;
}
}
public static void Init()
{
if (_instance != null) return;
lock (_lock)
{
if (_instance == null)
{
_instance = new PopupService();
}
}
}
private PopupWindowViewModel _currentViewModel;
private PopupUpWindows _currentWindow;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private PopupService()
{
// UI 스레드에서 종료 이벤트 등록
if (Application.Current != null)
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
Application.Current.Exit += (s, e) => Dispose();
}));
}
}
#region Window 생성/제어
public void Generation()
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
if (_currentWindow == null || !_currentWindow.IsLoaded)
{
_currentViewModel = new PopupWindowViewModel();
_currentWindow = new PopupUpWindows(_currentViewModel);
_currentWindow.Closing += _currentWindow_Closing;
}
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.Generation 예외] {ex}");
}
}
private void _currentWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
_currentWindow.Hide();
}
public void Show()
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
if (_currentWindow == null || !_currentWindow.IsLoaded)
Generation();
if (_currentWindow != null)
{
if (_currentWindow.WindowState == WindowState.Minimized)
_currentWindow.WindowState = WindowState.Normal;
_currentWindow.Topmost = true;
_currentWindow.Show();
_currentWindow.Activate();
_currentWindow.Topmost = false;
}
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.Show 예외] {ex}");
}
}
public void Hide()
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentWindow?.Hide();
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.Hide 예외] {ex}");
}
}
#endregion
public void UpdateImages1(Mat LeftTop, OpenCvSharp.Rect roi)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentViewModel.SetImages1(LeftTop, roi);
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.UpdateImages1 예외] {ex}");
}
}, _cts.Token);
}
public void UpdateImages2(Mat RightTop, OpenCvSharp.Rect roi)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentViewModel.SetImages2(RightTop, roi);
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.UpdateImages2 예외] {ex}");
}
}, _cts.Token);
}
public void UpdateImages3(Mat LeftBottom, OpenCvSharp.Rect roi)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentViewModel.SetImages3(LeftBottom, roi);
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.UpdateImages2 예외] {ex}");
}
}, _cts.Token);
}
public void UpdateImages4(Mat RightBottom, OpenCvSharp.Rect roi)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
_currentViewModel.SetImages4(RightBottom, roi);
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.UpdateImages2 예외] {ex}");
}
}, _cts.Token);
}
public void SetParameters1(List<double> step)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.SetParameters1(step)
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetParameters1 예외] {ex}");
}
}, _cts.Token);
}
public void SetParameters2(List<double> step)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.SetParameters2(step)
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetParameters2 예외] {ex}");
}
}, _cts.Token);
}
public void SetParameters3(List<double> step)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.SetParameters3(step)
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetParameters3 예외] {ex}");
}
}, _cts.Token);
}
public void SetParameters4(List<double> step)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.SetParameters4(step)
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetParameters4 예외] {ex}");
}
}, _cts.Token);
}
public void SetStepLBAD(string str)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.StepLBAD = str
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetStepLBAD 예외] {ex}");
}
}, _cts.Token);
}
public void SetStepWELDING(string str)
{
if (_currentViewModel == null || _cts.IsCancellationRequested) return;
Task.Run(() =>
{
try
{
Application.Current.Dispatcher.Invoke(() =>
_currentViewModel.StepWELDING = str
);
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.SetStepWELDING 예외] {ex}");
}
}, _cts.Token);
}
#region Dispose
public void Dispose()
{
try
{
// 1. Task 취소
_cts.Cancel();
_cts.Dispose();
Application.Current.Dispatcher.Invoke(() =>
{
// 2. Window 종료
if (_currentWindow != null)
{
_currentWindow.Closing -= _currentWindow_Closing;
_currentWindow.Close();
_currentWindow = null;
}
// 3. ViewModel 제거 및 Mat Dispose
_currentViewModel?.DisposeImages();
_currentViewModel = null;
// 4. GC 강제
GC.Collect();
GC.WaitForPendingFinalizers();
AsyncLog.I("PopupService 종료 및 메모리 해제 완료");
});
}
catch (Exception ex)
{
AsyncLog.E($"[PopupService.Dispose 예외] {ex}");
}
}
#endregion
}
}