Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add collision completed listener #2896

Merged

Conversation

christian-mindfulness
Copy link
Contributor

@christian-mindfulness christian-mindfulness commented Dec 2, 2023

Description

Add a new variable to the CollisionDetection class. Call notifyListeners at the end of the collision detection step, so that users can add a listener to their code to know when this step has finished. The variable is a basic implementation of a Listenable class, since it needs no more complexity.

Checklist

  • I have followed the Contributor Guide when preparing my PR.
  • 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?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

Closes #2849

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments, and missing tests

packages/flame/lib/src/collisions/collision_detection.dart Outdated Show resolved Hide resolved
packages/flame/lib/src/collisions/collision_detection.dart Outdated Show resolved Hide resolved
@@ -161,3 +166,24 @@ abstract class CollisionDetection<T extends Hitbox<T>,
List<RaycastResult<T>>? out,
});
}

/// Add a basic class which implements a Listener.
class CollisionDetectionCompletionNotifier implements Listenable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class CollisionDetectionCompletionNotifier implements Listenable {
class CollisionDetectionCompletionNotifier with ChangeNotifier {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to manually implement Listenable, check https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the suggestion to implement Listenable came from you, to avoid the warning about unnecessary overrides. Happy to do whichever you think best.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, now I remember. 🤦‍♂️
I think it is probably better to go with with ChangeNotifier anyways, so that we don't have to do the re-implementation, and then we can just put an ignore lint lint above the overridden method.

@christian-mindfulness
Copy link
Contributor Author

Some comments, and missing tests

I appreciate the need for tests, but the testing framework is very confusing to me. @spydon would you be able to suggest a change for this?

@spydon
Copy link
Member

spydon commented Dec 4, 2023

I appreciate the need for tests, but the testing framework is very confusing to me. @spydon would you be able to suggest a change for this?

Yeah, the collision detection tests can be a bit confusing, this one can be fairly simple though, something like this:

group('collisionsCompletedNotifier', {
  runCollisionTestRegistry({
    'collisionsCompletedNotifier calls listeners': (game) async {
      var calledTimes = 0;
      final listeners = List.generate(10, (_) => () => calledTimes++);
      for(final listener in listeners) {
        game.collisionDetection.collisionsCompletedNotifier.addListener(listener);
      }
      game.update(0);
  
      expect(calledTimes, listeners.length);
    },
  });
});

and then just adding that in the end of this file:
https://github.com/flame-engine/flame/blob/main/packages/flame/test/collisions/collision_callback_test.dart

@christian-mindfulness
Copy link
Contributor Author

...
and then just adding that in the end of this file: https://github.com/flame-engine/flame/blob/main/packages/flame/test/collisions/collision_callback_test.dart

Thanks. Done that and managed to get the test to run, but fails:
Expected: <10>
Actual: <0>
I think the code might be adding the listeners, but not running collision detection and so the counter is not incremented?

@spydon
Copy link
Member

spydon commented Dec 4, 2023

@christian-mindfulness did you add the game.update(0);? I forgot to add that at first.

@christian-mindfulness
Copy link
Contributor Author

@christian-mindfulness did you add the game.update(0);? I forgot to add that at first.

Thanks the one, thank you.

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few final comments

doc/flame/collision_detection.md Outdated Show resolved Hide resolved
doc/flame/collision_detection.md Outdated Show resolved Hide resolved
doc/flame/collision_detection.md Outdated Show resolved Hide resolved
doc/flame/collision_detection.md Outdated Show resolved Hide resolved
Comment on lines 149 to 152
(game as HasCollisionDetection).collisionDetection.collisionsCompletedNotifier.
addListener(() {
resolveCollisions();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to break the line (as it's too long otherwise). I've now done it in a way that looks nice to me, happy to hear your thoughts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you put it in an IDE and or https://dartpad.dev it will correctly format it for you, since it follows 80 width by default

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't get VScode, dartpad or tutorialspoint to do it automatically for me. :-(

packages/flame/lib/src/collisions/collision_detection.dart Outdated Show resolved Hide resolved
@christian-mindfulness
Copy link
Contributor Author

Thanks @spydon for the review. I think my latest commit addresses all the issues. Let me know if I've missed anything. I've also simplified the extension of ChangeNotifier to have an empty body, which avoids any warnings.

@spydon
Copy link
Member

spydon commented Dec 6, 2023

Thanks @spydon for the review. I think my latest commit addresses all the issues. Let me know if I've missed anything. I've also simplified the extension of ChangeNotifier to have an empty body, which avoids any warnings.

You have to override notifyListeners since super.notifyListeners isn't exposed, only for tests.

@christian-mindfulness
Copy link
Contributor Author

Thanks @spydon for the review. I think my latest commit addresses all the issues. Let me know if I've missed anything. I've also simplified the extension of ChangeNotifier to have an empty body, which avoids any warnings.

You have to override notifyListeners since super.notifyListeners isn't exposed, only for tests.

Curious that it worked for me - I've changed back.

@spydon
Copy link
Member

spydon commented Dec 6, 2023

Curious that it worked for me - I've changed back.

It works, but you get an analyzer warning. That was why the pipeline didn't pass.

Comment on lines 149 to 153
(game as HasCollisionDetection).collisionDetection
.collisionsCompletedNotifier
.addListener(() {
resolveCollisions();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(game as HasCollisionDetection).collisionDetection
.collisionsCompletedNotifier
.addListener(() {
resolveCollisions();
});
(game as HasCollisionDetection)
.collisionDetection
.collisionsCompletedNotifier
.addListener(() {
resolveCollisions();
});

This is the correct formatting

Copy link
Member

@spydon spydon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! :)

@spydon spydon enabled auto-merge (squash) December 6, 2023 21:44
@spydon spydon merged commit 957db3c into flame-engine:main Dec 6, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add listener for when collision detection has been completed
2 participants