-
-
Notifications
You must be signed in to change notification settings - Fork 899
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
docs: Added documentation for GameLoop class #1234
Merged
Merged
Changes from 8 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
b120d7b
docs: Added documentation for GameLoop class
st-pasha 160301f
restore currentTime -> previous
st-pasha 6830290
Merge branch 'main' into ps/game-loop
st-pasha 838e72f
Deprecate pause and resume in GameLoop
st-pasha c4976b7
Merge branch 'main' into ps/game-loop
st-pasha 8626342
Merge branch 'ps/gameloop-pause-resume' into ps/game-loop
st-pasha 1f3b995
GameLoop.previous is now private
st-pasha 981d979
Merge branch 'ps/gameloop-pause-resume' into ps/game-loop
st-pasha 4efc1c4
Merge branch 'main' into ps/game-loop
st-pasha b6b6471
Merge branch 'main' into ps/game-loop
st-pasha 07fd1bb
Merge branch 'main' into ps/game-loop
spydon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,82 @@ | ||
import 'package:flutter/scheduler.dart'; | ||
|
||
/// Internal class that drives the game loop by calling the provided [callback] | ||
/// function on every Flutter animation frame. | ||
/// | ||
/// After creating a GameLoop, call `start()` in order to make it actually run. | ||
/// When a GameLoop object is no longer needed, it must be `dispose()`d. | ||
/// | ||
/// For example: | ||
/// ```dart | ||
/// final gameLoop = GameLoop(onGameLoopTick); | ||
/// gameLoop.start(); | ||
/// ... | ||
/// gameLoop.dispose(); | ||
/// ``` | ||
class GameLoop { | ||
void Function(double dt) callback; | ||
Duration previous = Duration.zero; | ||
late Ticker _ticker; | ||
|
||
GameLoop(this.callback) { | ||
_ticker = Ticker(_tick); | ||
} | ||
|
||
/// Function to be called on every Flutter rendering frame. | ||
/// | ||
/// This function takes a single parameter `dt`, which is the amount of time | ||
/// passed since the previous invocation of this function. The time is | ||
/// measured in seconds, with microsecond precision. The argument will be | ||
/// equal to 0 on first invocation of the callback. | ||
void Function(double dt) callback; | ||
|
||
/// Total amount of time passed since the game loop was started. | ||
/// | ||
/// This variable is updated on every rendering frame, just before the | ||
/// [callback] is invoked. It will be equal to zero while the game loop is | ||
/// stopped. It is also guaranteed to be equal to zero on the first invocation | ||
/// of the callback. | ||
Duration _previous = Duration.zero; | ||
|
||
/// Internal object responsible for periodically calling the [callback] | ||
/// function. | ||
late final Ticker _ticker; | ||
|
||
/// This method is periodically invoked by the [_ticker]. | ||
void _tick(Duration timestamp) { | ||
final dt = _computeDeltaT(timestamp); | ||
final durationDelta = timestamp - _previous; | ||
final dt = durationDelta.inMicroseconds / Duration.microsecondsPerSecond; | ||
_previous = timestamp; | ||
callback(dt); | ||
} | ||
|
||
double _computeDeltaT(Duration now) { | ||
final delta = previous == Duration.zero ? Duration.zero : now - previous; | ||
previous = now; | ||
return delta.inMicroseconds / Duration.microsecondsPerSecond; | ||
} | ||
|
||
/// Start running the game loop. The game loop is created in a paused state, | ||
/// so this must be called once in order to make the loop running. Calling | ||
/// this method again when the game loop already runs is a noop. | ||
void start() { | ||
_ticker.start(); | ||
if (!_ticker.isActive) { | ||
_ticker.start(); | ||
} | ||
} | ||
|
||
/// Stop the game loop. While it is stopped, the time "freezes". When the | ||
/// game loop is started again, the [callback] will NOT be made aware that | ||
/// any amount of time has passed. | ||
void stop() { | ||
_ticker.stop(); | ||
_previous = Duration.zero; | ||
} | ||
|
||
/// Call this before deleting the [GameLoop] object. | ||
/// | ||
/// The [GameLoop] will no longer be usable after this method is called. You | ||
/// do not have to stop the game loop before disposing of it. | ||
void dispose() { | ||
_ticker.dispose(); | ||
} | ||
|
||
void pause() { | ||
_ticker.muted = true; | ||
previous = Duration.zero; | ||
} | ||
@Deprecated('Internal variable') | ||
Duration get previous => _previous; | ||
|
||
void resume() { | ||
_ticker.muted = false; | ||
// If the game has started paused, we need to start the ticker | ||
// as it would not have been started yet | ||
if (!_ticker.isActive) { | ||
start(); | ||
} | ||
} | ||
@Deprecated('Use stop() instead') | ||
st-pasha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
void pause() => stop(); | ||
|
||
@Deprecated('Use start() instead') | ||
void resume() => start(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use
Deprecated
? There are specialized decorators for this likeProtected
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we don't use that variable anywhere. It was never intended to be public.
So, now that we make it private, the getter is provided in case anyone's code was reading that variable. The getter is marked deprecated, as a way to signal that this variable really shouldn't be used, and that the getter will be removed after a while.