Add a port.passive = follow mode and the node.passive equivalents
out-follow, in-follow, follow.
This makes it possible to control how a port influences the state of
the peer and how the peer influences the state of the node independently.
In passive mode, the port will not make the peer runnable and will also
not become runnable when the peer activates.
In the follow mode, the port will not make the peer runnable but it will
become runnable when the peer is active.
This makes it possible to do new things like (f for follow):
Source -> (f)loopback1-in|loopback1-out(f) -> Sink
It will not make the source and sink run but when one of them start, all
will become runnable.
Or you can now better do the leak node hack that was previously used:
Source -> (f)pw-record
That will only start running when the source is activated by something
else.
With port.passive = true|false|follow there is a potential 4th case
which would activate the peer but not be activated by the peer, which is
not something that makes sense.
We used to skip the runnable state from driver nodes because we assume
that they will be activated from other nodes. We however need to make
this more general to all suspendable nodes.
This makes pw-play -> loopback1-sink loopback1-out -> loopback2-sink
loopback-out -> sink also work correctly because the loopback2-sink does
not activate loopback1-out then.
The sync-groups are only to group nodes with the same driver but don't
make them runnable.
This avoid making v4l2 runnable (without a link) when running ardour
because ardour uses the transport, which activates the sync group.
Move the runnable state calculation out of the collect_nodes function.
They are really two different steps that doin't overlap much.
The runnable state of a node is very easy to calculate. A node is
runnable if it is linked to another node without a passive port. When we
find two runnable nodes, make them runnable, which makes all nodes
linked to them runnable, stopping at passive ports.
We don't have to check the active state of the nodes or links to group
them together. This ensures we don't swap nodes around too much when the
node or link state changes.
There is no reason to delay preparing the link (by the scheduler) when
both nodes are active, we can do that right from the start.
This makes things a bit more symetrical because deactivating a node does
not unprepare a link.
This however changes things a bit because you can no longer delay link
prepare until you activate the node. I don't know if this is actually in
use and it would probably be to delay format negotiation. The right way
do delay format negotiation is to wait until an EnumFormat is set but
that is something to improve later.