draggableList/Tab 개발 중
This commit is contained in:
283
Assets/Scripts/UVC/Factory/Playback/UI/UIPlaybackController.cs
Normal file
283
Assets/Scripts/UVC/Factory/Playback/UI/UIPlaybackController.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using UVC.UI.Loading;
|
||||
|
||||
namespace UVC.Factory.Playback.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// UIPlaybackController는 UIPlayback(View)에서 발생하는 이벤트를 받아
|
||||
/// 실제 재생, 일시정지, 데이터 준비 등 비즈니스 로직을 처리하는 컨트롤러입니다.
|
||||
///
|
||||
/// <b>예시: UIPlayback과의 연결</b>
|
||||
/// <code>
|
||||
/// // UIPlayback에서 컨트롤러를 생성할 때 View를 넘겨줍니다.
|
||||
/// var controller = new UIPlaybackController(this);
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public class UIPlaybackController : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// View 역할을 하는 UIPlayback 참조입니다.
|
||||
/// </summary>
|
||||
private readonly UIPlayback view;
|
||||
|
||||
// 재생 중 여부
|
||||
private bool isPlaying = false;
|
||||
// 데이터 준비 중 여부
|
||||
private bool preparingData = false;
|
||||
// 재생에 필요한 정보
|
||||
private string date;
|
||||
private string time;
|
||||
private string fileName;
|
||||
// 타이머 동작 여부
|
||||
private bool isTick = false;
|
||||
|
||||
/// <summary>
|
||||
/// 타이머 동작 여부를 외부에서 제어할 수 있습니다.
|
||||
/// true로 설정하면 내부적으로 OnTimer()가 실행됩니다.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 타이머를 시작하려면
|
||||
/// controller.IsTick = true;
|
||||
/// // 타이머를 멈추려면
|
||||
/// controller.IsTick = false;
|
||||
/// </code>
|
||||
/// </example>
|
||||
public bool IsTick
|
||||
{
|
||||
get => isTick;
|
||||
set
|
||||
{
|
||||
if (isTick != value)
|
||||
{
|
||||
isTick = value;
|
||||
if (isTick) OnTimer().Forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 생성자에서 View와 이벤트를 연결합니다.
|
||||
/// </summary>
|
||||
/// <param name="view">UIPlayback 인스턴스</param>
|
||||
public UIPlaybackController(UIPlayback view)
|
||||
{
|
||||
this.view = view;
|
||||
SubscribeToViewEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// View에서 발생하는 이벤트를 컨트롤러의 메서드와 연결합니다.
|
||||
/// </summary>
|
||||
private void SubscribeToViewEvents()
|
||||
{
|
||||
view.OnClickExitButton += OnClickExit;
|
||||
view.OnClickPlayButton += OnClickPlay;
|
||||
view.OnChangeProgressValue += OnChangeProgress;
|
||||
view.OnChangeSpeedValue += OnChangeSpeed;
|
||||
view.OnChangeOpacityValue += OnValueChangedOpacity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 컨트롤러가 더 이상 필요 없을 때 이벤트 연결을 해제합니다.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (isPlaying) IsTick = false;
|
||||
view.OnClickExitButton -= OnClickExit;
|
||||
view.OnClickPlayButton -= OnClickPlay;
|
||||
view.OnChangeProgressValue -= OnChangeProgress;
|
||||
view.OnChangeSpeedValue -= OnChangeSpeed;
|
||||
view.OnChangeOpacityValue -= OnValueChangedOpacity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생에 필요한 데이터를 설정하고 UI를 초기화합니다.
|
||||
/// </summary>
|
||||
/// <param name="date">날짜(예: "2024-07-29")</param>
|
||||
/// <param name="time">시간(초 단위 문자열, 예: "3600")</param>
|
||||
/// <param name="fileName">파일명</param>
|
||||
/// <returns>비동기 작업(UniTask)</returns>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 재생 데이터를 설정하는 예시
|
||||
/// await controller.SetData("2024-07-29", "3600", "sample.sqlite");
|
||||
/// </code>
|
||||
/// </example>
|
||||
public async UniTask SetData(string date, string time, string fileName)
|
||||
{
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.fileName = fileName;
|
||||
|
||||
int timeInt = int.Parse(time);
|
||||
view.UpdateDateTime(date.Substring(2).Replace("-", "."));
|
||||
view.InitProgressBar(timeInt);
|
||||
view.InitSpeedSlider();
|
||||
view.SetOpacity(1);
|
||||
|
||||
UpdateTimeScale(1);
|
||||
preparingData = true;
|
||||
view.SetUIInteractable(!preparingData);
|
||||
isPlaying = false;
|
||||
UpdatePlayState();
|
||||
|
||||
// 실제 데이터 로딩 (비동기)
|
||||
await PlaybackService.Instance.DispatchBaseInfoData(date, time, fileName);
|
||||
preparingData = false;
|
||||
view.SetUIInteractable(!preparingData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 종료 버튼 클릭 시 호출됩니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// UI를 숨기고, 재생 상태를 초기화하며, PlaybackService에 종료를 알립니다.
|
||||
/// </remarks>
|
||||
private void OnClickExit()
|
||||
{
|
||||
UILoading.Show();
|
||||
isPlaying = false;
|
||||
UpdatePlayState();
|
||||
view.Hide();
|
||||
PlaybackService.Instance.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생/일시정지 버튼 클릭 시 호출됩니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 데이터 준비 중에는 동작하지 않습니다.
|
||||
/// </remarks>
|
||||
private void OnClickPlay()
|
||||
{
|
||||
if (preparingData) return;
|
||||
isPlaying = !isPlaying;
|
||||
UpdatePlayState();
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// 재생 위치(프로그레스바) 변경 시 호출됩니다.
|
||||
/// </summary>
|
||||
/// <param name="newValue">변경된 위치(초)</param>
|
||||
private void OnChangeProgress(int newValue)
|
||||
{
|
||||
ChangePlayTime().Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생 속도 변경 시 호출됩니다.
|
||||
/// </summary>
|
||||
/// <param name="newValue">변경된 속도 값</param>
|
||||
private void OnChangeSpeed(int newValue)
|
||||
{
|
||||
UpdateTimeScale(isPlaying ? view.GetSpeedValue() : 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 투명도 슬라이더 변경 시 호출됩니다.
|
||||
/// </summary>
|
||||
/// <param name="newValue">0~1 사이의 투명도 값</param>
|
||||
private void OnValueChangedOpacity(float newValue)
|
||||
{
|
||||
view.SetOpacity(newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생/일시정지 상태에 따라 UI와 타이머를 갱신합니다.
|
||||
/// </summary>
|
||||
private void UpdatePlayState()
|
||||
{
|
||||
view.UpdatePlayButtonState(isPlaying);
|
||||
IsTick = isPlaying;
|
||||
OnChangeSpeed(view.GetSpeedValue());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생 위치를 변경할 때 호출됩니다.
|
||||
/// 데이터 준비, UI 비활성화, 로딩 표시 등 처리 후 재생 위치를 이동합니다.
|
||||
/// </summary>
|
||||
private async UniTaskVoid ChangePlayTime()
|
||||
{
|
||||
bool tempIsPlaying = isPlaying;
|
||||
isPlaying = false;
|
||||
UpdatePlayState();
|
||||
|
||||
int newSecond = view.GetProgressValue();
|
||||
if (newSecond == view.GetProgressMaxValue())
|
||||
{
|
||||
newSecond -= 60;
|
||||
view.SetProgressValue(newSecond);
|
||||
}
|
||||
|
||||
preparingData = true;
|
||||
view.SetUIInteractable(!preparingData);
|
||||
IsTick = false;
|
||||
UILoading.Show();
|
||||
|
||||
|
||||
int minute = newSecond / 60;
|
||||
int seconds = newSecond % 60;
|
||||
// 새로운 위치로 데이터 요청
|
||||
await PlaybackService.Instance.DispatchBaseInfoData(date, time, fileName, minute.ToString("00"), seconds.ToString("00"));
|
||||
|
||||
preparingData = false;
|
||||
view.SetUIInteractable(!preparingData);
|
||||
|
||||
if (tempIsPlaying)
|
||||
{
|
||||
isPlaying = true;
|
||||
UpdatePlayState();
|
||||
}
|
||||
UILoading.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생 중일 때 일정 간격으로 호출되어 진행 바를 업데이트합니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// IsTick이 true일 때만 동작합니다.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 타이머를 시작하려면
|
||||
/// controller.IsTick = true;
|
||||
/// </code>
|
||||
/// </example>
|
||||
private async UniTaskVoid OnTimer()
|
||||
{
|
||||
if (view.GetProgressValue() >= view.GetProgressMaxValue())
|
||||
{
|
||||
if (isPlaying) OnClickPlay();
|
||||
return;
|
||||
}
|
||||
|
||||
view.SetProgressValue(view.GetProgressValue() + 1);
|
||||
// 실시간 데이터 요청
|
||||
PlaybackService.Instance.DispatchRealTimeData(view.GetProgressValue(), view.GetSpeedValue()).Forget();
|
||||
|
||||
if (IsTick)
|
||||
{
|
||||
// 재생 속도에 따라 대기 시간 조절
|
||||
await UniTask.Delay(TimeSpan.FromMilliseconds(1000 / view.GetSpeedValue()));
|
||||
if (IsTick) OnTimer().Forget();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 재생 속도를 PlaybackService에 반영합니다.
|
||||
/// </summary>
|
||||
/// <param name="timeScale">적용할 재생 속도</param>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 재생 속도를 2배로 변경
|
||||
/// controller.UpdateTimeScale(2f);
|
||||
/// </code>
|
||||
/// </example>
|
||||
internal void UpdateTimeScale(float timeScale)
|
||||
{
|
||||
PlaybackService.Instance.TimeScale = timeScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user