BLoC State Machine
An extension to the bloc state management library which lets you create State Machine using a declarative API.
Overview
state_machine_bloc
export a StateMachine
class, a new kind of bloc designed to declare state machines using a nice builder API. It can be used in the same way as Cubit
and Bloc
and it aims to be compatible with the rest of the ecosystem.
state_machine_bloc
supports:
- Storing data in states
- Defining state transitions based on event
- Applying guard conditions to transitions
- sideEffects
- onEnter/onExit
State machines shines is in their expressiveness, predictability, and robustness:
- This makes it easy to know all possible states of business logic
- They eliminate bugs and weird situations because they won't let the UI transition to a state which we donโt know about.
- This eliminates the need for code that protects other codes from execution because They do not accept input that is not explicitly defined as acceptable for the current state.
class Timer extends StateMachine<Event, State> { Timer() : super(Running()) { define<Running>((b) => b ..onEnter((Running currentState) => print("on enter running state")) ..on<Stopped>((Stopped event, Running currentState) => Paused()), ); define<Paused>((b) => b ..onExit((Running currentState) => print("on exit paused state")) ..on<Started>((Started event, Paused currentState) => Running()), ); } }
Additional ressources
- You are managing state? Think twice.
- The rise of state machine
- Robust React User Interfaces with Finite State Machines
Project Status
This project is very early and in active development. A basic Proof of Concept has been done so you can try it already. Any opinions, feedback, thought and contributions are welcome.
Roadmap
- PoC
- Make timer state machine example pass all original unit tests
- Implements more bloc's example and maybe try new one
- Define specs
- Write some documentation
- Alpha implementation
features to be explored
- nested states machines
- dedicated flutter builder/listener widgets
- make state machine usable with other library than bloc
Getting Started
Install
add this to your pubspec.yaml
state_machine_bloc:
git:
url: git@github.com:Pierre2tm/state_machine_bloc.git
path: packages/state_machine_bloc
then run flutter pub get
.
import the package
import 'package:state_machine_bloc/state_machine_bloc.dart'
Usage
Declare your StateMachine
:
timer.dart
import 'package:state_machine_bloc/state_machine_bloc.dart'; class Event {} class Started extends Event {} class Stopped extends Event {} class State {} class Running extends State {} class Paused extends State {} ```dart class Timer extends StateMachine<Event, State> { Timer() : super(Running()) { define<Running>((b) => b ..onEnter((Running currentState) => print("on enter running state")) ..on<Stopped>((Stopped event, Running currentState) => Paused()), ); define<Paused>((b) => b ..onExit((Running currentState) => print("on exit paused state")) ..on<Started>((Started event, Paused currentState) => Running()), ); } }
Then use it as a regular Bloc
:
timer_page.dart
BlocProvider(
create: (_) => Timer(ticker: Ticker()),
child: const TimerView(),
);
TODO: better examples TODO: detailed usage