Files
blockout/BlockOutReplica/Assets/Scripts/Infrastructure/OriginalLevelRepository.cs
T
2026-10-20 13:21:04 +08:00

59 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using BlockOutReplica.Domain;
using UnityEngine;
namespace BlockOutReplica.Infrastructure
{
public static class OriginalLevelRepository
{
private const string LevelRoot = "OriginalLevels/";
private static IReadOnlyList<string> cachedLevelIds;
public static LevelDefinition LoadLevelOne() => Load("t140-level-1");
public static IReadOnlyList<string> GetLevelIds()
{
if (cachedLevelIds != null) return cachedLevelIds;
TextAsset[] assets = Resources.LoadAll<TextAsset>("OriginalLevels");
List<string> ids = new List<string>(assets.Length);
for (int i = 0; i < assets.Length; i++) ids.Add(assets[i].name);
ids.Sort(CompareLevelIds);
cachedLevelIds = ids;
return cachedLevelIds;
}
public static LevelDefinition Load(string levelId)
{
if (string.IsNullOrWhiteSpace(levelId) || levelId.Contains("/") || levelId.Contains("\\"))
throw new ArgumentException("Level id must be a plain resource name.", nameof(levelId));
string resourcePath = LevelRoot + levelId;
TextAsset asset = Resources.Load<TextAsset>(resourcePath);
if (asset == null)
throw new InvalidOperationException("Missing Resources/" + resourcePath + ".json");
return OriginalLevelJsonParser.Parse(asset.text);
}
private static int CompareLevelIds(string left, string right)
{
SplitLevelId(left, out string leftFamily, out int leftNumber);
SplitLevelId(right, out string rightFamily, out int rightNumber);
int family = string.CompareOrdinal(leftFamily, rightFamily);
return family != 0 ? family : leftNumber.CompareTo(rightNumber);
}
private static void SplitLevelId(string id, out string family, out int number)
{
int marker = id.LastIndexOf("-level-", StringComparison.Ordinal);
if (marker < 0 || !int.TryParse(id.Substring(marker + 7), out number))
{
family = id;
number = int.MaxValue;
return;
}
family = id.Substring(0, marker);
}
}
}