Compare commits
1 Commits
master
...
feature/ba
Author | SHA1 | Date |
---|---|---|
|
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