Initial flame_lua_runtime package
This commit is contained in:
90
lib/runtime/audio/runtime_audio_cache.dart
Normal file
90
lib/runtime/audio/runtime_audio_cache.dart
Normal file
@@ -0,0 +1,90 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user