사용자 정보 표시 관리 팝업 완료

This commit is contained in:
logonkhi
2025-08-01 13:30:58 +09:00
parent 23da311db0
commit 22794651f2
16 changed files with 226 additions and 59 deletions

View File

@@ -1,9 +1,13 @@
#nullable enable
using Cysharp.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UVC.Extention;
namespace UVC.Data.Core
@@ -17,6 +21,8 @@ namespace UVC.Data.Core
/// DataMask는 주로 DataMapper 클래스와 함께 사용되어 서로 다른 JSON 형식 간의
/// 데이터 변환 및 매핑 규칙을 정의합니다. 기본 JSON 구조 외에도 추가 속성들을
/// 통해 매핑 과정에서 필요한 메타데이터를 제공합니다.
/// 또한 AppData 폴더(AppData/Company Name/Product Name)에서 JSON 파일을 로드하고 저장하는 기능을 제공하여,
/// 그 기능은 FactoryObject의 정보를 InfoWindow로 보여줄때 사용됩니다.
/// </remarks>
/// <example>
/// 기본 사용 예시:
@@ -58,6 +64,10 @@ namespace UVC.Data.Core
private static Dictionary<string, DataMask> _dataMasks = new Dictionary<string, DataMask>();
public static IReadOnlyDictionary<string, DataMask> DataMasks => _dataMasks;
// 사용자 데이터 마스크를 저장하는 컬렉션입니다.
private static Dictionary<string, DataMask> _userDataMasks = new Dictionary<string, DataMask>();
public static IReadOnlyDictionary<string, DataMask> UserDataMasks => _userDataMasks;
/// <summary>
/// 컬렉션에 데이터 마스크를 추가하고 지정된 키와 연결합니다.
/// </summary>
@@ -65,10 +75,16 @@ namespace UVC.Data.Core
///</remarks>
/// <param name="key">데이터 마스크에 연결할 키입니다. <see langword="null"/>이거나 비어 있을 수 없습니다.</param>
/// <param name="mask">추가할 <see cref="DataMask"/>입니다. <see langword="null"/>일 수 없습니다.</param>
public static void AddMask(string key, DataMask mask)
/// <param name="withUser">사용자 데이터 마스크도 함께 추가할지 여부를 지정합니다. 기본값은 false입니다.</param>
public static void AddMask(string key, DataMask mask, bool withUser = false)
{
if (string.IsNullOrEmpty(key) || mask == null) return;
_dataMasks[key] = mask;
if (withUser && !_userDataMasks.ContainsKey(key))
{
// 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에 추가
AddUserMask(key, mask.CreateUserMask());
}
}
/// <summary>
@@ -76,10 +92,16 @@ namespace UVC.Data.Core
/// </summary>
/// <remarks> <paramref name="key"/>가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다.</remarks>
/// <param name="key">제거할 데이터 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다.</param>
public static void RemoveMask(string key)
/// <param name="withUser">사용자 데이터 마스크도 함께 제거할지 여부를 지정합니다. 기본값은 false입니다.</param>
public static void RemoveMask(string key, bool withUser = false)
{
if (string.IsNullOrEmpty(key)) return;
_dataMasks.Remove(key);
if(withUser)
{
// 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에서 제거
RemoveUserMask(key);
}
}
/// <summary>
@@ -95,7 +117,127 @@ namespace UVC.Data.Core
return mask;
}
/// <summary>
/// 내부 컬렉션에서 모든 데이터 마스크를 지웁니다.
/// </summary>
/// <remarks>이 메서드는 내부 데이터 마스크 컬렉션에서 모든 항목을 제거하고
/// 빈 상태로 재설정합니다. 이전에 추가된 모든 마스크를 지워야 할 때 이 메서드를 사용하세요.</remarks>
public static void ClearMask()
{
_dataMasks.Clear();
}
/// <summary>
/// 사용자 정의 키를 지정된 데이터 마스크에 연결합니다.
/// </summary>
/// <remarks>동일한 키를 가진 데이터 마스크가 이미 있는 경우 새
/// 마스크로 대체됩니다.</remarks>
/// <param name="key">데이터 마스크의 고유 식별자입니다. <see langword="null"/>이거나 비어 있을 수 없습니다.</param>
/// <param name="mask">지정된 키와 연결할 <see cref="DataMask"/> 객체입니다. <see langword="null"/>일 수 없습니다.</param>
public static void AddUserMask(string key, DataMask mask)
{
if (string.IsNullOrEmpty(key) || mask == null) return;
_userDataMasks[key] = mask;
}
/// <summary>
/// 지정된 키와 연관된 사용자 마스크를 제거합니다.
/// </summary>
/// <remarks> <paramref name="key"/>가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다.
///</remarks>
/// <param name="key">제거할 사용자 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다.</param>
public static void RemoveUserMask(string key)
{
if (string.IsNullOrEmpty(key)) return;
_userDataMasks.Remove(key);
}
/// <summary>
/// 지정된 키와 연관된 <see cref="DataMask"/>를 검색합니다.
/// </summary>
/// <param name="key">연관된 <see cref="DataMask"/>를 찾는 데 사용되는 키입니다. null이거나 비어 있을 수 없습니다.</param>
/// <returns>지정된 키와 연관된 <see cref="DataMask"/> 또는 키를 찾을 수 없거나 null이거나 비어 있는 경우 <see langword="null"/>을 반환합니다.
///</returns>
public static DataMask? GetUserMask(string key)
{
if (string.IsNullOrEmpty(key)) return null;
_userDataMasks.TryGetValue(key, out var mask);
return mask;
}
/// <summary>
/// 내부 컬렉션에서 모든 사용자 데이터 마스크를 지웁니다.
/// </summary>
/// <remarks>이 메서드는 사용자 데이터 마스크 컬렉션에서 모든 항목을 제거하고 빈 상태로 재설정합니다.
/// 일반적으로 새 마스크를 적용하기 전에 이전에 적용된 마스크를 지우는 데 사용됩니다.
///</remarks>
public static void ClearUserMask()
{
_userDataMasks.Clear();
}
/// <summary>
/// 애플리케이션의 영구 데이터 디렉터리(AppData/Company Name/Product Name)에서 사용자 마스크 데이터를 로드합니다.
/// </summary>
/// <remarks>이 메서드는 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에서 JSON 파일을 검색합니다.
/// 각 JSON 파일을 읽고 그 내용을 사용하여 <see cref="DataMask"/>
/// 객체를 생성한 후 애플리케이션의 사용자 마스크 컬렉션에 추가합니다. 이 메서드는 메인 스레드를 차단하지 않도록 백그라운드
/// 스레드에서 실행됩니다.</remarks>
/// <returns></returns>
public static async UniTask LoadUserMasksFromAppData()
{
string persistentDataPath = UnityEngine.Application.persistentDataPath;
await UniTask.RunOnThreadPool(() =>
{
string folderPath = System.IO.Path.Combine(persistentDataPath, "user");
DirectoryInfo directory = new DirectoryInfo(folderPath);
if (!directory.Exists) return;
FileInfo[] files = directory.GetFiles("*.json");
foreach (FileInfo file in files)
{
string filePath = file.FullName;
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
if (string.IsNullOrEmpty(fileName)) continue;
string jsonString = System.IO.File.ReadAllText(filePath);
AddUserMask(fileName, new DataMask(jsonString));
}
});
}
/// <summary>
/// 사용자 데이터 마스크를 애플리케이션의 영구 데이터 경로(AppData/Company Name/Product Name)에 저장합니다.
/// </summary>
/// <remarks>이 메서드는 모든 사용자 데이터 마스크를 반복하며 각 마스크를 JSON 파일로 저장합니다.
/// 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에 디렉터리가 없으면
/// 생성됩니다. 각 파일의 이름은 해당 키와 ".json" 확장자를 사용하여 지정됩니다. 저장 과정에서 발생하는 모든 오류는
/// Unity 콘솔에 기록됩니다.</remarks>
/// <returns></returns>
public static async UniTask SaveUserMasksToAppData()
{
string persistentDataPath = UnityEngine.Application.persistentDataPath;
await UniTask.RunOnThreadPool(() =>
{
foreach (var keyValue in _userDataMasks)
{
string key = keyValue.Key;
if (string.IsNullOrEmpty(key)) continue;
if (!_userDataMasks.TryGetValue(key, out var mask)) return;
try
{
string folderPath = System.IO.Path.Combine(persistentDataPath, "user");
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string filePath = System.IO.Path.Combine(folderPath, $"{key}.json");
string jsonString = mask.ToJsonString();
System.IO.File.WriteAllText(filePath, jsonString);
}
catch (Exception ex)
{
Debug.LogError($"DataMask SaveToStreamingAssets Error: {ex.Message}");
}
}
});
}
/// <summary>
/// DataObject의 Id에 해당하는 key 문자열입니다.
@@ -354,6 +496,23 @@ namespace UVC.Data.Core
return mask;
}
/// <summary>
/// 현재 컬렉션의 각 키가 자기 자신에게 매핑되는 새로운 <see cref="DataMask"/> 인스턴스를 생성합니다.
/// </summary>
/// <remarks>이 메서드는 현재 컬렉션을 반복하고 컬렉션의 각 키가 결과 마스크의 키와 값으로 모두 사용되는 새로운 <see
/// cref="DataMask"/>를 생성합니다.
///</remarks>
/// <returns>각 키가 자기 자신에게 매핑되는 키-값 쌍을 포함하는 <see cref="DataMask"/> 객체를 반환합니다.</returns>
public DataMask CreateUserMask()
{
DataMask userMask = new DataMask();
foreach (var pair in this)
{
userMask[pair.Key] = pair.Key;
}
return userMask;
}
/// <summary>
/// Json 문자열로 변환합니다.
/// </summary>