2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2020-2023 EfficiOS, inc.
10 #include "common/assert.h"
12 struct RunInData final
14 RunInCompClsQueryFunc compClsCtxFunc
;
15 RunInCompClsInitFunc compCtxFunc
;
16 RunInMsgIterClsInitFunc msgIterCtxFunc
;
19 static const RunInData
& runInDataFromMethodData(void * const methodData
)
21 return *static_cast<const RunInData
*>(methodData
);
24 static bt_component_class_initialize_method_status
25 compClsInit(bt_self_component_source
* const selfComp
, bt_self_component_source_configuration
*,
26 const bt_value
*, void * const initMethodData
)
29 bt_self_component_source_add_output_port(selfComp
, "out", initMethodData
, nullptr);
31 BT_ASSERT(status
== BT_SELF_COMPONENT_ADD_PORT_STATUS_OK
);
33 auto& data
= runInDataFromMethodData(initMethodData
);
35 if (data
.compCtxFunc
) {
36 data
.compCtxFunc(bt_self_component_source_as_self_component(selfComp
));
39 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
;
42 static bt_component_class_query_method_status
43 compClsQuery(bt_self_component_class_source
* const selfCompCls
, bt_private_query_executor
*,
44 const char *, const bt_value
*, void * const methodData
,
45 const bt_value
** const result
)
47 auto& data
= runInDataFromMethodData(methodData
);
49 if (data
.compClsCtxFunc
) {
50 data
.compClsCtxFunc(bt_self_component_class_source_as_self_component_class(selfCompCls
));
53 *result
= bt_value_null
;
54 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK
;
57 static bt_message_iterator_class_initialize_method_status
58 msgIterClsInit(bt_self_message_iterator
* const selfMsgIter
,
59 bt_self_message_iterator_configuration
*, bt_self_component_port_output
* const port
)
61 auto& data
= runInDataFromMethodData(bt_self_component_port_get_data(
62 bt_self_component_port_output_as_self_component_port(port
)));
64 if (data
.msgIterCtxFunc
) {
65 data
.msgIterCtxFunc(selfMsgIter
);
68 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK
;
71 static bt_message_iterator_class_next_method_status
72 msgIterClsNext(bt_self_message_iterator
*, bt_message_array_const
, uint64_t, uint64_t *)
74 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END
;
77 void runIn(RunInCompClsQueryFunc compClsCtxFunc
, RunInCompClsInitFunc compCtxFunc
,
78 RunInMsgIterClsInitFunc msgIterCtxFunc
)
80 RunInData data
{std::move(compClsCtxFunc
), std::move(compCtxFunc
), std::move(msgIterCtxFunc
)};
82 /* Create and configure custom source component class */
83 const auto msgIterCls
= bt_message_iterator_class_create(msgIterClsNext
);
85 BT_ASSERT(msgIterCls
);
89 bt_message_iterator_class_set_initialize_method(msgIterCls
, msgIterClsInit
);
91 BT_ASSERT(status
== BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK
);
94 const auto srcCompCls
= bt_component_class_source_create("yo", msgIterCls
);
96 BT_ASSERT(srcCompCls
);
100 bt_component_class_source_set_initialize_method(srcCompCls
, compClsInit
);
102 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
106 const auto status
= bt_component_class_source_set_query_method(srcCompCls
, compClsQuery
);
108 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
111 /* Execute a query (executes `compClsCtxFunc`) */
113 const auto queryExec
= bt_query_executor_create_with_method_data(
114 bt_component_class_source_as_component_class(srcCompCls
), "", nullptr, &data
);
116 BT_ASSERT(queryExec
);
118 const bt_value
*queryRes
;
119 const auto status
= bt_query_executor_query(queryExec
, &queryRes
);
121 BT_ASSERT(status
== BT_QUERY_EXECUTOR_QUERY_STATUS_OK
);
123 bt_value_put_ref(queryRes
);
124 bt_query_executor_put_ref(queryExec
);
128 const auto graph
= bt_graph_create(0);
132 /* Add custom source component (executes `compCtxFunc`) */
133 const bt_component_source
*srcComp
;
136 const auto status
= bt_graph_add_source_component_with_initialize_method_data(
137 graph
, srcCompCls
, "whatever", NULL
, &data
, BT_LOGGING_LEVEL_NONE
, &srcComp
);
139 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
142 /* Find `sink.utils.dummy` component class */
143 const bt_plugin
*utilsPlugin
= nullptr;
147 bt_plugin_find("utils", BT_TRUE
, BT_TRUE
, BT_TRUE
, BT_TRUE
, BT_TRUE
, &utilsPlugin
);
149 BT_ASSERT(status
== BT_PLUGIN_FIND_STATUS_OK
);
152 /* Add `sink.utils.dummy` component */
153 const bt_component_sink
*sinkComp
;
156 const auto dummyCompCls
=
157 bt_plugin_borrow_sink_component_class_by_name_const(utilsPlugin
, "dummy");
159 BT_ASSERT(dummyCompCls
);
161 const auto status
= bt_graph_add_sink_component(graph
, dummyCompCls
, "the-sink", nullptr,
162 BT_LOGGING_LEVEL_NONE
, &sinkComp
);
164 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
169 const auto outPort
= bt_component_source_borrow_output_port_by_name_const(srcComp
, "out");
173 const auto inPort
= bt_component_sink_borrow_input_port_by_name_const(sinkComp
, "in");
177 const auto status
= bt_graph_connect_ports(graph
, outPort
, inPort
, nullptr);
179 BT_ASSERT(status
== BT_GRAPH_CONNECT_PORTS_STATUS_OK
);
182 /* Run graph (executes `msgIterCtxFunc`) */
183 const auto status
= bt_graph_run(graph
);
185 BT_ASSERT(status
== BT_GRAPH_RUN_STATUS_OK
);
187 /* Discard plugin and graph */
188 bt_plugin_put_ref(utilsPlugin
);
189 bt_graph_put_ref(graph
);
190 bt_component_class_source_put_ref(srcCompCls
);
191 bt_message_iterator_class_put_ref(msgIterCls
);
194 void runInCompClsQuery(RunInCompClsQueryFunc func
)
196 runIn(std::move(func
), nullptr, nullptr);
199 void runInCompClsInit(RunInCompClsInitFunc func
)
201 runIn(nullptr, std::move(func
), nullptr);
204 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func
)
206 runIn(nullptr, nullptr, std::move(func
));