mirror of https://github.com/flutter/pinball.git
feat: adding assets manager (#163)
parent
d7216bbe6d
commit
5fe5fc007d
@ -0,0 +1,27 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
part 'assets_manager_state.dart';
|
||||
|
||||
/// {@template assets_manager_cubit}
|
||||
/// Cubit responsable for pre loading any game assets
|
||||
/// {@endtemplate}
|
||||
class AssetsManagerCubit extends Cubit<AssetsManagerState> {
|
||||
/// {@macro assets_manager_cubit}
|
||||
AssetsManagerCubit(List<Future> loadables)
|
||||
: super(
|
||||
AssetsManagerState.initial(
|
||||
loadables: loadables,
|
||||
),
|
||||
);
|
||||
|
||||
/// Loads the assets
|
||||
Future<void> load() async {
|
||||
final all = state.loadables.map((loadable) async {
|
||||
await loadable;
|
||||
emit(state.copyWith(loaded: [...state.loaded, loadable]));
|
||||
}).toList();
|
||||
|
||||
await Future.wait(all);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
part of 'assets_manager_cubit.dart';
|
||||
|
||||
/// {@template assets_manager_state}
|
||||
/// State used to load the game assets
|
||||
/// {@endtemplate}
|
||||
class AssetsManagerState extends Equatable {
|
||||
/// {@macro assets_manager_state}
|
||||
const AssetsManagerState({
|
||||
required this.loadables,
|
||||
required this.loaded,
|
||||
});
|
||||
|
||||
/// {@macro assets_manager_state}
|
||||
const AssetsManagerState.initial({
|
||||
required List<Future> loadables,
|
||||
}) : this(loadables: loadables, loaded: const []);
|
||||
|
||||
/// List of futures to load
|
||||
final List<Future> loadables;
|
||||
|
||||
/// List of loaded futures
|
||||
final List<Future> loaded;
|
||||
|
||||
/// Returns a value between 0 and 1 to indicate the loading progress
|
||||
double get progress => loaded.length / loadables.length;
|
||||
|
||||
/// Returns a copy of this instance with the given parameters
|
||||
/// updated
|
||||
AssetsManagerState copyWith({
|
||||
List<Future>? loadables,
|
||||
List<Future>? loaded,
|
||||
}) {
|
||||
return AssetsManagerState(
|
||||
loadables: loadables ?? this.loadables,
|
||||
loaded: loaded ?? this.loaded,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [loaded, loadables];
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pinball/game/game.dart';
|
||||
|
||||
void main() {
|
||||
group('AssetsManagerCubit', () {
|
||||
final completer1 = Completer<void>();
|
||||
final completer2 = Completer<void>();
|
||||
|
||||
final future1 = completer1.future;
|
||||
final future2 = completer2.future;
|
||||
|
||||
blocTest<AssetsManagerCubit, AssetsManagerState>(
|
||||
'emits the loaded on the order that they load',
|
||||
build: () => AssetsManagerCubit([future1, future2]),
|
||||
act: (cubit) {
|
||||
cubit.load();
|
||||
completer2.complete();
|
||||
completer1.complete();
|
||||
},
|
||||
expect: () => [
|
||||
AssetsManagerState(
|
||||
loadables: [future1, future2],
|
||||
loaded: [future2],
|
||||
),
|
||||
AssetsManagerState(
|
||||
loadables: [future1, future2],
|
||||
loaded: [future2, future1],
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pinball/game/game.dart';
|
||||
|
||||
void main() {
|
||||
group('AssetsManagerState', () {
|
||||
test('can be instantiated', () {
|
||||
expect(
|
||||
AssetsManagerState(loadables: const [], loaded: const []),
|
||||
isNotNull,
|
||||
);
|
||||
});
|
||||
|
||||
test('has the correct initial state', () {
|
||||
final future = Future<void>.value();
|
||||
expect(
|
||||
AssetsManagerState.initial(loadables: [future]),
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: [future],
|
||||
loaded: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
group('progress', () {
|
||||
final future1 = Future<void>.value();
|
||||
final future2 = Future<void>.value();
|
||||
|
||||
test('returns 0 when no future is loaded', () {
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: [future1, future2],
|
||||
loaded: const [],
|
||||
).progress,
|
||||
equals(0),
|
||||
);
|
||||
});
|
||||
|
||||
test('returns the correct value when some of the futures are loaded', () {
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: [future1, future2],
|
||||
loaded: [future1],
|
||||
).progress,
|
||||
equals(0.5),
|
||||
);
|
||||
});
|
||||
|
||||
test('returns the 1 when all futures are loaded', () {
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: [future1, future2],
|
||||
loaded: [future1, future2],
|
||||
).progress,
|
||||
equals(1),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('copyWith', () {
|
||||
final future = Future<void>.value();
|
||||
|
||||
test('returns a copy with the updated loadables', () {
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: const [],
|
||||
).copyWith(loadables: [future]),
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: [future],
|
||||
loaded: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('returns a copy with the updated loaded', () {
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: const [],
|
||||
).copyWith(loaded: [future]),
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: [future],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('supports value comparison', () {
|
||||
final future1 = Future<void>.value();
|
||||
final future2 = Future<void>.value();
|
||||
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: const [],
|
||||
),
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: [future1],
|
||||
loaded: const [],
|
||||
),
|
||||
isNot(
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: [future2],
|
||||
loaded: const [],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: [future1],
|
||||
),
|
||||
isNot(
|
||||
equals(
|
||||
AssetsManagerState(
|
||||
loadables: const [],
|
||||
loaded: [future2],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in new issue