Net.Project.B.Dialogue/Src/Dialogue/IDialogueService.cs

91 lines
2.9 KiB
C#

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
{
/// <summary>
/// 对话服务
/// </summary>
public interface IDialogueService
{
/// <summary>
/// 所有对话
/// </summary>
IReadOnlyDictionary<int, IDialogueData> Dialogues { get; }
/// <summary>
/// 对话开始
/// </summary>
public event Func<IDialogueData, UniTask> OnDialogueStart;
/// <summary>
/// 对话结束
/// </summary>
public event Action<IDialogueData> OnDialogueEnd;
/// <summary>
/// 对话选择
/// </summary>
public event Func<IDialogueData, IReadOnlyCollection<IDialogueChoice>, UniTask<int>> OnDialogueChoose;
/// <summary>
/// 对话选择回调
/// </summary>
public event Action<IDialogueData, IDialogueChoice> OnDialogueChose;
/// <summary>
/// 开启对话
/// </summary>
/// <param name="dialogueData">对话</param>
/// <returns></returns>
UniTask CreateDialogue(IDialogueData dialogueData);
UniTask<int> CreateDialogue(IDialogueData dialogueData, IReadOnlyCollection<IDialogueChoice> dialogueChoices);
}
public class DialogueService : IDialogueService
{
public IReadOnlyDictionary<int, IDialogueData> Dialogues => _dialogues;
public event Func<IDialogueData, UniTask> OnDialogueStart;
public event Action<IDialogueData> OnDialogueEnd;
public event Func<IDialogueData, IReadOnlyCollection<IDialogueChoice>, UniTask<int>> OnDialogueChoose;
public event Action<IDialogueData, IDialogueChoice> 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<int> CreateDialogue(IDialogueData dialogueData,
IReadOnlyCollection<IDialogueChoice> 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<int, IDialogueData> _dialogues = new();
}
}