Implement the component graph interface
[babeltrace.git] / lib / component / component.c
index c3ccd95c57edf569498c3b725c4be2d6e0de6e49..8056db14eb1feced347ed804f672ba5ffe65b92c 100644 (file)
@@ -32,6 +32,7 @@
 #include <babeltrace/component/component-source-internal.h>
 #include <babeltrace/component/component-filter-internal.h>
 #include <babeltrace/component/component-sink-internal.h>
+#include <babeltrace/component/component-graph-internal.h>
 #include <babeltrace/component/notification/iterator-internal.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/compiler.h>
@@ -94,6 +95,7 @@ enum bt_component_status bt_component_init(struct bt_component *component,
                goto end;
        }
 
+       component->initializing = true;
        component->destroy = destroy;
 end:
        return ret;
@@ -107,7 +109,7 @@ enum bt_component_class_type bt_component_get_class_type(
 
 BT_HIDDEN
 struct bt_notification_iterator *bt_component_create_iterator(
-               struct bt_component *component)
+               struct bt_component *component, void *init_method_data)
 {
        enum bt_notification_iterator_status ret_iterator;
        enum bt_component_class_type type;
@@ -134,30 +136,32 @@ struct bt_notification_iterator *bt_component_create_iterator(
        case BT_COMPONENT_CLASS_TYPE_SOURCE:
        {
                struct bt_component_class_source *source_class;
-               enum bt_component_status ret_component;
+               enum bt_notification_iterator_status status;
 
                source_class = container_of(class, struct bt_component_class_source, parent);
-               assert(source_class->methods.init_iterator);
-               ret_component =
-                       source_class->methods.init_iterator(component, iterator);
-               if (ret_component != BT_COMPONENT_STATUS_OK) {
-                       goto error;
-               }
-               break;
 
+               if (source_class->methods.iterator.init) {
+                       status = source_class->methods.iterator.init(component,
+                                       iterator, init_method_data);
+                       if (status < 0) {
+                               goto error;
+                       }
+               }
                break;
        }
        case BT_COMPONENT_CLASS_TYPE_FILTER:
        {
                struct bt_component_class_filter *filter_class;
-               enum bt_component_status ret_component;
+               enum bt_notification_iterator_status status;
 
                filter_class = container_of(class, struct bt_component_class_filter, parent);
-               assert(filter_class->methods.init_iterator);
-               ret_component =
-                       filter_class->methods.init_iterator(component, iterator);
-               if (ret_component != BT_COMPONENT_STATUS_OK) {
-                       goto error;
+
+               if (filter_class->methods.iterator.init) {
+                       status = filter_class->methods.iterator.init(component,
+                                       iterator, init_method_data);
+                       if (status < 0) {
+                               goto error;
+                       }
                }
                break;
        }
@@ -207,8 +211,6 @@ struct bt_component *bt_component_create_with_init_method_data(
                goto end;
        }
 
-       component->initializing = true;
-
        if (component_class->methods.init) {
                ret = component_class->methods.init(component, params,
                        init_method_data);
@@ -247,7 +249,7 @@ const char *bt_component_get_name(struct bt_component *component)
                goto end;
        }
 
-       ret = component->name->str;
+       ret = component->name->len == 0 ? NULL : component->name->str;
 end:
        return ret;
 }
@@ -293,3 +295,199 @@ bt_component_set_private_data(struct bt_component *component,
 end:
        return ret;
 }
+
+BT_HIDDEN
+void bt_component_set_graph(struct bt_component *component,
+               struct bt_graph *graph)
+{
+       struct bt_object *parent = bt_object_get_parent(&component->base);
+
+       assert(!parent || parent == &graph->base);
+       if (!parent) {
+               bt_object_set_parent(component, &graph->base);
+       }
+       bt_put(parent);
+}
+
+struct bt_graph *bt_component_get_graph(
+               struct bt_component *component)
+{
+       return (struct bt_graph *) bt_object_get_parent(&component->base);
+}
+
+BT_HIDDEN
+int bt_component_init_input_ports(struct bt_component *component,
+               GPtrArray **input_ports)
+{
+       int ret = 0;
+       struct bt_port *default_port;
+
+       *input_ports = g_ptr_array_new_with_free_func(bt_object_release);
+       if (!*input_ports) {
+               ret = -1;
+               goto end;
+       }
+
+       default_port = bt_component_add_port(component, *input_ports,
+                       BT_PORT_TYPE_INPUT, DEFAULT_INPUT_PORT_NAME);
+       if (!default_port) {
+               ret = -1;
+               goto end;
+       }
+       bt_put(default_port);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_component_init_output_ports(struct bt_component *component,
+               GPtrArray **output_ports)
+{
+       int ret = 0;
+       struct bt_port *default_port;
+
+       *output_ports = g_ptr_array_new_with_free_func(bt_object_release);
+       if (!*output_ports) {
+               ret = -1;
+               goto end;
+       }
+
+       default_port = bt_component_add_port(component, *output_ports,
+                       BT_PORT_TYPE_OUTPUT, DEFAULT_OUTPUT_PORT_NAME);
+       if (!default_port) {
+               ret = -1;
+               goto end;
+       }
+       bt_put(default_port);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
+{
+       size_t i;
+       struct bt_port *ret_port = NULL;
+
+       for (i = 0; i < ports->len; i++) {
+               struct bt_port *port = g_ptr_array_index(ports, i);
+               const char *port_name = bt_port_get_name(port);
+
+               if (!port_name) {
+                       continue;
+               }
+
+               if (!strcmp(name, port_name)) {
+                       ret_port = bt_get(port);
+                       break;
+               }
+       }
+
+       return ret_port;
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (index < 0 || index >= ports->len) {
+               goto end;
+       }
+
+       port = bt_get(g_ptr_array_index(ports, index));
+end:
+       return port;
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_add_port(
+               struct bt_component *component,GPtrArray *ports,
+               enum bt_port_type port_type, const char *name)
+{
+       size_t i;
+       struct bt_port *new_port = NULL;
+
+       if (!component->initializing || !name || *name == '\0') {
+               goto end;
+       }
+
+       /* Look for a port having the same name. */
+       for (i = 0; i < ports->len; i++) {
+               const char *port_name;
+               struct bt_port *port = g_ptr_array_index(
+                               ports, i);
+
+               port_name = bt_port_get_name(port);
+               if (!port_name) {
+                       continue;
+               }
+
+               if (!strcmp(name, port_name)) {
+                       /* Port name clash, abort. */
+                       goto end;
+               }
+       }
+
+       new_port = bt_port_create(component, port_type, name);
+       if (!new_port) {
+               goto end;
+       }
+
+       /*
+        * No name clash, add the port.
+        * The component is now the port's parent; it should _not_
+        * hold a reference to the port since the port's lifetime
+        * is now protected by the component's own lifetime.
+        */
+       g_ptr_array_add(ports, new_port);
+end:
+       return new_port;
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_remove_port(
+               struct bt_component *component, GPtrArray *ports,
+               const char *name)
+{
+       size_t i;
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (!component->initializing || !name) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       for (i = 0; i < ports->len; i++) {
+               const char *port_name;
+               struct bt_port *port = g_ptr_array_index(ports, i);
+
+               port_name = bt_port_get_name(port);
+               if (!port_name) {
+                       continue;
+               }
+
+               if (!strcmp(name, port_name)) {
+                       g_ptr_array_remove_index(ports, i);
+                       goto end;
+               }
+       }
+       status = BT_COMPONENT_STATUS_NOT_FOUND;
+end:
+       return status;
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_new_connection(
+               struct bt_component *component, struct bt_port *own_port,
+               struct bt_connection *connection)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (component->class->methods.new_connection_method) {
+               status = component->class->methods.new_connection_method(
+                               own_port, connection);
+       }
+
+       return status;
+}
This page took 0.026127 seconds and 4 git commands to generate.