159 lines
5.1 KiB
C#
159 lines
5.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.FixSystem
|
||
{
|
||
[Serializable]
|
||
public sealed class PunchTapeDefinition
|
||
{
|
||
[SerializeField] private string id;
|
||
[SerializeField] private string displayNameParam;
|
||
[SerializeField] private string dialogNode;
|
||
[SerializeField] private string memoryResourceKey;
|
||
[SerializeField] private string visibilityCode;
|
||
[SerializeField] private string contentId;
|
||
[SerializeField] private string timecode;
|
||
|
||
public string Id => id;
|
||
public string DisplayNameParam => displayNameParam;
|
||
public string DialogNode => dialogNode;
|
||
public string MemoryResourceKey => memoryResourceKey;
|
||
public string VisibilityCode => visibilityCode;
|
||
public string ContentId => contentId;
|
||
public string Timecode => timecode;
|
||
|
||
public bool TryValidate(out string error)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(id))
|
||
{
|
||
error = "ID 不能为空。";
|
||
return false;
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(displayNameParam) ||
|
||
!displayNameParam.StartsWith("l10n.", StringComparison.Ordinal))
|
||
{
|
||
error = $"'{id}' 的名称必须配置为 l10n.* 参数键。";
|
||
return false;
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(dialogNode) || string.IsNullOrWhiteSpace(memoryResourceKey) ||
|
||
string.IsNullOrWhiteSpace(visibilityCode) || string.IsNullOrWhiteSpace(contentId) ||
|
||
string.IsNullOrWhiteSpace(timecode))
|
||
{
|
||
error = $"'{id}' 存在未填写的流程或显示字段。";
|
||
return false;
|
||
}
|
||
|
||
error = null;
|
||
return true;
|
||
}
|
||
|
||
#if UNITY_EDITOR
|
||
public void ConfigureForEditor(string definitionId, string localizedNameParam, string yarnDialogNode,
|
||
string resourceKey, string visibility, string cid, string timestamp)
|
||
{
|
||
id = definitionId;
|
||
displayNameParam = localizedNameParam;
|
||
dialogNode = yarnDialogNode;
|
||
memoryResourceKey = resourceKey;
|
||
visibilityCode = visibility;
|
||
contentId = cid;
|
||
timecode = timestamp;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
[CreateAssetMenu(fileName = "PunchTapeCatalog", menuName = AibisAssetMenus.MemoryPunchTapeCatalog)]
|
||
public sealed class PunchTapeCatalog : ScriptableObject
|
||
{
|
||
[SerializeField] private List<PunchTapeDefinition> definitions = new();
|
||
|
||
private Dictionary<string, PunchTapeDefinition> definitionById;
|
||
|
||
public IReadOnlyList<PunchTapeDefinition> Definitions => definitions;
|
||
|
||
public bool TryGetDefinition(string definitionId, out PunchTapeDefinition definition)
|
||
{
|
||
EnsureLookup();
|
||
if (string.IsNullOrWhiteSpace(definitionId))
|
||
{
|
||
definition = null;
|
||
return false;
|
||
}
|
||
|
||
return definitionById.TryGetValue(definitionId, out definition);
|
||
}
|
||
|
||
public List<string> GetValidationErrors()
|
||
{
|
||
var errors = new List<string>();
|
||
var ids = new HashSet<string>(StringComparer.Ordinal);
|
||
|
||
if (definitions == null || definitions.Count == 0)
|
||
{
|
||
errors.Add("Catalog 中没有打孔带定义。");
|
||
return errors;
|
||
}
|
||
|
||
for (var i = 0; i < definitions.Count; i++)
|
||
{
|
||
var definition = definitions[i];
|
||
if (definition == null)
|
||
{
|
||
errors.Add($"definitions[{i}] 为空。");
|
||
continue;
|
||
}
|
||
|
||
if (!definition.TryValidate(out var error))
|
||
errors.Add(error);
|
||
|
||
if (!string.IsNullOrWhiteSpace(definition.Id) && !ids.Add(definition.Id))
|
||
errors.Add($"存在重复 ID:'{definition.Id}'。");
|
||
}
|
||
|
||
return errors;
|
||
}
|
||
|
||
private void EnsureLookup()
|
||
{
|
||
if (definitionById != null)
|
||
return;
|
||
|
||
definitionById = new Dictionary<string, PunchTapeDefinition>(StringComparer.Ordinal);
|
||
if (definitions == null)
|
||
return;
|
||
|
||
foreach (var definition in definitions)
|
||
{
|
||
if (definition == null || string.IsNullOrWhiteSpace(definition.Id) ||
|
||
definitionById.ContainsKey(definition.Id))
|
||
continue;
|
||
|
||
definitionById.Add(definition.Id, definition);
|
||
}
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
definitionById = null;
|
||
}
|
||
|
||
#if UNITY_EDITOR
|
||
private void OnValidate()
|
||
{
|
||
definitionById = null;
|
||
}
|
||
|
||
public void SetDefinitionsForEditor(IEnumerable<PunchTapeDefinition> newDefinitions)
|
||
{
|
||
definitions = newDefinitions == null
|
||
? new List<PunchTapeDefinition>()
|
||
: new List<PunchTapeDefinition>(newDefinitions);
|
||
definitionById = null;
|
||
}
|
||
#endif
|
||
}
|
||
}
|