Files
XRLib/Assets/Scripts/Factory/Playback/PlaybackRepository.cs
2025-12-08 21:06:05 +09:00

195 lines
8.5 KiB
C#

#nullable enable
using Best.HTTP;
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using UnityEngine;
using UVC.Data;
using UVC.Network;
namespace UVC.Factory.Playback
{
public class PlaybackRepository
{
private PlaybackSQLiteService? sqliteService = null;
/// <summary>
/// 서버에서 재생 목록 날짜 리스트를 요청합니다.
///
/// 예시:
/// <code>
/// var repo = new PlaybackRepository();
/// var dateList = await repo.RequestPlaybackDateList();
/// if (dateList != null)
/// {
/// foreach (var date in dateList.Keys)
/// {
/// Debug.Log($"날짜: {date}");
/// }
/// }
/// </code>
/// </summary>
/// <returns>성공 시 날짜별 재생 목록 딕셔너리, 실패 시 null</returns>
public async UniTask<Dictionary<string, Dictionary<string, string>>?> RequestPlaybackDateList()
{
//local
//string path = System.IO.Path.Combine(Application.streamingAssetsPath, "playbackList.json");
//string json = System.IO.File.ReadAllText(path);
//HttpResponseModel<Dictionary<string, Dictionary<string, string>>> localData = JsonHelper.FromJson<HttpResponseModel<Dictionary<string, Dictionary<string, string>>>>(json);
//return new EntityWithState<Dictionary<string, Dictionary<string, string>>>(APIState.Loaded, localData.data);
try
{
#if UNITY_WEBGL && !UNITY_EDITOR
// WebGL: ThreadPool 사용 없이 직접 실행
var response = await HttpRequester.RequestGet<HttpResponseModel<Dictionary<string, Dictionary<string, string>>>>(URLList.Get("playbackList"));
if (string.Equals(response.message, "success", StringComparison.OrdinalIgnoreCase))
{
return new Dictionary<string, Dictionary<string, string>>(response.data);
}
return null;
#else
return await UniTask.RunOnThreadPool<Dictionary<string, Dictionary<string, string>>?>(async () =>
{
var response = await HttpRequester.RequestGet<HttpResponseModel<Dictionary<string, Dictionary<string, string>>>>(URLList.Get("playbackList"));
if (response.message.ToLower() == "success")
{
return new Dictionary<string, Dictionary<string, string>>(response.data);
}
return null;
});
#endif
}
catch (Exception e)
{
Debug.Log($"Exception {e.ToString()}");
return null;
}
}
/// <summary>
/// 서버에서 재생 데이터 파일을 다운로드합니다.
///
/// 예시:
/// <code>
/// var repo = new PlaybackRepository();
/// string fileName = "sample.db";
/// string savePath = Application.persistentDataPath + "/sample.db";
/// repo.DownloadPlaybackData(
/// fileName,
/// savePath,
/// (current, total) => Debug.Log($"{current}/{total} bytes 다운로드 중"),
/// () => Debug.Log("다운로드 완료"),
/// (error) => Debug.LogError($"다운로드 실패: {error}")
/// );
/// </code>
/// </summary>
/// <param name="fileName">다운로드할 파일명</param>
/// <param name="savePath">저장 경로</param>
/// <param name="OnProgress">다운로드 진행 콜백 (현재, 전체 바이트)</param>
/// <param name="OnComplete">다운로드 완료 콜백</param>
/// <param name="OnError">다운로드 실패 콜백 (에러 메시지)</param>
/// <returns>다운로드 요청 객체(필요시 Abort 등 제어 가능), 실패 시 null</returns>
public HTTPRequest? DownloadPlaybackData(string fileName, string savePath, Action<long, long> OnProgress, Action OnComplete, Action<string> OnError)
{
try
{
return HttpRequester.Download($"{URLList.Get("playbackFile")}/{fileName}", savePath, OnComplete, OnProgress, OnError);
}
catch (Exception e)
{
Debug.Log($"Exception {e.ToString()}");
return null;
}
}
/// <summary>
/// selectTime보다 ±second 사이의 데이터를 조회합니다. selectTime, second 포함.
///
/// 예시:
/// <code>
/// var repo = new PlaybackRepository();
/// string date = "2024-07-29";
/// string sqlFileName = "sample.db";
/// string selectTime = "2024-07-29T12:00:00.000Z";
/// int second = 10;
/// var list = await repo.SelectBySecondAsync(date, sqlFileName, selectTime, second, true, 5);
/// foreach (var entity in list)
/// {
/// Debug.Log($"데이터: {entity.data}, 시간: {entity.timestamp}");
/// }
/// </code>
/// </summary>
/// <param name="date">폴더명(날짜 등)</param>
/// <param name="sqlFileName">SQLite 파일명</param>
/// <param name="selectTime">yyyy-MM-ddTHH:mm:ss.fffZ 형식의 기준 시간</param>
/// <param name="second">±초(양수: 미래, 음수: 과거)</param>
/// <param name="orderAsc">true: 오래된 시간부터, false: 최근 시간부터</param>
/// <param name="limit">최대 조회 개수(0이면 제한 없음)</param>
/// <returns>조회된 데이터 리스트</returns>
public async UniTask<List<PlaybackSQLiteDataEntity>> SelectBySecondAsync(string date, string sqlFileName, string selectTime, int second, bool orderAsc = true, int limit = 0)
{
validationSqliteService(date, sqlFileName);
return await sqliteService!.SelectBySecond(selectTime, second, orderAsc, limit);
}
/// <summary>
/// baseInfo 테이블에서 selectTime보다 ±second 사이의 데이터를 조회합니다. selectTime, second 포함.
///
/// 예시:
/// <code>
/// var repo = new PlaybackRepository();
/// string date = "2024-07-29";
/// string sqlFileName = "sample.db";
/// string selectTime = "2024-07-29T12:00:00.000Z";
/// int second = -5;
/// var list = await repo.SelectBySecondBaseInfo(date, sqlFileName, selectTime, second, false, 1);
/// foreach (var entity in list)
/// {
/// Debug.Log($"데이터: {entity.data}, 시간: {entity.timestamp}");
/// }
/// </code>
/// </summary>
/// <param name="date">폴더명(날짜 등)</param>
/// <param name="sqlFileName">SQLite 파일명</param>
/// <param name="selectTime">yyyy-MM-ddTHH:mm:ss.fffZ 형식의 기준 시간</param>
/// <param name="second">±초(양수: 미래, 음수: 과거)</param>
/// <param name="orderAsc">true: 오래된 시간부터, false: 최근 시간부터</param>
/// <param name="limit">최대 조회 개수</param>
/// <returns>조회된 데이터 리스트</returns>
public async UniTask<List<PlaybackSQLiteDataEntity>> SelectBySecondBaseInfo(string date, string sqlFileName, string selectTime, int second = 59, bool orderAsc = true, int limit = 1)
{
validationSqliteService(date, sqlFileName);
return await sqliteService!.SelectBySecondBaseInfo(selectTime, second, orderAsc, limit);
}
/// <summary>
/// 내부적으로 SQLite 서비스가 올바른 파일에 연결되어 있는지 확인하고, 필요시 재연결합니다.
///
/// 예시:
/// <code>
/// // 일반적으로 직접 호출할 필요 없음(내부에서 자동 호출)
/// validationSqliteService("2024-07-29", "sample.db");
/// </code>
/// </summary>
/// <param name="date">폴더명(날짜 등)</param>
/// <param name="sqlFileName">SQLite 파일명</param>
private void validationSqliteService(string date, string sqlFileName)
{
if (sqliteService == null) sqliteService = new PlaybackSQLiteService();
if (sqliteService.Connected)
{
if (sqliteService.Date != date || sqliteService.SqliteFileName != sqlFileName)
{
sqliteService.CloseDB();
}
}
sqliteService.Connect(date, sqlFileName);
}
}
}