4 * Babeltrace Plugin Component Class
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/compiler-internal.h>
30 #include <babeltrace/graph/component-class-internal.h>
31 #include <babeltrace/ref.h>
32 #include <babeltrace/types.h>
36 void bt_component_class_destroy(struct bt_object
*obj
)
38 struct bt_component_class
*class;
42 class = container_of(obj
, struct bt_component_class
, base
);
44 /* Call destroy listeners in reverse registration order */
45 for (i
= class->destroy_listeners
->len
- 1; i
>= 0; i
--) {
46 struct bt_component_class_destroy_listener
*listener
=
47 &g_array_index(class->destroy_listeners
,
48 struct bt_component_class_destroy_listener
,
51 listener
->func(class, listener
->data
);
55 g_string_free(class->name
, TRUE
);
57 if (class->description
) {
58 g_string_free(class->description
, TRUE
);
61 g_string_free(class->help
, TRUE
);
63 if (class->destroy_listeners
) {
64 g_array_free(class->destroy_listeners
, TRUE
);
71 int bt_component_class_init(struct bt_component_class
*class,
72 enum bt_component_class_type type
, const char *name
)
76 bt_object_init(class, bt_component_class_destroy
);
78 class->name
= g_string_new(name
);
83 class->description
= g_string_new(NULL
);
84 if (!class->description
) {
88 class->help
= g_string_new(NULL
);
93 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
94 sizeof(struct bt_component_class_destroy_listener
));
95 if (!class->destroy_listeners
) {
109 struct bt_component_class
*bt_component_class_source_create(const char *name
,
110 bt_component_class_notification_iterator_next_method notification_iterator_next_method
)
112 struct bt_component_class_source
*source_class
= NULL
;
115 if (!name
|| !notification_iterator_next_method
) {
119 source_class
= g_new0(struct bt_component_class_source
, 1);
124 ret
= bt_component_class_init(&source_class
->parent
,
125 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
128 * If bt_component_class_init() fails, the component
129 * class is put, therefore its memory is already
136 source_class
->methods
.iterator
.next
= notification_iterator_next_method
;
139 return &source_class
->parent
;
142 struct bt_component_class
*bt_component_class_filter_create(const char *name
,
143 bt_component_class_notification_iterator_next_method notification_iterator_next_method
)
145 struct bt_component_class_filter
*filter_class
= NULL
;
148 if (!name
|| !notification_iterator_next_method
) {
152 filter_class
= g_new0(struct bt_component_class_filter
, 1);
157 ret
= bt_component_class_init(&filter_class
->parent
,
158 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
161 * If bt_component_class_init() fails, the component
162 * class is put, therefore its memory is already
169 filter_class
->methods
.iterator
.next
= notification_iterator_next_method
;
172 return &filter_class
->parent
;
175 struct bt_component_class
*bt_component_class_sink_create(const char *name
,
176 bt_component_class_sink_consume_method consume_method
)
178 struct bt_component_class_sink
*sink_class
= NULL
;
181 if (!name
|| !consume_method
) {
185 sink_class
= g_new0(struct bt_component_class_sink
, 1);
190 ret
= bt_component_class_init(&sink_class
->parent
,
191 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
194 * If bt_component_class_init() fails, the component
195 * class is put, therefore its memory is already
202 sink_class
->methods
.consume
= consume_method
;
205 return &sink_class
->parent
;
208 int bt_component_class_set_init_method(
209 struct bt_component_class
*component_class
,
210 bt_component_class_init_method init_method
)
214 if (!component_class
|| component_class
->frozen
|| !init_method
) {
219 component_class
->methods
.init
= init_method
;
225 int bt_component_class_set_query_method(
226 struct bt_component_class
*component_class
,
227 bt_component_class_query_method query_method
)
231 if (!component_class
|| component_class
->frozen
|| !query_method
) {
236 component_class
->methods
.query
= query_method
;
242 int bt_component_class_set_accept_port_connection_method(
243 struct bt_component_class
*component_class
,
244 bt_component_class_accept_port_connection_method method
)
248 if (!component_class
|| component_class
->frozen
|| !method
) {
253 component_class
->methods
.accept_port_connection
= method
;
259 int bt_component_class_set_port_connected_method(
260 struct bt_component_class
*component_class
,
261 bt_component_class_port_connected_method method
)
265 if (!component_class
|| component_class
->frozen
|| !method
) {
270 component_class
->methods
.port_connected
= method
;
276 int bt_component_class_set_port_disconnected_method(
277 struct bt_component_class
*component_class
,
278 bt_component_class_port_disconnected_method method
)
282 if (!component_class
|| component_class
->frozen
|| !method
) {
287 component_class
->methods
.port_disconnected
= method
;
293 int bt_component_class_set_finalize_method(
294 struct bt_component_class
*component_class
,
295 bt_component_class_finalize_method finalize_method
)
299 if (!component_class
|| component_class
->frozen
|| !finalize_method
) {
304 component_class
->methods
.finalize
= finalize_method
;
310 int bt_component_class_source_set_notification_iterator_init_method(
311 struct bt_component_class
*component_class
,
312 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
314 struct bt_component_class_source
*source_class
;
317 if (!component_class
|| component_class
->frozen
||
318 !notification_iterator_init_method
||
319 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
324 source_class
= container_of(component_class
,
325 struct bt_component_class_source
, parent
);
326 source_class
->methods
.iterator
.init
= notification_iterator_init_method
;
332 int bt_component_class_source_set_notification_iterator_finalize_method(
333 struct bt_component_class
*component_class
,
334 bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method
)
336 struct bt_component_class_source
*source_class
;
339 if (!component_class
|| component_class
->frozen
||
340 !notification_iterator_finalize_method
||
341 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
346 source_class
= container_of(component_class
,
347 struct bt_component_class_source
, parent
);
348 source_class
->methods
.iterator
.finalize
=
349 notification_iterator_finalize_method
;
355 int bt_component_class_source_set_notification_iterator_seek_time_method(
356 struct bt_component_class
*component_class
,
357 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
359 struct bt_component_class_source
*source_class
;
362 if (!component_class
|| component_class
->frozen
||
363 !notification_iterator_seek_time_method
||
364 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
369 source_class
= container_of(component_class
,
370 struct bt_component_class_source
, parent
);
371 source_class
->methods
.iterator
.seek_time
=
372 notification_iterator_seek_time_method
;
378 int bt_component_class_filter_set_notification_iterator_init_method(
379 struct bt_component_class
*component_class
,
380 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
382 struct bt_component_class_filter
*filter_class
;
385 if (!component_class
|| component_class
->frozen
||
386 !notification_iterator_init_method
||
387 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
392 filter_class
= container_of(component_class
,
393 struct bt_component_class_filter
, parent
);
394 filter_class
->methods
.iterator
.init
= notification_iterator_init_method
;
400 int bt_component_class_filter_set_notification_iterator_finalize_method(
401 struct bt_component_class
*component_class
,
402 bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method
)
404 struct bt_component_class_filter
*filter_class
;
407 if (!component_class
|| component_class
->frozen
||
408 !notification_iterator_finalize_method
||
409 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
414 filter_class
= container_of(component_class
,
415 struct bt_component_class_filter
, parent
);
416 filter_class
->methods
.iterator
.finalize
=
417 notification_iterator_finalize_method
;
423 int bt_component_class_filter_set_notification_iterator_seek_time_method(
424 struct bt_component_class
*component_class
,
425 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
427 struct bt_component_class_filter
*filter_class
;
430 if (!component_class
|| component_class
->frozen
||
431 !notification_iterator_seek_time_method
||
432 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
437 filter_class
= container_of(component_class
,
438 struct bt_component_class_filter
, parent
);
439 filter_class
->methods
.iterator
.seek_time
=
440 notification_iterator_seek_time_method
;
446 int bt_component_class_set_description(
447 struct bt_component_class
*component_class
,
448 const char *description
)
452 if (!component_class
|| component_class
->frozen
|| !description
) {
457 g_string_assign(component_class
->description
, description
);
463 int bt_component_class_set_help(
464 struct bt_component_class
*component_class
,
469 if (!component_class
|| component_class
->frozen
|| !help
) {
474 g_string_assign(component_class
->help
, help
);
480 const char *bt_component_class_get_name(
481 struct bt_component_class
*component_class
)
483 return component_class
? component_class
->name
->str
: NULL
;
486 enum bt_component_class_type
bt_component_class_get_type(
487 struct bt_component_class
*component_class
)
489 return component_class
? component_class
->type
:
490 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
493 const char *bt_component_class_get_description(
494 struct bt_component_class
*component_class
)
496 return component_class
&& component_class
->description
&&
497 component_class
->description
->str
[0] != '\0' ?
498 component_class
->description
->str
: NULL
;
501 const char *bt_component_class_get_help(
502 struct bt_component_class
*component_class
)
504 return component_class
&& component_class
->help
&&
505 component_class
->help
->str
[0] != '\0' ?
506 component_class
->help
->str
: NULL
;
510 void bt_component_class_add_destroy_listener(struct bt_component_class
*class,
511 bt_component_class_destroy_listener_func func
, void *data
)
513 struct bt_component_class_destroy_listener listener
;
517 listener
.func
= func
;
518 listener
.data
= data
;
519 g_array_append_val(class->destroy_listeners
, listener
);
522 int bt_component_class_freeze(
523 struct bt_component_class
*component_class
)
527 if (!component_class
) {
532 component_class
->frozen
= BT_TRUE
;
538 struct bt_value
*bt_component_class_query(
539 struct bt_component_class
*component_class
,
540 const char *object
, struct bt_value
*params
)
542 struct bt_value
*results
= NULL
;
544 if (!component_class
|| !object
|| !params
||
545 !component_class
->methods
.query
) {
549 results
= component_class
->methods
.query(component_class
,