[ADD] CSV Loader 초안 완료
This commit is contained in:
parent
c1cbd2c3ff
commit
5db096060e
|
@ -0,0 +1,118 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
/// <summary>
|
||||
/// CSV 데이터를 다양한 소스에서 Pull 방식으로 로드할 수 있는 클래스입니다.
|
||||
/// 호출 측에서 MoveNext()를 통해 처리 타이밍을 제어하세요.
|
||||
/// </summary>
|
||||
public static class CSVLoader
|
||||
{
|
||||
/// <summary>CSV 파싱 로직 정의</summary>
|
||||
public interface IParser<T>
|
||||
{
|
||||
T Parse(string[] columns);
|
||||
}
|
||||
|
||||
/// <summary>로딩 진행 상태 메타데이터</summary>
|
||||
public struct Progress
|
||||
{
|
||||
public int TotalRows;
|
||||
public int RowsLoaded;
|
||||
}
|
||||
|
||||
/// <summary>URL(HTTP)로부터 다운로드하여 파싱</summary>
|
||||
public static IEnumerator<Progress> Download<T>(string url,
|
||||
IParser<T> parser,
|
||||
List<T> outList)
|
||||
{
|
||||
using var uwr = UnityWebRequest.Get(url);
|
||||
var operation = uwr.SendWebRequest();
|
||||
// 요청이 완료될 때까지 대기 (Progress 타입 반환은 요청 상태 표시용)
|
||||
while (!operation.isDone)
|
||||
{
|
||||
yield return new Progress { TotalRows = 0, RowsLoaded = 0 };
|
||||
}
|
||||
|
||||
if (uwr.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Logger.LogError($"CSVLoader: Download failed '{url}': {uwr.error}");
|
||||
yield break;
|
||||
}
|
||||
|
||||
string text = uwr.downloadHandler.text;
|
||||
foreach (var prog in ProcessText(text, parser, outList))
|
||||
yield return prog;
|
||||
}
|
||||
|
||||
/// <summary>절대 경로의 파일을 읽어 파싱</summary>
|
||||
public static IEnumerator<Progress> LoadFromFile<T>(string filePath,
|
||||
IParser<T> parser,
|
||||
List<T> outList)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Logger.LogError($"CSVLoader: File not found '{filePath}'");
|
||||
yield break;
|
||||
}
|
||||
string text = File.ReadAllText(filePath);
|
||||
foreach (var prog in ProcessText(text, parser, outList))
|
||||
yield return prog;
|
||||
}
|
||||
|
||||
/// <summary>StreamingAssets 내 상대 경로 또는 URL로부터 로드</summary>
|
||||
public static IEnumerator<Progress> LoadFromStreamingAssets<T>(string relativePath,
|
||||
IParser<T> parser,
|
||||
List<T> outList)
|
||||
{
|
||||
string fullPath = Path.Combine(Application.streamingAssetsPath, relativePath);
|
||||
if (fullPath.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var downloadEnum = Download(fullPath, parser, outList);
|
||||
while (downloadEnum.MoveNext())
|
||||
yield return downloadEnum.Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileEnum = LoadFromFile(fullPath, parser, outList);
|
||||
while (fileEnum.MoveNext())
|
||||
yield return fileEnum.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Resources 폴더 내 TextAsset로부터 로드</summary>
|
||||
public static IEnumerator<Progress> LoadFromResources<T>(string resourcePath,
|
||||
IParser<T> parser,
|
||||
List<T> outList)
|
||||
{
|
||||
var ta = Resources.Load<TextAsset>(resourcePath);
|
||||
if (ta == null)
|
||||
{
|
||||
Logger.LogError($"CSVLoader: Resource not found '{resourcePath}'");
|
||||
yield break;
|
||||
}
|
||||
string text = ta.text;
|
||||
foreach (var prog in ProcessText(text, parser, outList))
|
||||
yield return prog;
|
||||
}
|
||||
|
||||
/// <summary>텍스트를 실제 파싱하여 Progress를 반환하는 내부 모듈</summary>
|
||||
static IEnumerable<Progress> ProcessText<T>(string text,
|
||||
IParser<T> parser,
|
||||
List<T> outList)
|
||||
{
|
||||
var lines = text.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int total = lines.Length;
|
||||
// 첫 번째 줄은 헤더이므로 무시
|
||||
// 두 번째 줄은 설명이므로 무시
|
||||
for (int i = 2; i < total; i++)
|
||||
{
|
||||
var cols = lines[i].TrimEnd('\r').Split(',');
|
||||
outList.Add(parser.Parse(cols));
|
||||
yield return new Progress { TotalRows = total, RowsLoaded = i + 1 };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1b37f2c717edfd748bf3173c734fee71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue