call method

  1. @override
OU? call({
  1. required covariant Collective<E> cell,
  2. required covariant IN signal,
  3. Set<Cell>? notified,
})

Processes collection change signals

Implementation

@override
OU? call({required covariant Collective<E> cell, required covariant IN signal, Set<Cell>? notified}) {

  if (identical((cell as CollectiveCell)._properties.receptor, this)) {

    if (cell is Deputy) {
      return super.call(cell: cell, signal: signal);
    }

    if (signal is CollectivePost && signal.from != cell) {
      final collective = cell as CollectiveCell;
      final container = collective._properties.container;
      final containerType = collective._properties.containerType;

      bool partial = false;
      final map = <CollectiveEvent, Set>{};

      void tryAdd(E e) {
        if (containerType.add<E>(collective, container, e)) {
          (map[Collective.elementAdded] ??= <E>{}).add(e);
          if (e is CollectiveCell) {
            e._properties.synapses.link(e, host: collective);
          }
        } else {
          partial = true;
        }
      }

      for (var en in signal.body!.entries) {

        switch(en.key) {
          case Collective.elementUpdated:
            for (var c in en.value) {
              if (c is ElementValueChange && c.element is E) {
                if (container.contains(c.element)) {
                  (map[Collective.elementUpdated] ??= <ElementValueChange<E,dynamic>>{}).add(c);
                } else {
                  tryAdd(c.element);
                }
              }
            }
            break;

          case Collective.elementAdded:
            if (en.value.isNotEmpty) {
              en.value.whereType<E>().forEach(tryAdd);
            }
            break;

          case Collective.elementRemoved:
            if (en.value.isNotEmpty) {
              for (var e in en.value) {
                if (containerType.remove<E>(collective, container, e)) {
                  (map[Collective.elementRemoved] ??= <E>{}).add(e);
                  if (e is CollectiveCell) {
                    e._properties.synapses.unlink(collective);
                  }
                } else {
                  partial = true;
                }
              }
            }
            break;
        }
      }

      Signal? post;
      if (map.isNotEmpty) {
        if (signal.body!.length == 1) {
          if (map.keys.single == Collective.elementUpdated) {
            post = partial
                ? CollectivePost._(from: signal.from, body: {Collective.elementUpdated: map.values.first.cast()})
                : signal;
          }
        } else if (partial) {
          post = CollectivePost._(from: signal.from, body: map);
        }
      }

      if (post != null && post is IN) {
        return super.call(cell: cell, signal: post, notified: notified);
      }

    } else {
      return super.call(cell: cell, signal: signal, notified: notified);
    }
  }

  return null;
}