feat: implementing composable blueprints (#92)

* feat: implementing composable blueprints

* fix: coverage
pull/100/head
Erick 4 years ago committed by GitHub
parent cfd4e790fa
commit cf92856dc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,6 +14,8 @@ const _attachedErrorMessage = "Can't add to attached Blueprints";
/// the [FlameGame] level. /// the [FlameGame] level.
abstract class Blueprint<T extends FlameGame> { abstract class Blueprint<T extends FlameGame> {
final List<Component> _components = []; final List<Component> _components = [];
final List<Blueprint> _blueprints = [];
bool _isAttached = false; bool _isAttached = false;
/// Called before the the [Component]s managed /// Called before the the [Component]s managed
@ -25,7 +27,10 @@ abstract class Blueprint<T extends FlameGame> {
@mustCallSuper @mustCallSuper
Future<void> attach(T game) async { Future<void> attach(T game) async {
build(game); build(game);
await game.addAll(_components); await Future.wait([
game.addAll(_components),
..._blueprints.map(game.addFromBlueprint).toList(),
]);
_isAttached = true; _isAttached = true;
} }
@ -41,8 +46,23 @@ abstract class Blueprint<T extends FlameGame> {
_components.add(component); _components.add(component);
} }
/// Adds a list of [Blueprint]s to this blueprint.
void addAllBlueprints(List<Blueprint> blueprints) {
assert(!_isAttached, _attachedErrorMessage);
_blueprints.addAll(blueprints);
}
/// Adds a single [Blueprint] to this blueprint.
void addBlueprint(Blueprint blueprint) {
assert(!_isAttached, _attachedErrorMessage);
_blueprints.add(blueprint);
}
/// Returns a copy of the components built by this blueprint /// Returns a copy of the components built by this blueprint
List<Component> get components => List.unmodifiable(_components); List<Component> get components => List.unmodifiable(_components);
/// Returns a copy of the children blueprints
List<Blueprint> get blueprints => List.unmodifiable(_blueprints);
} }
/// A [Blueprint] that provides additional /// A [Blueprint] that provides additional

@ -14,6 +14,28 @@ class MyBlueprint extends Blueprint {
} }
} }
class MyOtherBlueprint extends Blueprint {
@override
void build(_) {
add(Component());
}
}
class YetMyOtherBlueprint extends Blueprint {
@override
void build(_) {
add(Component());
}
}
class MyComposedBlueprint extends Blueprint {
@override
void build(_) {
addBlueprint(MyBlueprint());
addAllBlueprints([MyOtherBlueprint(), YetMyOtherBlueprint()]);
}
}
class MyForge2dBlueprint extends Forge2DBlueprint { class MyForge2dBlueprint extends Forge2DBlueprint {
@override @override
void build(_) { void build(_) {
@ -24,12 +46,23 @@ class MyForge2dBlueprint extends Forge2DBlueprint {
void main() { void main() {
group('Blueprint', () { group('Blueprint', () {
setUpAll(() {
registerFallbackValue(MyBlueprint());
registerFallbackValue(Component());
});
test('components can be added to it', () { test('components can be added to it', () {
final blueprint = MyBlueprint()..build(MockPinballGame()); final blueprint = MyBlueprint()..build(MockPinballGame());
expect(blueprint.components.length, equals(3)); expect(blueprint.components.length, equals(3));
}); });
test('blueprints can be added to it', () {
final blueprint = MyComposedBlueprint()..build(MockPinballGame());
expect(blueprint.blueprints.length, equals(3));
});
test('adds the components to a game on attach', () { test('adds the components to a game on attach', () {
final mockGame = MockPinballGame(); final mockGame = MockPinballGame();
when(() => mockGame.addAll(any())).thenAnswer((_) async {}); when(() => mockGame.addAll(any())).thenAnswer((_) async {});
@ -38,6 +71,14 @@ void main() {
verify(() => mockGame.addAll(any())).called(1); verify(() => mockGame.addAll(any())).called(1);
}); });
test('adds components from a child Blueprint the to a game on attach', () {
final mockGame = MockPinballGame();
when(() => mockGame.addAll(any())).thenAnswer((_) async {});
MyComposedBlueprint().attach(mockGame);
verify(() => mockGame.addAll(any())).called(4);
});
test( test(
'throws assertion error when adding to an already attached blueprint', 'throws assertion error when adding to an already attached blueprint',
() async { () async {

Loading…
Cancel
Save