part of 'runtime_audio_manager.dart'; extension _RuntimeAudioManagerLoading on RuntimeAudioManager { Future _loadAudio( String? keyOrPath, { required bool failOnError, }) { if (keyOrPath == null || keyOrPath.isEmpty) { return Future.value(null); } final requestToken = _asyncGate.token; final requestGeneration = requestToken.generation; final path = _tryResolve(keyOrPath); if (path == null) { return Future.value(null); } final existing = _audios[path]; if (existing != null) { final bytes = existing.bytes; if (existing.generation == requestGeneration && existing.state == GameResourceState.ready && bytes != null) { _touch(existing); return Future.value(bytes); } final inflight = existing.inflight; if (existing.generation == requestGeneration && inflight != null) { return failOnError ? _throwIfNull(inflight, keyOrPath) : inflight.catchError((_) => null); } } final record = _AudioResourceRecord(generation: requestGeneration) ..state = GameResourceState.loading; _audios[path] = record; final future = _readAudio(path, record, requestToken); record.inflight = future; return failOnError ? _throwIfNull(future, keyOrPath) : future; } Future _throwIfNull( Future future, String keyOrPath, ) async { final bytes = await future; if (bytes == null) { throw ResourceLoadException('Required audio resource failed: $keyOrPath'); } return bytes; } Future _readAudio( String path, _AudioResourceRecord record, RuntimeAsyncToken requestToken, ) async { try { final activePackage = _package; if (activePackage == null) { throw StateError('RuntimeAudioManager has no active package'); } final ownedBytes = await _loadLimiter.run(() async { final data = await activePackage.readBytes(path); final bytes = data.buffer.asUint8List( data.offsetInBytes, data.lengthInBytes, ); return Uint8List.fromList(bytes); }); record.inflight = null; if (_disposed || !_asyncGate.accepts(requestToken) || _audios[path] != record) { record.state = GameResourceState.disposed; return null; } record ..bytes = ownedBytes ..state = GameResourceState.ready ..lastError = null; _cacheBytes += ownedBytes.length; _touch(record); _enforceAudioBudget(); return ownedBytes; } catch (error) { record.inflight = null; if (_disposed || !_asyncGate.accepts(requestToken) || _audios[path] != record) { record.state = GameResourceState.disposed; return null; } record ..state = GameResourceState.failed ..lastError = error; _diagnostics?.record( type: RuntimeDiagnosticType.resourceLoadError, message: 'Audio resource failed to load', error: error, context: {'path': path, 'generation': requestToken.generation}, ); return null; } } String? _tryResolve(String keyOrPath) { try { final activePackage = _package; if (activePackage == null) { return null; } return activePackage.resolveResourcePath(keyOrPath); } catch (_) { return null; } } }