post<M2> method

MessageActionDescriptor<M, D, C> post<M2>({
  1. FutureOr<M2> getMessage(
    1. MessageHandlerContext<M, D, C> ctx
    )?,
  2. M2? message,
  3. String? label,
})

Posts a new message to be processed by the state machine while a message is being handled.

If getMessage is provided, the function will be evaluated when the transition occurs, and the returned message will be posted. Otherwise a message must be provided.

class DoIt {}
class ItWasDone {}

ItWasDone onDoIt(MessageHandlerContext<DoItLater, void, void> ctx) {
  print('I did it');
  return ItWasDone();
}
void onItWasDone(MessageContext ctx, ItWasDone msg) => print('It was done');

var state1 = StateKey('s1');
var builder = StateTreeBuilder(initialState: state1);

builder.state(state1, (b) {
  // Handle DoIt message by posting a ItWasDone message for future processing
  b.onMessage<DoIt>((b) => b.stay(action: b.act.post(onDoIt)));
  // Handle ItWasDone message
  b.onMessage<ItWasDone>((b) => b.stay(action: b.act.run(onItWasDone)));
});

This action can be labeled when formatting a state tree by providing a label.

Implementation

MessageActionDescriptor<M, D, C> post<M2>({
  FutureOr<M2> Function(MessageHandlerContext<M, D, C> ctx)? getMessage,
  M2? message,
  String? label,
}) {
  if (getMessage == null && message == null) {
    throw ArgumentError('getMessage or message must be provided');
  } else if (getMessage != null && message != null) {
    throw ArgumentError('One of getMessage or message must be provided');
  }

  var _getMessage = getMessage ?? (_) => message!;
  var info = MessageActionInfo(ActionType.schedule, M2, null, label);
  return MessageActionDescriptor<M, D, C>(
    info,
    (ctx) => _getMessage(ctx).bind((msg) {
      _log.fine(() => "State '$_forState' is posting message of type $M2");
      ctx.messageContext.post(msg as Object);
    }),
  );
}