share method

System<State, Event> share()

Share same source of truth using strategy refCount.

If system.run has been called multiple time, this operator will make them share same source of truth. This operator use refCount strategy to dispose resource, Which means the first run triggers source system run and when all running systems has been disposed, then the source system will be disposed.

It's useful for some scoped system like detailPageSystem, downward run will share same source of truth for this page only. The system can be run multiple times for different concerns (performance optimization), but they share same source of truth in this page. Another detail page has another source of truth that's the scoped means.

Implementation

System<State, Event> share() => copy((run) {
  int count = 0;
  Disposer? sourceDisposer;
  EffectForwarder<State, Event>? forwarder;
  EffectForwarder<State, Event> getForwarder() => forwarder ??= EffectForwarder();

  return ({reduce, effect, interceptor}) {

    assert(reduce == null, 'downward `reduce` is not null in share context.');
    assert(interceptor == null, 'downward `interceptor` is not null in share context.');

    final nextEffect = effect ?? (_, __, ___, ____) {};
    final Disposer disposer = getForwarder().add(effect: nextEffect);
    count += 1;

    if (count == 1) {
      sourceDisposer = run(effect: getForwarder().effect);
    }

    return Disposer(() {
      disposer();
      count -= 1;
      if (count == 0) {
        sourceDisposer?.call();
        sourceDisposer = null;
        forwarder?.dispose();
        forwarder = null;
      }
    });
  };
});