feat(flame_audio): Adding an easy way of updating the prefix from FlameAudio (#2751)

<!--
The title of your PR on the line above should start with a [Conventional
Commit] prefix
(`fix:`, `feat:`, `docs:`, `test:`, `chore:`, `refactor:`, `perf:`,
`build:`, `ci:`,
`style:`, `revert:`). This title will later become an entry in the
[CHANGELOG], so please
make sure that it summarizes the PR adequately.
-->

# Description
<!--
Provide a description of what this PR is doing.
If you're modifying existing behavior, describe the existing behavior,
how this PR is changing it,
and what motivated the change. If this is a breaking change, specify
explicitly which APIs were
changed.
-->

It was already possible to update the prefixes of FlameAudio assets, but
it required a certain understanding of `FlameAudio` and `Audioplayers`.

This PR adds a simple helper method that makes it easier to change
without requiring much context of the internals of the package.

## Checklist
<!--
Before you create this PR confirm that it meets all requirements listed
below by checking the
relevant checkboxes with `[x]`. If some checkbox is not applicable, mark
it as `[-]`.
-->

- [x] I have followed the [Contributor Guide] when preparing my PR.
- [x] I have updated/added tests for ALL new/updated/fixed
functionality.
- [ ] I have updated/added relevant documentation in `docs` and added
dartdoc comments with `///`.
- [ ] I have updated/added relevant examples in `examples` or `docs`.


## Breaking Change?
<!--
Would your PR require Flame users to update their apps following your
change?

If yes, then the title of the PR should include "!" (for example,
`feat!:`, `fix!:`). See
[Conventional Commit] for details. Also, for a breaking PR uncomment and
fill in the "Migration
instructions" section below.
-->

- [ ] Yes, this PR is a breaking change.
- [x] No, this PR is not a breaking change.

<!--
### Migration instructions

If the PR is breaking, uncomment this header and add instructions for
how to migrate from the
currently released version to the new proposed way.
-->

## Related Issues
<!--
Indicate which issues this PR resolves, if any. For example:

Closes #1234
!-->

<!-- Links -->
[Contributor Guide]:
https://github.com/flame-engine/flame/blob/main/CONTRIBUTING.md
[Conventional Commit]: https://conventionalcommits.org
[CHANGELOG]:
https://github.com/flame-engine/flame/blob/main/CHANGELOG.md
This commit is contained in:
Erick
2023-09-19 13:09:05 -03:00
committed by GitHub
parent 9c1e1c3098
commit d2c9dcecbe
3 changed files with 81 additions and 7 deletions

View File

@ -4,13 +4,46 @@ import 'package:flame_audio/bgm.dart';
export 'package:audioplayers/audioplayers.dart'; export 'package:audioplayers/audioplayers.dart';
/// A typedef for a function that creates an [AudioCache] instance.
typedef AudioCacheFactory = AudioCache Function({required String prefix});
/// A typedef for a function that creates a [Bgm] instance.
typedef BgmFactory = Bgm Function({required AudioCache audioCache});
/// This utility class holds static references to some global audio objects. /// This utility class holds static references to some global audio objects.
/// ///
/// You can use as a helper to very simply play a sound or a background music. /// You can use as a helper to very simply play a sound or a background music.
/// Alternatively you can create your own instances and control them yourself. /// Alternatively you can create your own instances and control them yourself.
class FlameAudio { class FlameAudio {
/// The factory used to create the global [AudioCache] instance.
///
/// Useful to override the default [AudioCache] constructor in testing
/// or edge cases where the developer needs control on how [AudioCache]
/// are created.
static AudioCacheFactory audioCacheFactory = AudioCache.new;
/// The factory used to create the global [Bgm] instance.
///
/// Useful to override the default [Bgm] constructor in testing
/// or edge cases where the developer needs control on how [Bgm]
/// are created.
static BgmFactory bgmFactory = Bgm.new;
/// Access a shared instance of the [AudioCache] class. /// Access a shared instance of the [AudioCache] class.
static AudioCache audioCache = AudioCache(prefix: 'assets/audio/'); static AudioCache audioCache = audioCacheFactory(
prefix: 'assets/audio/',
);
/// Access a shared instance of the [Bgm] class.
///
/// This will use the same global audio cache from [FlameAudio].
static final Bgm bgm = bgmFactory(audioCache: audioCache);
/// Updates the prefix in the global [AudioCache] and [bgm] instances.
static void updatePrefix(String prefix) {
audioCache.prefix = prefix;
bgm.audioPlayer.audioCache.prefix = prefix;
}
static Future<AudioPlayer> _preparePlayer( static Future<AudioPlayer> _preparePlayer(
String file, String file,
@ -74,11 +107,6 @@ class FlameAudio {
); );
} }
/// Access a shared instance of the [Bgm] class.
///
/// This will use the same global audio cache from [FlameAudio].
static final Bgm bgm = Bgm(audioCache: audioCache);
/// Creates a new Audio Pool using Flame's global Audio Cache. /// Creates a new Audio Pool using Flame's global Audio Cache.
static Future<AudioPool> createPool( static Future<AudioPool> createPool(
String sound, { String sound, {

View File

@ -21,4 +21,7 @@ dependencies:
dev_dependencies: dev_dependencies:
dartdoc: ^6.2.2 dartdoc: ^6.2.2
flame_lint: ^1.1.0 flame_lint: ^1.1.0
flutter_test:
sdk: flutter
mocktail: ^1.0.0

View File

@ -0,0 +1,43 @@
import 'package:flame_audio/bgm.dart';
import 'package:flame_audio/flame_audio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class _MockAudioCache extends Mock implements AudioCache {}
class _MockAudioPlayer extends Mock implements AudioPlayer {}
class _MockBgmCache extends Mock implements Bgm {}
void main() {
group('FlameAudio', () {
test('starts the audioCache with the default prefix', () {
expect(
FlameAudio.audioCache.prefix,
equals('assets/audio/'),
);
});
group('updatePrefix', () {
test('updates the prefix on both bgm and audioCache', () {
final audioCache = _MockAudioCache();
FlameAudio.audioCache = audioCache;
final bgm = _MockBgmCache();
final bgmAudioPlayer = _MockAudioPlayer();
when(() => bgm.audioPlayer).thenReturn(bgmAudioPlayer);
final bgmAudioCache = _MockAudioCache();
when(() => bgmAudioPlayer.audioCache).thenReturn(bgmAudioCache);
FlameAudio.bgmFactory = ({required AudioCache audioCache}) => bgm;
const newPrefix = 'newPrefix/';
FlameAudio.updatePrefix(newPrefix);
verify(() => audioCache.prefix = newPrefix).called(1);
verify(() => bgmAudioCache.prefix = newPrefix).called(1);
});
});
});
}