91 lines
2.3 KiB
Dart
91 lines
2.3 KiB
Dart
part of 'runtime_audio_manager.dart';
|
|
|
|
extension _RuntimeAudioManagerCache on RuntimeAudioManager {
|
|
void _releaseCachedAudio() {
|
|
_loadLimiter.clearPending();
|
|
for (final path in _audios.keys.toList(growable: false)) {
|
|
_removeAudioRecord(path);
|
|
}
|
|
|
|
_channels.clear();
|
|
final players = _players.toList(growable: false);
|
|
_players.clear();
|
|
final pooledPlayers = _sfxPool.toList(growable: false);
|
|
_sfxPool.clear();
|
|
for (final player in [...players, ...pooledPlayers]) {
|
|
player.dispose();
|
|
}
|
|
}
|
|
|
|
RuntimeAudioPlayer _takeSfxPlayer() {
|
|
if (_sfxPool.isNotEmpty) {
|
|
return _sfxPool.removeLast();
|
|
}
|
|
return _playerFactory();
|
|
}
|
|
|
|
Future<void> _releaseSfxPlayer(RuntimeAudioPlayer player) async {
|
|
if (_disposed || _sfxPool.length >= _maxSfxPoolSize) {
|
|
await player.dispose();
|
|
return;
|
|
}
|
|
_sfxPool.add(player);
|
|
}
|
|
|
|
void _touch(_AudioResourceRecord record) {
|
|
record.lastUsed = ++_accessCounter;
|
|
}
|
|
|
|
void _enforceAudioBudget() {
|
|
while (_isOverBudget()) {
|
|
final victim = _leastRecentlyUsedAudio();
|
|
if (victim == null || !_removeAudioRecord(victim)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool _isOverBudget() {
|
|
final maxBytes = _maxCacheBytes;
|
|
final maxEntries = _maxCacheEntries;
|
|
return (maxBytes != null && _cacheBytes > maxBytes) ||
|
|
(maxEntries != null && _readyAudioCount > maxEntries);
|
|
}
|
|
|
|
int get _readyAudioCount => _audios.values
|
|
.where((record) => record.state == GameResourceState.ready)
|
|
.length;
|
|
|
|
String? _leastRecentlyUsedAudio() {
|
|
String? victimPath;
|
|
_AudioResourceRecord? victim;
|
|
for (final entry in _audios.entries) {
|
|
final record = entry.value;
|
|
if (record.state != GameResourceState.ready) {
|
|
continue;
|
|
}
|
|
if (victim == null || record.lastUsed < victim.lastUsed) {
|
|
victim = record;
|
|
victimPath = entry.key;
|
|
}
|
|
}
|
|
return victimPath;
|
|
}
|
|
|
|
bool _removeAudioRecord(String path) {
|
|
final record = _audios.remove(path);
|
|
if (record == null) {
|
|
return false;
|
|
}
|
|
_cacheBytes -= record.bytes?.length ?? 0;
|
|
if (_cacheBytes < 0) {
|
|
_cacheBytes = 0;
|
|
}
|
|
record
|
|
..state = GameResourceState.disposed
|
|
..bytes = null
|
|
..inflight = null;
|
|
return true;
|
|
}
|
|
}
|