using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using BITKit; using Cysharp.Threading.Tasks; namespace Net.Project.B.Dialogue { /// /// 对话服务 /// public interface IDialogueService { /// /// 所有对话 /// IReadOnlyDictionary Dialogues { get; } /// /// 对话开始 /// public event Func OnDialogueStart; /// /// 对话结束 /// public event Action OnDialogueEnd; /// /// 对话选择 /// public event Func, UniTask> OnDialogueChoose; /// /// 对话选择回调 /// public event Action OnDialogueChose; /// /// 开启对话 /// /// 对话 /// UniTask CreateDialogue(IDialogueData dialogueData); UniTask CreateDialogue(IDialogueData dialogueData, IReadOnlyCollection dialogueChoices); } public class DialogueService : IDialogueService { public IReadOnlyDictionary Dialogues => _dialogues; public event Func OnDialogueStart; public event Action OnDialogueEnd; public event Func, UniTask> OnDialogueChoose; public event Action OnDialogueChose; public async UniTask CreateDialogue(IDialogueData dialogueData) { if (_dialogues.TryAdd(dialogueData.Identity, dialogueData) is false) { dialogueData.Identity = _dialogues.Keys.Max() + 1; _dialogues.TryAdd(dialogueData.Identity, dialogueData); } await OnDialogueStart.UniTaskFunc(dialogueData); OnDialogueEnd?.Invoke(dialogueData); } public async UniTask CreateDialogue(IDialogueData dialogueData, IReadOnlyCollection dialogueChoices) { if (OnDialogueChoose is null) { throw new NullReferenceException("OnDialogueChoose is null,unable to create dialogue"); } var task = OnDialogueChoose.Invoke(dialogueData, dialogueChoices); var index = await task; OnDialogueChose?.Invoke(dialogueData, dialogueChoices.ElementAt(index)); return index; } private readonly ConcurrentDictionary _dialogues = new(); } }