dispatch method

Cmd? dispatch(
  1. Msg msg
)

Dispatches a message through interception, children, then self handlers.

Implementation

Cmd? dispatch(Msg msg) {
  rebuild();

  if (msg is BackgroundColorMsg) {
    updateThemeFromBackground(msg.hex);
  }

  // --- 1. Interception Phase (Top-down) ---
  // Widgets can override handleIntercept to catch messages before children.
  Cmd? interceptCmd;
  if (this is StatefulElement) {
    interceptCmd = (this as StatefulElement).state.handleIntercept(msg);
  } else {
    final (newWidget, cmd) = widget.handleIntercept(msg);
    if (!identical(newWidget, widget)) {
      update(newWidget);
    }
    interceptCmd = cmd;
  }
  if (interceptCmd != null) return interceptCmd;

  // --- 2. Children Phase ---
  final cmds = <Cmd>[];
  final children = msg is KeyMsg ? _children.reversed : _children;
  for (final child in children) {
    final cmd = child.dispatch(msg);
    if (cmd != null) {
      // Keyboard events use a "one-winner" policy with bubbling.
      // If a child handled it, we stop propagation.
      if (msg is KeyMsg) return cmd;
      cmds.add(cmd);
    }
  }

  // --- 3. Self Phase (Bottom-up) ---
  Cmd? selfCmd;
  if (this is StatefulElement) {
    selfCmd = (this as StatefulElement).state.handleUpdate(msg);
  } else {
    final (newWidget, cmd) = widget.handleUpdate(msg);
    if (!identical(newWidget, widget)) {
      update(newWidget);
    }
    selfCmd = cmd;
  }

  if (selfCmd != null) {
    if (msg is KeyMsg) return selfCmd;
    cmds.add(selfCmd);
  }

  return _coalesceCommands(cmds);
}