Stream of States

You can subscribe to a stream of StateOfMind objects from the StateMachine.

Each time the FSM transitions to a new state the stream will emit a StateOfMind which contains details of the new state(s) the FSM is in.

Remember that with Nested States or Concurrent Regions an FSM can be in multiple states at the same time.

The `StateOfMind` will contain a complete set of all States that reflect the StateMachine's current state.

Using a stream with a StreamBuilder:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'FSM2 Stream Builder sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  StateMachine machine;
  MyStatefulWidget({Key key}) : super(key: key)
  {
   machine = StateMachine.create((g) => g
    ..initialState(Solid())
    ..state<Solid>((b) => b
      ..on<OnMelted, Liquid>(
            sideEffect: (e) => print('Melted'),
          )))
   ));

}

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {

  Widget build(BuildContext context) {
    return DefaultTextStyle(
      style: Theme.of(context).textTheme.headline2,
      textAlign: TextAlign.center,
      child: Container(
        alignment: FractionalOffset.center,
        color: Colors.white,
        child: StreamBuilder<StateOfMind>(
          stream: machine.stream,
          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
            List<Widget> children;
            if (snapshot.hasError) {
              children = <Widget>[
                Icon(
                  Icons.error_outline,
                  color: Colors.red,
                  size: 60,
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text('Error: ${snapshot.error}'),
                )
              ];
            } else {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.waiting:
                  children = <Widget>[
                    Icon(
                      Icons.info,
                      color: Colors.blue,
                      size: 60,
                    ),
                    const Padding(
                      padding: EdgeInsets.only(top: 16),
                      child: Text('I lost my mind'),
                    )
                  ];
                  break;
               
                case ConnectionState.active:
                case ConnectionState.done:
                  children = <Widget>[
                    Icon(
                      Icons.info,
                      color: Colors.blue,
                      size: 60,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 16),
                      child: showState(snapshot.data),
                    )
                  ];
                  break;
              }
            }

            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: children,
            );
          },
        ),
      ),
    );
  }
  
  Widget showState(StateOfMind som)
  {
    var children = <Text>[];
    for (var stateType in som.currentStates)
    {
      children.add(Text(stateType));
    }
    return Column(children: children);
  }
}

Last updated