+ return BT_GRAPH_STATUS_OK;
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
+{
+ uint64_t i;
+ GArray *listeners;
+ struct bt_component *comp;
+
+ BT_ASSERT(graph);
+ BT_ASSERT(port);
+ BT_LIB_LOGV("Notifying graph listeners that a port was added: "
+ "%![graph-]+g, %![port-]+p", graph, port);
+ comp = bt_port_borrow_component_inline(port);
+ BT_ASSERT(comp);
+
+ switch (comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ switch (port->type) {
+ case BT_PORT_TYPE_OUTPUT:
+ listeners = graph->listeners.source_output_port_added;
+ break;
+ default:
+ abort();
+ }
+
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ switch (port->type) {
+ case BT_PORT_TYPE_INPUT:
+ listeners = graph->listeners.filter_input_port_added;
+ break;
+ case BT_PORT_TYPE_OUTPUT:
+ listeners = graph->listeners.filter_output_port_added;
+ break;
+ default:
+ abort();
+ }
+
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ {
+ switch (port->type) {
+ case BT_PORT_TYPE_INPUT:
+ listeners = graph->listeners.sink_input_port_added;
+ break;
+ default:
+ abort();
+ }
+
+ break;
+ }
+ default:
+ abort();
+ }
+
+ for (i = 0; i < listeners->len; i++) {
+ struct bt_graph_listener_port_added *listener =
+ &g_array_index(listeners,
+ struct bt_graph_listener_port_added, i);
+
+ BT_ASSERT(listener->func);
+ listener->func(comp, port, listener->base.data);
+ }
+}
+
+BT_HIDDEN
+void bt_graph_notify_ports_connected(struct bt_graph *graph,
+ struct bt_port *upstream_port, struct bt_port *downstream_port)
+{
+ uint64_t i;
+ GArray *listeners;
+ struct bt_component *upstream_comp;
+ struct bt_component *downstream_comp;
+
+ BT_ASSERT(graph);
+ BT_ASSERT(upstream_port);
+ BT_ASSERT(downstream_port);
+ BT_LIB_LOGV("Notifying graph listeners that ports were connected: "
+ "%![graph-]+g, %![up-port-]+p, %![down-port-]+p",
+ graph, upstream_port, downstream_port);
+ upstream_comp = bt_port_borrow_component_inline(upstream_port);
+ BT_ASSERT(upstream_comp);
+ downstream_comp = bt_port_borrow_component_inline(downstream_port);
+ BT_ASSERT(downstream_comp);
+
+ switch (upstream_comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ switch (downstream_comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ listeners =
+ graph->listeners.source_filter_ports_connected;
+ break;
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ listeners =
+ graph->listeners.source_sink_ports_connected;
+ break;
+ default:
+ abort();
+ }
+
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ switch (downstream_comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ listeners =
+ graph->listeners.filter_filter_ports_connected;
+ break;
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ listeners =
+ graph->listeners.filter_sink_ports_connected;
+ break;
+ default:
+ abort();
+ }
+
+ break;
+ }
+ default:
+ abort();
+ }
+
+ for (i = 0; i < listeners->len; i++) {
+ struct bt_graph_listener_ports_connected *listener =
+ &g_array_index(listeners,
+ struct bt_graph_listener_ports_connected, i);
+
+ BT_ASSERT(listener->func);
+ listener->func(upstream_comp, downstream_comp,
+ upstream_port, downstream_port, listener->base.data);