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();
}
}