[Optimization] TimerService&TimerDebug&AudioService
[Optimization] TimerService&TimerDebug&AudioService
This commit is contained in:
parent
a74715b468
commit
f4f0ea1754
@ -13,7 +13,6 @@ namespace AlicizaX.Audio.Editor
|
|||||||
private readonly AudioCategoryDebugInfo _categoryInfo = new AudioCategoryDebugInfo();
|
private readonly AudioCategoryDebugInfo _categoryInfo = new AudioCategoryDebugInfo();
|
||||||
private readonly AudioAgentDebugInfo _agentInfo = new AudioAgentDebugInfo();
|
private readonly AudioAgentDebugInfo _agentInfo = new AudioAgentDebugInfo();
|
||||||
private readonly AudioClipCacheDebugInfo _clipCacheInfo = new AudioClipCacheDebugInfo();
|
private readonly AudioClipCacheDebugInfo _clipCacheInfo = new AudioClipCacheDebugInfo();
|
||||||
private SerializedProperty m_InstanceRoot = null;
|
|
||||||
private SerializedProperty m_AudioListener = null;
|
private SerializedProperty m_AudioListener = null;
|
||||||
private SerializedProperty m_AudioMixer = null;
|
private SerializedProperty m_AudioMixer = null;
|
||||||
private SerializedProperty m_AudioGroupConfigs = null;
|
private SerializedProperty m_AudioGroupConfigs = null;
|
||||||
@ -31,7 +30,6 @@ namespace AlicizaX.Audio.Editor
|
|||||||
|
|
||||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
||||||
{
|
{
|
||||||
EditorGUILayout.PropertyField(m_InstanceRoot);
|
|
||||||
EditorGUILayout.PropertyField(m_AudioListener, AudioListenerLabel);
|
EditorGUILayout.PropertyField(m_AudioListener, AudioListenerLabel);
|
||||||
EditorGUILayout.PropertyField(m_AudioMixer);
|
EditorGUILayout.PropertyField(m_AudioMixer);
|
||||||
EditorGUILayout.PropertyField(m_AudioGroupConfigs, GroupConfigLabel);
|
EditorGUILayout.PropertyField(m_AudioGroupConfigs, GroupConfigLabel);
|
||||||
@ -51,7 +49,6 @@ namespace AlicizaX.Audio.Editor
|
|||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
m_InstanceRoot = serializedObject.FindProperty("m_InstanceRoot");
|
|
||||||
m_AudioListener = serializedObject.FindProperty("m_AudioListener");
|
m_AudioListener = serializedObject.FindProperty("m_AudioListener");
|
||||||
m_AudioMixer = serializedObject.FindProperty("m_AudioMixer");
|
m_AudioMixer = serializedObject.FindProperty("m_AudioMixer");
|
||||||
m_AudioGroupConfigs = serializedObject.FindProperty("m_AudioGroupConfigs");
|
m_AudioGroupConfigs = serializedObject.FindProperty("m_AudioGroupConfigs");
|
||||||
|
|||||||
8
Editor/Timer.meta
Normal file
8
Editor/Timer.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d5eec662629e81c458ff9c776e1a9e29
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
169
Editor/Timer/TimerComponentInspector.cs
Normal file
169
Editor/Timer/TimerComponentInspector.cs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
using AlicizaX.Editor;
|
||||||
|
using AlicizaX.Timer.Runtime;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace AlicizaX.Timer.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(TimerComponent))]
|
||||||
|
internal sealed class TimerComponentInspector : GameFrameworkInspector
|
||||||
|
{
|
||||||
|
private const double UPDATE_INTERVAL = 0.001d;
|
||||||
|
private const int MAX_DISPLAY_COUNT = 20;
|
||||||
|
|
||||||
|
private TimerDebugInfo[] _timerBuffer;
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private TimerDebugInfo[] _leakBuffer;
|
||||||
|
#endif
|
||||||
|
private double _lastUpdateTime;
|
||||||
|
private int _cachedActiveCount;
|
||||||
|
private int _cachedPoolCapacity;
|
||||||
|
private int _cachedPeakActiveCount;
|
||||||
|
private int _cachedFreeCount;
|
||||||
|
private string _cachedUsageText;
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
base.OnInspectorGUI();
|
||||||
|
|
||||||
|
serializedObject.Update();
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
|
||||||
|
DrawRuntimeDebugInfo();
|
||||||
|
|
||||||
|
if (EditorApplication.isPlaying)
|
||||||
|
{
|
||||||
|
double currentTime = EditorApplication.timeSinceStartup;
|
||||||
|
if (currentTime - _lastUpdateTime >= UPDATE_INTERVAL)
|
||||||
|
{
|
||||||
|
_lastUpdateTime = currentTime;
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawRuntimeDebugInfo()
|
||||||
|
{
|
||||||
|
if (!EditorApplication.isPlaying)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AppServices.TryGet<ITimerService>(out ITimerService timerService))
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Timer service is not initialized.", MessageType.Info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timerService is not ITimerServiceDebugView debugView)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugView.GetStatistics(out _cachedActiveCount, out _cachedPoolCapacity, out _cachedPeakActiveCount, out _cachedFreeCount);
|
||||||
|
_cachedUsageText = _cachedPoolCapacity > 0
|
||||||
|
? Utility.Text.Format("{0:F1}%", (float)_cachedActiveCount / _cachedPoolCapacity * 100f)
|
||||||
|
: "0.0%";
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.LabelField("Runtime Debug", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.LabelField("Active Timers", _cachedActiveCount.ToString());
|
||||||
|
EditorGUILayout.LabelField("Pool Capacity", _cachedPoolCapacity.ToString());
|
||||||
|
EditorGUILayout.LabelField("Peak Active Count", _cachedPeakActiveCount.ToString());
|
||||||
|
EditorGUILayout.LabelField("Free Slots", _cachedFreeCount.ToString());
|
||||||
|
EditorGUILayout.LabelField("Pool Usage", _cachedUsageText);
|
||||||
|
|
||||||
|
DrawTimerList(debugView, _cachedActiveCount);
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
DrawLeakDetection(debugView, _cachedActiveCount);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTimerList(ITimerServiceDebugView debugView, int activeCount)
|
||||||
|
{
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.LabelField("Active Timers", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
if (activeCount <= 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("No active timers.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTimerBuffer(activeCount);
|
||||||
|
int timerCount = debugView.GetAllTimers(_timerBuffer);
|
||||||
|
int displayCount = Mathf.Min(timerCount, MAX_DISPLAY_COUNT);
|
||||||
|
|
||||||
|
if (displayCount < timerCount)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox(Utility.Text.Format("Showing first {0} timers of {1}.", displayCount, timerCount), MessageType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < displayCount; i++)
|
||||||
|
{
|
||||||
|
TimerDebugInfo timer = _timerBuffer[i];
|
||||||
|
string label = Utility.Text.Format(
|
||||||
|
"ID {0} | {1} | {2} | {3}",
|
||||||
|
timer.TimerId,
|
||||||
|
timer.IsLoop ? "Loop" : "Once",
|
||||||
|
timer.IsUnscaled ? "Unscaled" : "Scaled",
|
||||||
|
timer.IsRunning ? "Running" : "Paused");
|
||||||
|
|
||||||
|
string value = Utility.Text.Format(
|
||||||
|
"Left {0:F2}s | Duration {1:F2}s",
|
||||||
|
timer.LeftTime,
|
||||||
|
timer.Duration);
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField(label, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void DrawLeakDetection(ITimerServiceDebugView debugView, int activeCount)
|
||||||
|
{
|
||||||
|
if (activeCount <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureLeakBuffer(activeCount);
|
||||||
|
int staleCount = debugView.GetStaleOneShotTimers(_leakBuffer);
|
||||||
|
if (staleCount <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.LabelField(Utility.Text.Format("Stale One-Shot Timers ({0})", staleCount), EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.HelpBox("Non-loop timers older than 5 minutes. This may indicate long-delay tasks or paused timers.", MessageType.Warning);
|
||||||
|
|
||||||
|
for (int i = 0; i < staleCount; i++)
|
||||||
|
{
|
||||||
|
TimerDebugInfo staleTimer = _leakBuffer[i];
|
||||||
|
EditorGUILayout.LabelField(
|
||||||
|
Utility.Text.Format("ID {0}", staleTimer.TimerId),
|
||||||
|
Utility.Text.Format("Created {0:F1}s ago", staleTimer.CreationTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private void EnsureTimerBuffer(int count)
|
||||||
|
{
|
||||||
|
if (_timerBuffer == null || _timerBuffer.Length < count)
|
||||||
|
{
|
||||||
|
_timerBuffer = new TimerDebugInfo[count];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void EnsureLeakBuffer(int count)
|
||||||
|
{
|
||||||
|
if (_leakBuffer == null || _leakBuffer.Length < count)
|
||||||
|
{
|
||||||
|
_leakBuffer = new TimerDebugInfo[count];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Editor/Timer/TimerComponentInspector.cs.meta
Normal file
11
Editor/Timer/TimerComponentInspector.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 02aa1426c358e87479136bd0f17f1f1c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -1,6 +1,4 @@
|
|||||||
#if ZSTRING_SUPPORT
|
using Cysharp.Text;
|
||||||
using Cysharp.Text;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace AlicizaX
|
namespace AlicizaX
|
||||||
{
|
{
|
||||||
@ -21,11 +19,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg);
|
return ZString.Format(format, arg);
|
||||||
#else
|
|
||||||
return string.Format(format, arg);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -43,11 +38,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2);
|
return ZString.Format(format, arg1, arg2);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -67,11 +59,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3);
|
return ZString.Format(format, arg1, arg2, arg3);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -93,11 +82,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4);
|
return ZString.Format(format, arg1, arg2, arg3, arg4);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -121,11 +107,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -151,11 +134,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -183,11 +163,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -217,11 +194,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -253,11 +227,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -291,11 +262,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -331,11 +299,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -373,11 +338,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -417,11 +379,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -463,11 +422,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -511,11 +467,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -561,11 +514,8 @@ namespace AlicizaX
|
|||||||
{
|
{
|
||||||
throw new GameFrameworkException("Format is invalid.");
|
throw new GameFrameworkException("Format is invalid.");
|
||||||
}
|
}
|
||||||
#if ZSTRING_SUPPORT
|
|
||||||
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
|
return ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
|
||||||
#else
|
|
||||||
return string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,11 +21,6 @@
|
|||||||
"name": "com.alicizax.unity.animationflow",
|
"name": "com.alicizax.unity.animationflow",
|
||||||
"expression": "",
|
"expression": "",
|
||||||
"define": "ALICIZAX_UI_ANIMATION_SUPPORT"
|
"define": "ALICIZAX_UI_ANIMATION_SUPPORT"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "com.alicizax.unity.cysharp.zstring",
|
|
||||||
"expression": "2.3.0",
|
|
||||||
"define": "ZSTRING_SUPPORT"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
|
|||||||
3
Runtime/AssemblyInfo.cs
Normal file
3
Runtime/AssemblyInfo.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("AlicizaX.Framework.Editor")]
|
||||||
11
Runtime/AssemblyInfo.cs.meta
Normal file
11
Runtime/AssemblyInfo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc79b52770c12304bbdd80020433741e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -25,6 +25,8 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
private ulong _handle;
|
private ulong _handle;
|
||||||
private float _baseVolume;
|
private float _baseVolume;
|
||||||
private float _pitch;
|
private float _pitch;
|
||||||
|
private float _fadeInTimer;
|
||||||
|
private float _fadeInDuration;
|
||||||
private float _fadeTimer;
|
private float _fadeTimer;
|
||||||
private float _fadeDuration;
|
private float _fadeDuration;
|
||||||
private float _startedAt;
|
private float _startedAt;
|
||||||
@ -37,7 +39,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
internal ulong Handle => _handle;
|
internal ulong Handle => _handle;
|
||||||
internal int Generation => _generation;
|
internal int Generation => _generation;
|
||||||
internal bool IsFree => _state == AudioAgentRuntimeState.Free;
|
internal bool IsFree => _state == AudioAgentRuntimeState.Free;
|
||||||
internal bool IsPlayingState => _state == AudioAgentRuntimeState.Playing || _state == AudioAgentRuntimeState.Loading || _state == AudioAgentRuntimeState.Paused || _state == AudioAgentRuntimeState.FadingOut;
|
internal bool IsPlayingState => _state == AudioAgentRuntimeState.Playing || _state == AudioAgentRuntimeState.Loading || _state == AudioAgentRuntimeState.Paused || _state == AudioAgentRuntimeState.FadingIn || _state == AudioAgentRuntimeState.FadingOut;
|
||||||
internal float StartedAt => _startedAt;
|
internal float StartedAt => _startedAt;
|
||||||
|
|
||||||
internal void Initialize(AudioService service, AudioCategory category, int index, int globalIndex, AudioSourceObject sourceObject)
|
internal void Initialize(AudioService service, AudioCategory category, int index, int globalIndex, AudioSourceObject sourceObject)
|
||||||
@ -67,6 +69,8 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
_startedAt = Time.realtimeSinceStartup;
|
_startedAt = Time.realtimeSinceStartup;
|
||||||
_baseVolume = Mathf.Clamp01(request.Volume);
|
_baseVolume = Mathf.Clamp01(request.Volume);
|
||||||
_pitch = request.Pitch <= 0f ? 1f : request.Pitch;
|
_pitch = request.Pitch <= 0f ? 1f : request.Pitch;
|
||||||
|
_fadeInDuration = request.FadeInSeconds > 0f ? request.FadeInSeconds : 0f;
|
||||||
|
_fadeInTimer = 0f;
|
||||||
_fadeDuration = request.FadeOutSeconds > 0f ? request.FadeOutSeconds : DefaultFadeOutSeconds;
|
_fadeDuration = request.FadeOutSeconds > 0f ? request.FadeOutSeconds : DefaultFadeOutSeconds;
|
||||||
_loop = request.Loop;
|
_loop = request.Loop;
|
||||||
_spatial = request.Spatial || request.FollowTarget != null || request.UseWorldPosition;
|
_spatial = request.Spatial || request.FollowTarget != null || request.UseWorldPosition;
|
||||||
@ -169,6 +173,22 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
UpdateFollowTarget();
|
UpdateFollowTarget();
|
||||||
UpdateOcclusion();
|
UpdateOcclusion();
|
||||||
|
|
||||||
|
if (_state == AudioAgentRuntimeState.FadingIn)
|
||||||
|
{
|
||||||
|
_fadeInTimer += deltaTime;
|
||||||
|
if (_fadeInTimer >= _fadeInDuration)
|
||||||
|
{
|
||||||
|
_state = AudioAgentRuntimeState.Playing;
|
||||||
|
ApplyRuntimeVolume(1f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float scale = _fadeInTimer / Mathf.Max(_fadeInDuration, MinFadeOutSeconds);
|
||||||
|
ApplyRuntimeVolume(scale);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_state == AudioAgentRuntimeState.Playing)
|
if (_state == AudioAgentRuntimeState.Playing)
|
||||||
{
|
{
|
||||||
if (!_loop && _source != null && !_source.isPlaying)
|
if (!_loop && _source != null && !_source.isPlaying)
|
||||||
@ -252,9 +272,20 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
|
|
||||||
_source.clip = clip;
|
_source.clip = clip;
|
||||||
_source.loop = _loop;
|
_source.loop = _loop;
|
||||||
ApplyRuntimeVolume(1f);
|
|
||||||
_source.Play();
|
if (_fadeInDuration > 0f)
|
||||||
|
{
|
||||||
|
_fadeInTimer = 0f;
|
||||||
|
_state = AudioAgentRuntimeState.FadingIn;
|
||||||
|
ApplyRuntimeVolume(0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_state = AudioAgentRuntimeState.Playing;
|
_state = AudioAgentRuntimeState.Playing;
|
||||||
|
ApplyRuntimeVolume(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
_source.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopImmediate(bool notifyCategory)
|
private void StopImmediate(bool notifyCategory)
|
||||||
@ -313,6 +344,8 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
_handle = 0;
|
_handle = 0;
|
||||||
_baseVolume = 1f;
|
_baseVolume = 1f;
|
||||||
_pitch = 1f;
|
_pitch = 1f;
|
||||||
|
_fadeInTimer = 0f;
|
||||||
|
_fadeInDuration = 0f;
|
||||||
_fadeTimer = 0f;
|
_fadeTimer = 0f;
|
||||||
_fadeDuration = 0f;
|
_fadeDuration = 0f;
|
||||||
_startedAt = 0f;
|
_startedAt = 0f;
|
||||||
|
|||||||
@ -6,6 +6,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
Loading = 1,
|
Loading = 1,
|
||||||
Playing = 2,
|
Playing = 2,
|
||||||
Paused = 3,
|
Paused = 3,
|
||||||
FadingOut = 4
|
FadingIn = 4,
|
||||||
|
FadingOut = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
|
using Cysharp.Text;
|
||||||
|
|
||||||
namespace AlicizaX.Audio.Runtime
|
namespace AlicizaX.Audio.Runtime
|
||||||
{
|
{
|
||||||
@ -51,7 +52,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
_enabled = !config.Mute;
|
_enabled = !config.Mute;
|
||||||
|
|
||||||
MixerGroup = ResolveMixerGroup(audioMixer, config);
|
MixerGroup = ResolveMixerGroup(audioMixer, config);
|
||||||
InstanceRoot = new GameObject("Audio Category - " + Type).transform;
|
InstanceRoot = new GameObject(ZString.Concat("Audio Category - ", Type)).transform;
|
||||||
InstanceRoot.SetParent(service.InstanceRoot, false);
|
InstanceRoot.SetParent(service.InstanceRoot, false);
|
||||||
|
|
||||||
int capacity = config.AgentHelperCount;
|
int capacity = config.AgentHelperCount;
|
||||||
@ -321,7 +322,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
|
|
||||||
private static AudioMixerGroup ResolveMixerGroup(AudioMixer audioMixer, AudioGroupConfig config)
|
private static AudioMixerGroup ResolveMixerGroup(AudioMixer audioMixer, AudioGroupConfig config)
|
||||||
{
|
{
|
||||||
AudioMixerGroup[] groups = audioMixer.FindMatchingGroups("Master/" + config.AudioType);
|
AudioMixerGroup[] groups = audioMixer.FindMatchingGroups(ZString.Concat("Master/", config.AudioType));
|
||||||
if (groups != null && groups.Length > 0)
|
if (groups != null && groups.Length > 0)
|
||||||
{
|
{
|
||||||
return groups[0];
|
return groups[0];
|
||||||
|
|||||||
@ -9,7 +9,6 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
public sealed class AudioComponent : MonoBehaviour
|
public sealed class AudioComponent : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private AudioMixer m_AudioMixer;
|
[SerializeField] private AudioMixer m_AudioMixer;
|
||||||
[SerializeField] private Transform m_InstanceRoot;
|
|
||||||
[SerializeField] private AudioListener m_AudioListener;
|
[SerializeField] private AudioListener m_AudioListener;
|
||||||
[SerializeField] private AudioGroupConfigCollection m_AudioGroupConfigs;
|
[SerializeField] private AudioGroupConfigCollection m_AudioGroupConfigs;
|
||||||
|
|
||||||
@ -22,10 +21,13 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
EnsureInstanceRoot();
|
if (m_AudioMixer == null)
|
||||||
EnsureAudioMixer();
|
{
|
||||||
|
throw new GameFrameworkException("AudioMixer is not assigned. Please assign an AudioMixer in the inspector.");
|
||||||
|
}
|
||||||
|
|
||||||
AudioGroupConfig[] configs = m_AudioGroupConfigs != null ? m_AudioGroupConfigs.GroupConfigs : null;
|
AudioGroupConfig[] configs = m_AudioGroupConfigs != null ? m_AudioGroupConfigs.GroupConfigs : null;
|
||||||
_audioService.Initialize(configs, m_InstanceRoot, m_AudioMixer);
|
_audioService.Initialize(configs, transform, m_AudioMixer);
|
||||||
if (m_AudioListener != null)
|
if (m_AudioListener != null)
|
||||||
{
|
{
|
||||||
_audioService.RegisterListener(m_AudioListener);
|
_audioService.RegisterListener(m_AudioListener);
|
||||||
@ -47,26 +49,5 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
_audioService.UnregisterListener(m_AudioListener);
|
_audioService.UnregisterListener(m_AudioListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureInstanceRoot()
|
|
||||||
{
|
|
||||||
if (m_InstanceRoot != null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_InstanceRoot = new GameObject("[AudioService Instances]").transform;
|
|
||||||
m_InstanceRoot.SetParent(transform, false);
|
|
||||||
m_InstanceRoot.localScale = Vector3.one;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureAudioMixer()
|
|
||||||
{
|
|
||||||
if (m_AudioMixer == null)
|
|
||||||
{
|
|
||||||
m_AudioMixer = Resources.Load<AudioMixer>("AudioMixer");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
public float MaxDistance;
|
public float MaxDistance;
|
||||||
public AudioRolloffMode RolloffMode;
|
public AudioRolloffMode RolloffMode;
|
||||||
public bool OverrideSpatialSettings;
|
public bool OverrideSpatialSettings;
|
||||||
|
public float FadeInSeconds;
|
||||||
public float FadeOutSeconds;
|
public float FadeOutSeconds;
|
||||||
|
|
||||||
public AudioPlayRequest()
|
public AudioPlayRequest()
|
||||||
@ -157,6 +158,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
MaxDistance = 500f;
|
MaxDistance = 500f;
|
||||||
RolloffMode = AudioRolloffMode.Logarithmic;
|
RolloffMode = AudioRolloffMode.Logarithmic;
|
||||||
OverrideSpatialSettings = false;
|
OverrideSpatialSettings = false;
|
||||||
|
FadeInSeconds = 0f;
|
||||||
FadeOutSeconds = 0.15f;
|
FadeOutSeconds = 0.15f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using AlicizaX.Resource.Runtime;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
using YooAsset;
|
using YooAsset;
|
||||||
|
using Cysharp.Text;
|
||||||
|
|
||||||
namespace AlicizaX.Audio.Runtime
|
namespace AlicizaX.Audio.Runtime
|
||||||
{
|
{
|
||||||
@ -31,6 +32,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
private readonly bool[] _categoryEnables = new bool[(int)AudioType.Max];
|
private readonly bool[] _categoryEnables = new bool[(int)AudioType.Max];
|
||||||
private readonly Dictionary<string, AudioClipCacheEntry> _clipCache = new Dictionary<string, AudioClipCacheEntry>(DefaultCacheCapacity, StringComparer.Ordinal);
|
private readonly Dictionary<string, AudioClipCacheEntry> _clipCache = new Dictionary<string, AudioClipCacheEntry>(DefaultCacheCapacity, StringComparer.Ordinal);
|
||||||
private readonly AudioSourceObject[][] _sourceObjects = new AudioSourceObject[(int)AudioType.Max][];
|
private readonly AudioSourceObject[][] _sourceObjects = new AudioSourceObject[(int)AudioType.Max][];
|
||||||
|
private readonly Dictionary<AudioType, AudioGroupConfig> _configMap = new Dictionary<AudioType, AudioGroupConfig>((int)AudioType.Max);
|
||||||
|
|
||||||
private IResourceService _resourceService;
|
private IResourceService _resourceService;
|
||||||
private IObjectPool<AudioSourceObject> _sourcePool;
|
private IObjectPool<AudioSourceObject> _sourcePool;
|
||||||
@ -109,18 +111,41 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
{
|
{
|
||||||
Shutdown(false);
|
Shutdown(false);
|
||||||
|
|
||||||
_resourceService = AppServices.Require<IResourceService>();
|
|
||||||
IObjectPoolService objectPoolService = AppServices.Require<IObjectPoolService>();
|
|
||||||
_sourcePool = objectPoolService.HasObjectPool<AudioSourceObject>(SourcePoolName)
|
|
||||||
? objectPoolService.GetObjectPool<AudioSourceObject>(SourcePoolName)
|
|
||||||
: objectPoolService.CreatePool<AudioSourceObject>(new ObjectPoolCreateOptions(SourcePoolName, false, 10f, int.MaxValue, float.MaxValue, 10));
|
|
||||||
|
|
||||||
if (audioGroupConfigs == null || audioGroupConfigs.Length == 0)
|
if (audioGroupConfigs == null || audioGroupConfigs.Length == 0)
|
||||||
{
|
{
|
||||||
throw new GameFrameworkException("AudioGroupConfig[] is invalid.");
|
throw new GameFrameworkException("AudioGroupConfig[] is invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_configs = audioGroupConfigs;
|
_configs = audioGroupConfigs;
|
||||||
|
BuildConfigMap();
|
||||||
|
|
||||||
|
InitializeObjectPools();
|
||||||
|
InitializeInstanceRoot(instanceRoot);
|
||||||
|
InitializeAudioMixer(audioMixer);
|
||||||
|
|
||||||
|
if (_unityAudioDisabled)
|
||||||
|
{
|
||||||
|
_initialized = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeHandleSystem();
|
||||||
|
InitializeCategories();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeObjectPools()
|
||||||
|
{
|
||||||
|
_resourceService = AppServices.Require<IResourceService>();
|
||||||
|
IObjectPoolService objectPoolService = AppServices.Require<IObjectPoolService>();
|
||||||
|
_sourcePool = objectPoolService.HasObjectPool<AudioSourceObject>(SourcePoolName)
|
||||||
|
? objectPoolService.GetObjectPool<AudioSourceObject>(SourcePoolName)
|
||||||
|
: objectPoolService.CreatePool<AudioSourceObject>(new ObjectPoolCreateOptions(SourcePoolName, false, 10f, int.MaxValue, float.MaxValue, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeInstanceRoot(Transform instanceRoot)
|
||||||
|
{
|
||||||
if (instanceRoot != null)
|
if (instanceRoot != null)
|
||||||
{
|
{
|
||||||
_instanceRoot = instanceRoot;
|
_instanceRoot = instanceRoot;
|
||||||
@ -138,20 +163,25 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
{
|
{
|
||||||
UnityEngine.Object.DontDestroyOnLoad(_instanceRoot.gameObject);
|
UnityEngine.Object.DontDestroyOnLoad(_instanceRoot.gameObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeAudioMixer(AudioMixer audioMixer)
|
||||||
|
{
|
||||||
_unityAudioDisabled = IsUnityAudioDisabled();
|
_unityAudioDisabled = IsUnityAudioDisabled();
|
||||||
if (_unityAudioDisabled)
|
if (_unityAudioDisabled)
|
||||||
{
|
{
|
||||||
_initialized = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_audioMixer = audioMixer != null ? audioMixer : Resources.Load<AudioMixer>("AudioMixer");
|
_audioMixer = audioMixer;
|
||||||
if (_audioMixer == null)
|
if (_audioMixer == null)
|
||||||
{
|
{
|
||||||
throw new GameFrameworkException("AudioMixer is invalid.");
|
throw new GameFrameworkException("AudioMixer is invalid. Please provide a valid AudioMixer.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeHandleSystem()
|
||||||
|
{
|
||||||
int totalAgentCount = 0;
|
int totalAgentCount = 0;
|
||||||
for (int i = 0; i < (int)AudioType.Max; i++)
|
for (int i = 0; i < (int)AudioType.Max; i++)
|
||||||
{
|
{
|
||||||
@ -169,7 +199,10 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
MemoryPool.Add<AudioPlayRequest>(totalAgentCount);
|
MemoryPool.Add<AudioPlayRequest>(totalAgentCount);
|
||||||
MemoryPool.Add<AudioLoadRequest>(totalAgentCount);
|
MemoryPool.Add<AudioLoadRequest>(totalAgentCount);
|
||||||
MemoryPool.Add<AudioClipCacheEntry>(_clipCacheCapacity);
|
MemoryPool.Add<AudioClipCacheEntry>(_clipCacheCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeCategories()
|
||||||
|
{
|
||||||
int globalIndexOffset = 0;
|
int globalIndexOffset = 0;
|
||||||
for (int i = 0; i < (int)AudioType.Max; i++)
|
for (int i = 0; i < (int)AudioType.Max; i++)
|
||||||
{
|
{
|
||||||
@ -186,8 +219,6 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
globalIndexOffset += config.AgentHelperCount;
|
globalIndexOffset += config.AgentHelperCount;
|
||||||
ApplyMixerVolume(config, _categoryVolumes[i], _categoryEnables[i]);
|
ApplyMixerVolume(config, _categoryVolumes[i], _categoryEnables[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
@ -439,12 +470,17 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void ClearCache()
|
public void ClearCache()
|
||||||
|
{
|
||||||
|
ClearCache(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearCache(bool force)
|
||||||
{
|
{
|
||||||
AudioClipCacheEntry entry = _allHead;
|
AudioClipCacheEntry entry = _allHead;
|
||||||
while (entry != null)
|
while (entry != null)
|
||||||
{
|
{
|
||||||
AudioClipCacheEntry next = entry.AllNext;
|
AudioClipCacheEntry next = entry.AllNext;
|
||||||
if (entry.RefCount <= 0 && !entry.Loading && entry.PendingHead == null)
|
if (force || (entry.RefCount <= 0 && !entry.Loading && entry.PendingHead == null))
|
||||||
{
|
{
|
||||||
RemoveClipEntry(entry);
|
RemoveClipEntry(entry);
|
||||||
}
|
}
|
||||||
@ -1073,7 +1109,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
|
|
||||||
private static string BuildSourceName(int typeIndex, int index)
|
private static string BuildSourceName(int typeIndex, int index)
|
||||||
{
|
{
|
||||||
return "AudioSource_" + typeIndex + "_" + index;
|
return ZString.Concat("AudioSource_", typeIndex, "_", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AudioGroupConfig GetConfig(AudioType type)
|
private AudioGroupConfig GetConfig(AudioType type)
|
||||||
@ -1087,23 +1123,27 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
return FindConfig(type);
|
return FindConfig(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AudioGroupConfig FindConfig(AudioType type)
|
private void BuildConfigMap()
|
||||||
{
|
{
|
||||||
|
_configMap.Clear();
|
||||||
if (_configs == null)
|
if (_configs == null)
|
||||||
{
|
{
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _configs.Length; i++)
|
for (int i = 0; i < _configs.Length; i++)
|
||||||
{
|
{
|
||||||
AudioGroupConfig config = _configs[i];
|
AudioGroupConfig config = _configs[i];
|
||||||
if (config != null && config.AudioType == type)
|
if (config != null)
|
||||||
{
|
{
|
||||||
return config;
|
_configMap[config.AudioType] = config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
private AudioGroupConfig FindConfig(AudioType type)
|
||||||
|
{
|
||||||
|
return _configMap.TryGetValue(type, out AudioGroupConfig config) ? config : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CountActiveAgents()
|
private int CountActiveAgents()
|
||||||
@ -1143,7 +1183,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearCache();
|
ClearCache(true);
|
||||||
if (_sourcePool != null)
|
if (_sourcePool != null)
|
||||||
{
|
{
|
||||||
_sourcePool.ReleaseAllUnused();
|
_sourcePool.ReleaseAllUnused();
|
||||||
@ -1153,6 +1193,7 @@ namespace AlicizaX.Audio.Runtime
|
|||||||
Array.Clear(_handleGenerations, 0, _handleGenerations.Length);
|
Array.Clear(_handleGenerations, 0, _handleGenerations.Length);
|
||||||
_handleAgents = Array.Empty<AudioAgent>();
|
_handleAgents = Array.Empty<AudioAgent>();
|
||||||
_handleGenerations = Array.Empty<uint>();
|
_handleGenerations = Array.Empty<uint>();
|
||||||
|
_configMap.Clear();
|
||||||
_resourceService = null;
|
_resourceService = null;
|
||||||
_sourcePool = null;
|
_sourcePool = null;
|
||||||
_audioMixer = null;
|
_audioMixer = null;
|
||||||
|
|||||||
@ -61,6 +61,25 @@ AudioMixerGroupController:
|
|||||||
m_Mute: 0
|
m_Mute: 0
|
||||||
m_Solo: 0
|
m_Solo: 0
|
||||||
m_BypassEffects: 0
|
m_BypassEffects: 0
|
||||||
|
--- !u!243 &-6728185375074428080
|
||||||
|
AudioMixerGroupController:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Ambient - 2
|
||||||
|
m_AudioMixer: {fileID: 24100000}
|
||||||
|
m_GroupID: df8234ed398782540a4972841dfd6079
|
||||||
|
m_Children: []
|
||||||
|
m_Volume: 9d25aae74848d51418de553067dd0f0b
|
||||||
|
m_Pitch: 2018eb0e2888cff44bf523ce3d06fd0b
|
||||||
|
m_Send: 00000000000000000000000000000000
|
||||||
|
m_Effects:
|
||||||
|
- {fileID: -2815600738436590526}
|
||||||
|
m_UserColorIndex: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_Solo: 0
|
||||||
|
m_BypassEffects: 0
|
||||||
--- !u!243 &-6280614258348125054
|
--- !u!243 &-6280614258348125054
|
||||||
AudioMixerGroupController:
|
AudioMixerGroupController:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -80,6 +99,25 @@ AudioMixerGroupController:
|
|||||||
m_Mute: 0
|
m_Mute: 0
|
||||||
m_Solo: 0
|
m_Solo: 0
|
||||||
m_BypassEffects: 0
|
m_BypassEffects: 0
|
||||||
|
--- !u!243 &-5751393387862637061
|
||||||
|
AudioMixerGroupController:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Ambient - 1
|
||||||
|
m_AudioMixer: {fileID: 24100000}
|
||||||
|
m_GroupID: 221f1da294156a3418168c39f16ae139
|
||||||
|
m_Children: []
|
||||||
|
m_Volume: 3a4c4abef80a7d74090c4558f2efbe8c
|
||||||
|
m_Pitch: bade8e01a57417d49bccd39245648de8
|
||||||
|
m_Send: 00000000000000000000000000000000
|
||||||
|
m_Effects:
|
||||||
|
- {fileID: 588078238856344238}
|
||||||
|
m_UserColorIndex: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_Solo: 0
|
||||||
|
m_BypassEffects: 0
|
||||||
--- !u!244 &-4958177229083455073
|
--- !u!244 &-4958177229083455073
|
||||||
AudioMixerEffectController:
|
AudioMixerEffectController:
|
||||||
m_ObjectHideFlags: 3
|
m_ObjectHideFlags: 3
|
||||||
@ -94,6 +132,25 @@ AudioMixerEffectController:
|
|||||||
m_SendTarget: {fileID: 0}
|
m_SendTarget: {fileID: 0}
|
||||||
m_EnableWetMix: 0
|
m_EnableWetMix: 0
|
||||||
m_Bypass: 0
|
m_Bypass: 0
|
||||||
|
--- !u!243 &-4470511876276122591
|
||||||
|
AudioMixerGroupController:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Ambient - 3
|
||||||
|
m_AudioMixer: {fileID: 24100000}
|
||||||
|
m_GroupID: 62ab3b1c1e1517f4892acd6bbf63325e
|
||||||
|
m_Children: []
|
||||||
|
m_Volume: ae513375e8726984d88a822dcc805a47
|
||||||
|
m_Pitch: c670d6f9426d69c439bed5c1581cf095
|
||||||
|
m_Send: 00000000000000000000000000000000
|
||||||
|
m_Effects:
|
||||||
|
- {fileID: 4372151859782775079}
|
||||||
|
m_UserColorIndex: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_Solo: 0
|
||||||
|
m_BypassEffects: 0
|
||||||
--- !u!243 &-4372808504093502661
|
--- !u!243 &-4372808504093502661
|
||||||
AudioMixerGroupController:
|
AudioMixerGroupController:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -186,6 +243,43 @@ AudioMixerGroupController:
|
|||||||
m_Mute: 0
|
m_Mute: 0
|
||||||
m_Solo: 0
|
m_Solo: 0
|
||||||
m_BypassEffects: 0
|
m_BypassEffects: 0
|
||||||
|
--- !u!243 &-3339031547535134654
|
||||||
|
AudioMixerGroupController:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Ambient
|
||||||
|
m_AudioMixer: {fileID: 24100000}
|
||||||
|
m_GroupID: eea06a873d29c174d9b93c8a87f28f29
|
||||||
|
m_Children:
|
||||||
|
- {fileID: -1635570523224726303}
|
||||||
|
- {fileID: -5751393387862637061}
|
||||||
|
- {fileID: -6728185375074428080}
|
||||||
|
- {fileID: -4470511876276122591}
|
||||||
|
m_Volume: 41dabee1ece434b46b30b1bf6008f4eb
|
||||||
|
m_Pitch: fef56cb47e7fcb845ae02cd29b60365e
|
||||||
|
m_Send: 00000000000000000000000000000000
|
||||||
|
m_Effects:
|
||||||
|
- {fileID: -1709768828366853691}
|
||||||
|
m_UserColorIndex: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_Solo: 0
|
||||||
|
m_BypassEffects: 0
|
||||||
|
--- !u!244 &-2815600738436590526
|
||||||
|
AudioMixerEffectController:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Attenuation
|
||||||
|
m_EffectID: 89fdfdacd88dd56428258e46d756e1ea
|
||||||
|
m_EffectName: Attenuation
|
||||||
|
m_MixLevel: c67a0995f8d7b524ba49eeeca5216f58
|
||||||
|
m_Parameters: []
|
||||||
|
m_SendTarget: {fileID: 0}
|
||||||
|
m_EnableWetMix: 0
|
||||||
|
m_Bypass: 0
|
||||||
--- !u!243 &-2659745067392564156
|
--- !u!243 &-2659745067392564156
|
||||||
AudioMixerGroupController:
|
AudioMixerGroupController:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -219,6 +313,20 @@ AudioMixerEffectController:
|
|||||||
m_SendTarget: {fileID: 0}
|
m_SendTarget: {fileID: 0}
|
||||||
m_EnableWetMix: 0
|
m_EnableWetMix: 0
|
||||||
m_Bypass: 0
|
m_Bypass: 0
|
||||||
|
--- !u!244 &-1709768828366853691
|
||||||
|
AudioMixerEffectController:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name:
|
||||||
|
m_EffectID: 65bb23c9d872c5347a34674e11b855f2
|
||||||
|
m_EffectName: Attenuation
|
||||||
|
m_MixLevel: eeea8e411d955da479365f63ad7834fd
|
||||||
|
m_Parameters: []
|
||||||
|
m_SendTarget: {fileID: 0}
|
||||||
|
m_EnableWetMix: 0
|
||||||
|
m_Bypass: 0
|
||||||
--- !u!243 &-1649243360580130678
|
--- !u!243 &-1649243360580130678
|
||||||
AudioMixerGroupController:
|
AudioMixerGroupController:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -238,6 +346,39 @@ AudioMixerGroupController:
|
|||||||
m_Mute: 0
|
m_Mute: 0
|
||||||
m_Solo: 0
|
m_Solo: 0
|
||||||
m_BypassEffects: 0
|
m_BypassEffects: 0
|
||||||
|
--- !u!243 &-1635570523224726303
|
||||||
|
AudioMixerGroupController:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Ambient - 0
|
||||||
|
m_AudioMixer: {fileID: 24100000}
|
||||||
|
m_GroupID: dfba3d60853b22649ac844b8e925e0f6
|
||||||
|
m_Children: []
|
||||||
|
m_Volume: d292610df4aee5543b1124a0f1048e76
|
||||||
|
m_Pitch: 2d28f5f5a88e080488060323fd5d5d55
|
||||||
|
m_Send: 00000000000000000000000000000000
|
||||||
|
m_Effects:
|
||||||
|
- {fileID: -1114540582412186105}
|
||||||
|
m_UserColorIndex: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_Solo: 0
|
||||||
|
m_BypassEffects: 0
|
||||||
|
--- !u!244 &-1114540582412186105
|
||||||
|
AudioMixerEffectController:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name:
|
||||||
|
m_EffectID: 10f22744f37e0a143adcb17b39acf14a
|
||||||
|
m_EffectName: Attenuation
|
||||||
|
m_MixLevel: c4b8d05d2d796eb46b9288ae6451e044
|
||||||
|
m_Parameters: []
|
||||||
|
m_SendTarget: {fileID: 0}
|
||||||
|
m_EnableWetMix: 0
|
||||||
|
m_Bypass: 0
|
||||||
--- !u!244 &-998299258853400712
|
--- !u!244 &-998299258853400712
|
||||||
AudioMixerEffectController:
|
AudioMixerEffectController:
|
||||||
m_ObjectHideFlags: 3
|
m_ObjectHideFlags: 3
|
||||||
@ -359,6 +500,11 @@ AudioMixerController:
|
|||||||
- e012b6d2e0501df43a88eb6beff8ae07
|
- e012b6d2e0501df43a88eb6beff8ae07
|
||||||
- e84c25a476798ea43a2f6de217af7dba
|
- e84c25a476798ea43a2f6de217af7dba
|
||||||
- 98657376d4096a947953ee04d82830c1
|
- 98657376d4096a947953ee04d82830c1
|
||||||
|
- eea06a873d29c174d9b93c8a87f28f29
|
||||||
|
- dfba3d60853b22649ac844b8e925e0f6
|
||||||
|
- 221f1da294156a3418168c39f16ae139
|
||||||
|
- df8234ed398782540a4972841dfd6079
|
||||||
|
- 62ab3b1c1e1517f4892acd6bbf63325e
|
||||||
name: View
|
name: View
|
||||||
m_CurrentViewIndex: 0
|
m_CurrentViewIndex: 0
|
||||||
m_TargetSnapshot: {fileID: 24500006}
|
m_TargetSnapshot: {fileID: 24500006}
|
||||||
@ -376,6 +522,7 @@ AudioMixerGroupController:
|
|||||||
- {fileID: 7235523536312936115}
|
- {fileID: 7235523536312936115}
|
||||||
- {fileID: 7185772616558441635}
|
- {fileID: 7185772616558441635}
|
||||||
- {fileID: -3395020342500439107}
|
- {fileID: -3395020342500439107}
|
||||||
|
- {fileID: -3339031547535134654}
|
||||||
m_Volume: ba83e724007d7e9459f157db3a54a741
|
m_Volume: ba83e724007d7e9459f157db3a54a741
|
||||||
m_Pitch: a2d2b77391464bb4887f0bcd3835015b
|
m_Pitch: a2d2b77391464bb4887f0bcd3835015b
|
||||||
m_Send: 00000000000000000000000000000000
|
m_Send: 00000000000000000000000000000000
|
||||||
@ -448,6 +595,20 @@ AudioMixerEffectController:
|
|||||||
m_SendTarget: {fileID: 0}
|
m_SendTarget: {fileID: 0}
|
||||||
m_EnableWetMix: 0
|
m_EnableWetMix: 0
|
||||||
m_Bypass: 0
|
m_Bypass: 0
|
||||||
|
--- !u!244 &588078238856344238
|
||||||
|
AudioMixerEffectController:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Attenuation
|
||||||
|
m_EffectID: fe69f682bd0b54a42a947db1c2b9c800
|
||||||
|
m_EffectName: Attenuation
|
||||||
|
m_MixLevel: ca7defaf1a72196439b28b45a8ca0dc6
|
||||||
|
m_Parameters: []
|
||||||
|
m_SendTarget: {fileID: 0}
|
||||||
|
m_EnableWetMix: 0
|
||||||
|
m_Bypass: 0
|
||||||
--- !u!244 &1413273517213151576
|
--- !u!244 &1413273517213151576
|
||||||
AudioMixerEffectController:
|
AudioMixerEffectController:
|
||||||
m_ObjectHideFlags: 3
|
m_ObjectHideFlags: 3
|
||||||
@ -533,6 +694,20 @@ AudioMixerGroupController:
|
|||||||
m_Mute: 0
|
m_Mute: 0
|
||||||
m_Solo: 0
|
m_Solo: 0
|
||||||
m_BypassEffects: 0
|
m_BypassEffects: 0
|
||||||
|
--- !u!244 &4372151859782775079
|
||||||
|
AudioMixerEffectController:
|
||||||
|
m_ObjectHideFlags: 3
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Attenuation
|
||||||
|
m_EffectID: 3519e333bc2088840ad9986fa50cde94
|
||||||
|
m_EffectName: Attenuation
|
||||||
|
m_MixLevel: 04a4d4239cebc9348a0e8e88df14e74c
|
||||||
|
m_Parameters: []
|
||||||
|
m_SendTarget: {fileID: 0}
|
||||||
|
m_EnableWetMix: 0
|
||||||
|
m_Bypass: 0
|
||||||
--- !u!244 &5734415080786067514
|
--- !u!244 &5734415080786067514
|
||||||
AudioMixerEffectController:
|
AudioMixerEffectController:
|
||||||
m_ObjectHideFlags: 3
|
m_ObjectHideFlags: 3
|
||||||
|
|||||||
200
Runtime/Debugger/DebuggerComponent.TimerInformationWindow.cs
Normal file
200
Runtime/Debugger/DebuggerComponent.TimerInformationWindow.cs
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
using AlicizaX.Timer.Runtime;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace AlicizaX.Debugger.Runtime
|
||||||
|
{
|
||||||
|
public sealed partial class DebuggerComponent
|
||||||
|
{
|
||||||
|
private sealed class TimerInformationWindow : ScrollableDebuggerWindowBase
|
||||||
|
{
|
||||||
|
private const int MAX_DISPLAY_COUNT = 50;
|
||||||
|
|
||||||
|
private struct RowView
|
||||||
|
{
|
||||||
|
public VisualElement Root;
|
||||||
|
public Label Title;
|
||||||
|
public Label Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITimerServiceDebugView m_TimerDebugView;
|
||||||
|
private TimerDebugInfo[] m_TimerInfos;
|
||||||
|
private Label m_SectionTitleLabel;
|
||||||
|
private Label m_ActiveCountLabel;
|
||||||
|
private Label m_PoolCapacityLabel;
|
||||||
|
private Label m_PeakCountLabel;
|
||||||
|
private Label m_FreeCountLabel;
|
||||||
|
private Label m_UsageLabel;
|
||||||
|
private Label m_WarningLabel;
|
||||||
|
private RowView m_EmptyRow;
|
||||||
|
private readonly RowView[] m_TimerRows = new RowView[MAX_DISPLAY_COUNT];
|
||||||
|
|
||||||
|
public override void Initialize(params object[] args)
|
||||||
|
{
|
||||||
|
m_TimerDebugView = AppServices.Require<ITimerService>() as ITimerServiceDebugView;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BuildWindow(VisualElement root)
|
||||||
|
{
|
||||||
|
if (m_TimerDebugView == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.Add(CreateActionButton("Refresh", RefreshContent, DebuggerTheme.ButtonSurfaceActive, DebuggerTheme.PrimaryText));
|
||||||
|
|
||||||
|
VisualElement overview = CreateSection("Timer Pool Overview", out VisualElement overviewCard);
|
||||||
|
m_ActiveCountLabel = AddTextRow(overviewCard, "Active Timer Count").Value;
|
||||||
|
m_PoolCapacityLabel = AddTextRow(overviewCard, "Pool Capacity").Value;
|
||||||
|
m_PeakCountLabel = AddTextRow(overviewCard, "Peak Active Count").Value;
|
||||||
|
m_FreeCountLabel = AddTextRow(overviewCard, "Free Count").Value;
|
||||||
|
m_UsageLabel = AddTextRow(overviewCard, "Pool Usage").Value;
|
||||||
|
root.Add(overview);
|
||||||
|
|
||||||
|
VisualElement section = CreateSection("Active Timers", out VisualElement timerCard);
|
||||||
|
m_SectionTitleLabel = section.ElementAt(0) as Label;
|
||||||
|
m_WarningLabel = new Label();
|
||||||
|
m_WarningLabel.style.color = new Color(1f, 0.5f, 0f);
|
||||||
|
m_WarningLabel.style.display = DisplayStyle.None;
|
||||||
|
m_WarningLabel.style.marginBottom = 4f;
|
||||||
|
timerCard.Add(m_WarningLabel);
|
||||||
|
|
||||||
|
m_EmptyRow = AddTextRow(timerCard, string.Empty);
|
||||||
|
m_EmptyRow.Root.style.display = DisplayStyle.None;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_DISPLAY_COUNT; i++)
|
||||||
|
{
|
||||||
|
m_TimerRows[i] = AddTextRow(timerCard, string.Empty);
|
||||||
|
m_TimerRows[i].Root.style.display = DisplayStyle.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.Add(section);
|
||||||
|
RefreshContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshContent()
|
||||||
|
{
|
||||||
|
if (m_TimerDebugView == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_TimerDebugView.GetStatistics(out int activeCount, out int poolCapacity, out int peakActiveCount, out int freeCount);
|
||||||
|
float poolUsage = poolCapacity > 0 ? (float)activeCount / poolCapacity : 0f;
|
||||||
|
|
||||||
|
m_ActiveCountLabel.text = activeCount.ToString();
|
||||||
|
m_PoolCapacityLabel.text = poolCapacity.ToString();
|
||||||
|
m_PeakCountLabel.text = peakActiveCount.ToString();
|
||||||
|
m_FreeCountLabel.text = freeCount.ToString();
|
||||||
|
m_UsageLabel.text = Utility.Text.Format("{0:P1}", poolUsage);
|
||||||
|
|
||||||
|
if (activeCount <= 0)
|
||||||
|
{
|
||||||
|
m_SectionTitleLabel.text = "Active Timers";
|
||||||
|
m_WarningLabel.style.display = DisplayStyle.None;
|
||||||
|
m_EmptyRow.Root.style.display = DisplayStyle.Flex;
|
||||||
|
m_EmptyRow.Title.text = "Status";
|
||||||
|
m_EmptyRow.Value.text = "No active timers";
|
||||||
|
SetTimerRowsVisible(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTimerInfoBuffer(activeCount);
|
||||||
|
int timerCount = m_TimerDebugView.GetAllTimers(m_TimerInfos);
|
||||||
|
int displayCount = timerCount > MAX_DISPLAY_COUNT ? MAX_DISPLAY_COUNT : timerCount;
|
||||||
|
|
||||||
|
m_SectionTitleLabel.text = Utility.Text.Format("Active Timers ({0})", timerCount);
|
||||||
|
m_EmptyRow.Root.style.display = DisplayStyle.None;
|
||||||
|
|
||||||
|
if (displayCount < timerCount)
|
||||||
|
{
|
||||||
|
m_WarningLabel.text = Utility.Text.Format("Showing first {0} timers of {1}.", displayCount, timerCount);
|
||||||
|
m_WarningLabel.style.display = DisplayStyle.Flex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_WarningLabel.style.display = DisplayStyle.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < displayCount; i++)
|
||||||
|
{
|
||||||
|
ref RowView row = ref m_TimerRows[i];
|
||||||
|
TimerDebugInfo info = m_TimerInfos[i];
|
||||||
|
row.Title.text = Utility.Text.Format("Timer #{0}", info.TimerId);
|
||||||
|
row.Value.text = Utility.Text.Format(
|
||||||
|
"{0} | {1} | {2} | Remaining: {3:F2}s | Duration: {4:F2}s",
|
||||||
|
info.IsLoop ? "Loop" : "Once",
|
||||||
|
info.IsRunning ? "Running" : "Paused",
|
||||||
|
info.IsUnscaled ? "Unscaled" : "Scaled",
|
||||||
|
info.LeftTime,
|
||||||
|
info.Duration);
|
||||||
|
row.Root.style.display = DisplayStyle.Flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTimerRowsVisible(displayCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetTimerRowsVisible(int visibleCount)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_DISPLAY_COUNT; i++)
|
||||||
|
{
|
||||||
|
m_TimerRows[i].Root.style.display = i < visibleCount ? DisplayStyle.Flex : DisplayStyle.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowView AddTextRow(VisualElement parent, string title)
|
||||||
|
{
|
||||||
|
float scale = DebuggerComponent.Instance != null ? DebuggerComponent.Instance.GetUiScale() : 1f;
|
||||||
|
VisualElement row = new VisualElement();
|
||||||
|
row.style.flexDirection = FlexDirection.Row;
|
||||||
|
row.style.alignItems = Align.Center;
|
||||||
|
row.style.minHeight = 36f * scale;
|
||||||
|
row.style.marginBottom = 4f * scale;
|
||||||
|
|
||||||
|
Label titleLabel = new Label(title);
|
||||||
|
titleLabel.style.minWidth = 280f * scale;
|
||||||
|
titleLabel.style.maxWidth = 280f * scale;
|
||||||
|
titleLabel.style.color = DebuggerTheme.SecondaryText;
|
||||||
|
titleLabel.style.fontSize = 18f * scale;
|
||||||
|
titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
|
||||||
|
titleLabel.style.flexShrink = 0f;
|
||||||
|
titleLabel.style.whiteSpace = WhiteSpace.Normal;
|
||||||
|
|
||||||
|
Label valueLabel = new Label();
|
||||||
|
valueLabel.style.flexGrow = 1f;
|
||||||
|
valueLabel.style.color = DebuggerTheme.PrimaryText;
|
||||||
|
valueLabel.style.fontSize = 18f * scale;
|
||||||
|
valueLabel.style.whiteSpace = WhiteSpace.Normal;
|
||||||
|
|
||||||
|
row.Add(titleLabel);
|
||||||
|
row.Add(valueLabel);
|
||||||
|
parent.Add(row);
|
||||||
|
|
||||||
|
RowView view;
|
||||||
|
view.Root = row;
|
||||||
|
view.Title = titleLabel;
|
||||||
|
view.Value = valueLabel;
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int EnsureTimerInfoBuffer(int count)
|
||||||
|
{
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
if (m_TimerInfos == null || m_TimerInfos.Length == 0)
|
||||||
|
{
|
||||||
|
m_TimerInfos = new TimerDebugInfo[1];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_TimerInfos == null || m_TimerInfos.Length < count)
|
||||||
|
{
|
||||||
|
m_TimerInfos = new TimerDebugInfo[count];
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8eac2550d41d14641b41a5c5523c4fde
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -93,6 +93,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
private ObjectPoolInformationWindow m_ObjectPoolInformationWindow = new ObjectPoolInformationWindow();
|
private ObjectPoolInformationWindow m_ObjectPoolInformationWindow = new ObjectPoolInformationWindow();
|
||||||
private ReferencePoolInformationWindow m_ReferencePoolInformationWindow = new ReferencePoolInformationWindow();
|
private ReferencePoolInformationWindow m_ReferencePoolInformationWindow = new ReferencePoolInformationWindow();
|
||||||
private AudioInformationWindow m_AudioInformationWindow = new AudioInformationWindow();
|
private AudioInformationWindow m_AudioInformationWindow = new AudioInformationWindow();
|
||||||
|
private TimerInformationWindow m_TimerInformationWindow = new TimerInformationWindow();
|
||||||
private SettingsWindow m_SettingsWindow = new SettingsWindow();
|
private SettingsWindow m_SettingsWindow = new SettingsWindow();
|
||||||
private FpsCounter m_FpsCounter;
|
private FpsCounter m_FpsCounter;
|
||||||
|
|
||||||
@ -502,6 +503,7 @@ namespace AlicizaX.Debugger.Runtime
|
|||||||
RegisterDebuggerWindow("Profiler/Object Pool", m_ObjectPoolInformationWindow);
|
RegisterDebuggerWindow("Profiler/Object Pool", m_ObjectPoolInformationWindow);
|
||||||
RegisterDebuggerWindow("Profiler/Reference Pool", m_ReferencePoolInformationWindow);
|
RegisterDebuggerWindow("Profiler/Reference Pool", m_ReferencePoolInformationWindow);
|
||||||
RegisterDebuggerWindow("Profiler/Audio", m_AudioInformationWindow);
|
RegisterDebuggerWindow("Profiler/Audio", m_AudioInformationWindow);
|
||||||
|
RegisterDebuggerWindow("Profiler/Timer", m_TimerInformationWindow);
|
||||||
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
|
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using AlicizaX.Localization.Runtime;
|
|||||||
using AlicizaX.ObjectPool;
|
using AlicizaX.ObjectPool;
|
||||||
using AlicizaX.Resource.Runtime;
|
using AlicizaX.Resource.Runtime;
|
||||||
using AlicizaX.Scene.Runtime;
|
using AlicizaX.Scene.Runtime;
|
||||||
|
using AlicizaX.Timer.Runtime;
|
||||||
using AlicizaX.UI.Runtime;
|
using AlicizaX.UI.Runtime;
|
||||||
|
|
||||||
public static partial class GameApp
|
public static partial class GameApp
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace AlicizaX
|
namespace AlicizaX.Timer.Runtime
|
||||||
{
|
{
|
||||||
[UnityEngine.Scripting.Preserve]
|
[UnityEngine.Scripting.Preserve]
|
||||||
public interface ITimerService : IService
|
public interface ITimerService : IService
|
||||||
{
|
{
|
||||||
int AddTimer(TimerHandler callback, float time, bool isLoop = false, bool isUnscaled = false, params object[] args);
|
|
||||||
int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false);
|
int AddTimer(TimerHandlerNoArgs callback, float time, bool isLoop = false, bool isUnscaled = false);
|
||||||
int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false);
|
int AddTimer<T>(Action<T> callback, T arg, float time, bool isLoop = false, bool isUnscaled = false) where T : class;
|
||||||
void Stop(int timerId);
|
void Stop(int timerId);
|
||||||
void Resume(int timerId);
|
void Resume(int timerId);
|
||||||
bool IsRunning(int timerId);
|
bool IsRunning(int timerId);
|
||||||
float GetLeftTime(int timerId);
|
float GetLeftTime(int timerId);
|
||||||
void Restart(int timerId);
|
void Restart(int timerId);
|
||||||
void RemoveTimer(int timerId);
|
void RemoveTimer(int timerId);
|
||||||
void RemoveAllTimer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
Runtime/Timer/ITimerServiceDebugView.cs
Normal file
27
Runtime/Timer/ITimerServiceDebugView.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace AlicizaX.Timer.Runtime
|
||||||
|
{
|
||||||
|
internal struct TimerDebugInfo
|
||||||
|
{
|
||||||
|
public int TimerId;
|
||||||
|
public float LeftTime;
|
||||||
|
public float Duration;
|
||||||
|
public bool IsLoop;
|
||||||
|
public bool IsRunning;
|
||||||
|
public bool IsUnscaled;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public float CreationTime;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface ITimerServiceDebugView
|
||||||
|
{
|
||||||
|
int GetAllTimers(TimerDebugInfo[] results);
|
||||||
|
|
||||||
|
void GetStatistics(out int activeCount, out int poolCapacity, out int peakActiveCount, out int freeCount);
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
int GetStaleOneShotTimers(TimerDebugInfo[] results);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Runtime/Timer/ITimerServiceDebugView.cs.meta
Normal file
11
Runtime/Timer/ITimerServiceDebugView.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5b7cf36ada40b944f8c506e3cd8ddd12
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -10,6 +10,11 @@ namespace AlicizaX.Timer.Runtime
|
|||||||
{
|
{
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
|
if (AppServices.TryGet<ITimerService>(out _))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AppServices.RegisterApp(new TimerService());
|
AppServices.RegisterApp(new TimerService());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,11 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 205d0803930745d7825f89aa604530a5
|
guid: 205d0803930745d7825f89aa604530a5
|
||||||
timeCreated: 1741683842
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AlicizaX;
|
using AlicizaX;
|
||||||
|
using AlicizaX.Timer.Runtime;
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
namespace AlicizaX.UI.Runtime
|
||||||
{
|
{
|
||||||
@ -46,8 +47,7 @@ namespace AlicizaX.UI.Runtime
|
|||||||
uiMetadata,
|
uiMetadata,
|
||||||
uiMetadata.MetaInfo.CacheTime,
|
uiMetadata.MetaInfo.CacheTime,
|
||||||
isLoop: false,
|
isLoop: false,
|
||||||
isUnscaled: true
|
isUnscaled: true);
|
||||||
);
|
|
||||||
|
|
||||||
if (timerId <= 0)
|
if (timerId <= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user