using System;
using System.Collections.Generic;
using UnityEngine;
namespace OCES.Audio
{
///
/// 音乐与环境音系统。由 AudioSystem 持有并初始化。
/// 对外只暴露 OnStateChanged,由 AudioSystem.SetState 转发调用。
///
class MusicSystem : MonoBehaviour
{
MusicStateRouter m_stateRouter;
MusicChannelPlayer m_musicChannel;
AmbienceChannelPlayer m_ambienceChannel;
internal event Action OnBeat;
internal event Action OnBar;
internal event Action OnGrid;
// 记录上一次两个通道各自匹配到的 PathId,用于查 Transition 表
uint m_lastMusicPathId;
uint m_lastAmbiencePathId;
internal IReadOnlyDictionary ActiveStates
{
get { return this.m_stateRouter.ActiveStates; }
}
internal void Initialize(
MusicSegmentConfig segments,
MusicContainerConfig containers,
MusicPathConfig musicPaths,
AmbiencePathConfig ambiencePaths,
MusicTransitionConfig musicTransitions,
AmbienceTransitionConfig ambienceTransitions,
AudioSourcePool musicPool,
AudioSourcePool ambiencePool)
{
MusicContainerPlayer musicContainerPlayer = new(containers, segments, musicPool, this);
MusicContainerPlayer ambientContainerPlayer = new(containers, segments, ambiencePool, this);
this.m_stateRouter = new MusicStateRouter(musicPaths, ambiencePaths);
this.m_musicChannel = new MusicChannelPlayer(
containers, musicTransitions, musicContainerPlayer, this,
id => OnBeat?.Invoke(id),
id => OnBar?.Invoke(id),
id => OnGrid?.Invoke(id));
this.m_ambienceChannel = new AmbienceChannelPlayer(ambienceTransitions, ambientContainerPlayer, this);
}
///
/// 由 AudioSystem.SetState 调用,更新状态并驱动两个通道切换。
///
internal void OnStateChanged(TEnum state) where TEnum : Enum
{
this.m_stateRouter.SetState(
state,
out uint musicContainerId,
out uint ambienceContainerId);
uint newMusicPathId = this.m_stateRouter.LastMusicPathId;
uint newAmbiencePathId = this.m_stateRouter.LastAmbiencePathId;
this.m_musicChannel.SwitchTo(musicContainerId, this.m_lastMusicPathId, newMusicPathId);
this.m_ambienceChannel.SwitchTo(ambienceContainerId, this.m_lastAmbiencePathId, newAmbiencePathId);
this.m_lastMusicPathId = newMusicPathId;
this.m_lastAmbiencePathId = newAmbiencePathId;
}
}
}