Skip to content

Commit

Permalink
#15: Add the possibility to skip the before and after events with sta…
Browse files Browse the repository at this point in the history
…te transitions.
  • Loading branch information
renggli committed Aug 2, 2023
1 parent dca2a68 commit ae507a0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
25 changes: 22 additions & 3 deletions lib/src/machine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,26 @@ class Machine<T> {
/// Errors during the transition phase are collected and included in the
/// event. Handlers can inspect and clear the errors. If any errors remain,
/// a single [TransitionError] is rethrown at the end of the state change.
set current(/*State<T>|T|Null*/ Object? state) {
set current(/*State<T>|T|Null*/ Object? state) => setCurrent(state);

/// Sets this machine to the given [state], either specified with a [State]
/// object, one of its identifiers, or `null` to remove the active state.
///
/// Throws an [ArgumentError], if the state is unknown or from a different
/// [Machine].
///
/// Triggers a [BeforeTransitionEvent] event before the transition starts,
/// unless [skipBeforeEvent] is set to `true`. This gives listeners the
/// opportunity to observe the transitions and possibly abort before it
/// starts.
///
/// Triggers an [AfterTransitionEvent] event after the transition completes,
/// unless [skipAfterEvent] is set to `true`. Errors during the transition
/// phase are collected and included in the event. Handlers can inspect and
/// clear the errors. If any errors remain, a single [TransitionError] is
/// rethrown at the end of the state change.
void setCurrent(/*State<T>|T|Null*/ Object? state,
{bool skipBeforeEvent = false, bool skipAfterEvent = false}) {
// Find and validate the target state.
final target = state is State<T>
? state
Expand All @@ -104,7 +123,7 @@ class Machine<T> {
// Notify listeners about the upcoming transition. Check if any of the
// listeners wish to abort the transition.
final source = _current;
if (_beforeTransitionController.hasListener) {
if (!skipBeforeEvent && _beforeTransitionController.hasListener) {
final transitionEvent = BeforeTransitionEvent<T>(this, source, target);
_beforeTransitionController.add(transitionEvent);
if (transitionEvent.isAborted) {
Expand Down Expand Up @@ -135,7 +154,7 @@ class Machine<T> {
}
}
// Notify listeners about the completed transition.
if (_afterTransitionController.hasListener) {
if (!skipAfterEvent && _afterTransitionController.hasListener) {
_afterTransitionController
.add(AfterTransitionEvent<T>(this, source, target, errors));
}
Expand Down
18 changes: 18 additions & 0 deletions test/statemachine_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -433,5 +433,23 @@ void main() {
machine.current = other;
expect(machine.current, exitAbort);
});
test('skip before/after event', () {
expectLater(
machine.onBeforeTransition,
emits(isBeforeTransitionEvent(
machine: machine,
source: other,
target: start,
)));
expectLater(
machine.onAfterTransition,
emits(isAfterTransitionEvent(
machine: machine,
source: start,
target: other,
)));
machine.setCurrent(other, skipBeforeEvent: true);
machine.setCurrent(start, skipAfterEvent: true);
});
});
}

0 comments on commit ae507a0

Please sign in to comment.