+ enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
+ enum bt_self_component_status comp_status;
+ struct bt_component *component = NULL;
+ int ret;
+ bool init_can_consume;
+ struct bt_value *new_params = NULL;
+
+ BT_ASSERT(comp_cls);
+ BT_ASSERT_PRE_NON_NULL(graph, "Graph");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph);
+ BT_ASSERT_PRE(
+ graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING,
+ "Graph is not in the \"configuring\" state: %!+g", graph);
+ BT_ASSERT_PRE(!component_name_exists(graph, name),
+ "Duplicate component name: %!+g, name=\"%s\"", graph, name);
+ BT_ASSERT_PRE(!params || bt_value_is_map(params),
+ "Parameter value is not a map value: %!+v", params);
+ init_can_consume = graph->can_consume;
+ bt_graph_set_can_consume(graph, false);
+ BT_LIB_LOGD("Adding component to graph: "
+ "%![graph-]+g, %![cc-]+C, name=\"%s\", %![params-]+v, "
+ "init-method-data-addr=%p",
+ graph, comp_cls, name, params, init_method_data);
+
+ if (!params) {
+ new_params = bt_value_map_create();
+ if (!new_params) {
+ BT_LOGE_STR("Cannot create map value object.");
+ graph_status = BT_GRAPH_STATUS_NOMEM;
+ goto end;
+ }
+
+ params = new_params;
+ }
+
+ ret = bt_component_create(comp_cls, name, &component);
+ if (ret) {
+ BT_LOGE("Cannot create empty component object: ret=%d",
+ ret);
+ graph_status = BT_GRAPH_STATUS_NOMEM;
+ goto end;
+ }
+
+ /*
+ * The user's initialization method needs to see that this
+ * component is part of the graph. If the user method fails, we
+ * immediately remove the component from the graph's components.
+ */
+ g_ptr_array_add(graph->components, component);
+ bt_component_set_graph(component, graph);
+ bt_value_freeze(params);
+
+ if (init_method) {
+ BT_LOGD_STR("Calling user's initialization method.");
+ comp_status = init_method(component, params, init_method_data);
+ BT_LOGD("User method returned: status=%s",
+ bt_self_component_status_string(comp_status));
+ if (comp_status != BT_SELF_COMPONENT_STATUS_OK) {
+ BT_LOGW_STR("Initialization method failed.");
+ graph_status = (int) comp_status;
+ bt_component_set_graph(component, NULL);
+ g_ptr_array_remove_fast(graph->components, component);
+ goto end;
+ }
+ }
+
+ /*
+ * Mark the component as initialized so that its finalization
+ * method is called when it is destroyed.
+ */
+ component->initialized = true;