Files

159 lines
5.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}
}