2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2020-2023 EfficiOS, inc.
9 #include "common/assert.h"
10 #include "cpp-common/bt2/wrap.hpp"
16 struct RunInData final
18 RunInCompClsQueryFunc compClsCtxFunc
;
19 RunInCompClsInitFunc compCtxFunc
;
20 RunInMsgIterClsInitFunc msgIterCtxFunc
;
23 const RunInData
& runInDataFromMethodData(void * const methodData
)
25 return *static_cast<const RunInData
*>(methodData
);
28 bt_component_class_initialize_method_status
compClsInit(bt_self_component_source
* const selfComp
,
29 bt_self_component_source_configuration
*,
31 void * const initMethodData
)
34 bt_self_component_source_add_output_port(selfComp
, "out", initMethodData
, nullptr);
36 BT_ASSERT(status
== BT_SELF_COMPONENT_ADD_PORT_STATUS_OK
);
38 auto& data
= runInDataFromMethodData(initMethodData
);
40 if (data
.compCtxFunc
) {
41 data
.compCtxFunc(bt2::wrap(bt_self_component_source_as_self_component(selfComp
)));
44 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
;
47 bt_component_class_query_method_status
48 compClsQuery(bt_self_component_class_source
* const selfCompCls
, bt_private_query_executor
*,
49 const char *, const bt_value
*, void * const methodData
,
50 const bt_value
** const result
)
52 auto& data
= runInDataFromMethodData(methodData
);
54 if (data
.compClsCtxFunc
) {
56 bt2::wrap(bt_self_component_class_source_as_self_component_class(selfCompCls
)));
59 *result
= bt_value_null
;
60 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK
;
63 bt_message_iterator_class_initialize_method_status
64 msgIterClsInit(bt_self_message_iterator
* const selfMsgIter
,
65 bt_self_message_iterator_configuration
*, bt_self_component_port_output
* const port
)
67 auto& data
= runInDataFromMethodData(bt_self_component_port_get_data(
68 bt_self_component_port_output_as_self_component_port(port
)));
70 if (data
.msgIterCtxFunc
) {
71 data
.msgIterCtxFunc(bt2::wrap(selfMsgIter
));
74 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK
;
77 bt_message_iterator_class_next_method_status
78 msgIterClsNext(bt_self_message_iterator
*, bt_message_array_const
, uint64_t, uint64_t *)
80 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END
;
85 bt_message_iterator
*msgIter
;
88 bt_component_class_initialize_method_status
dummySinkInit(bt_self_component_sink
* const self
,
89 bt_self_component_sink_configuration
*,
91 void * const initMethodData
)
93 const auto status
= bt_self_component_sink_add_input_port(self
, "in", NULL
, nullptr);
95 BT_ASSERT(status
== BT_SELF_COMPONENT_ADD_PORT_STATUS_OK
);
96 bt_self_component_set_data(bt_self_component_sink_as_self_component(self
), initMethodData
);
97 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
;
100 DummySinkData
& dummySinkDataFromSelfCompSink(bt_self_component_sink
* const self
)
102 return *static_cast<DummySinkData
*>(
103 bt_self_component_get_data(bt_self_component_sink_as_self_component(self
)));
106 bt_component_class_sink_graph_is_configured_method_status
107 dummySinkGraphIsConfigured(bt_self_component_sink
* const self
)
109 const auto port
= bt_self_component_sink_borrow_input_port_by_name(self
, "in");
113 const auto status
= bt_message_iterator_create_from_sink_component(
114 self
, port
, &dummySinkDataFromSelfCompSink(self
).msgIter
);
116 BT_ASSERT(status
== BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK
);
117 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
;
120 bt_component_class_sink_consume_method_status
dummySinkConsume(bt_self_component_sink
* const self
)
122 bt_message_array_const msgs
;
125 bt_message_iterator_next(dummySinkDataFromSelfCompSink(self
).msgIter
, &msgs
, &msgCount
);
127 BT_ASSERT(status
== BT_MESSAGE_ITERATOR_NEXT_STATUS_END
);
128 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END
;
133 void runIn(RunInCompClsQueryFunc compClsCtxFunc
, RunInCompClsInitFunc compCtxFunc
,
134 RunInMsgIterClsInitFunc msgIterCtxFunc
)
136 RunInData data
{std::move(compClsCtxFunc
), std::move(compCtxFunc
), std::move(msgIterCtxFunc
)};
138 /* Create and configure custom source component class */
139 const auto msgIterCls
= bt_message_iterator_class_create(msgIterClsNext
);
141 BT_ASSERT(msgIterCls
);
145 bt_message_iterator_class_set_initialize_method(msgIterCls
, msgIterClsInit
);
147 BT_ASSERT(status
== BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK
);
150 const auto srcCompCls
= bt_component_class_source_create("yo", msgIterCls
);
152 BT_ASSERT(srcCompCls
);
156 bt_component_class_source_set_initialize_method(srcCompCls
, compClsInit
);
158 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
162 const auto status
= bt_component_class_source_set_query_method(srcCompCls
, compClsQuery
);
164 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
167 /* Execute a query (executes `compClsCtxFunc`) */
169 const auto queryExec
= bt_query_executor_create_with_method_data(
170 bt_component_class_source_as_component_class(srcCompCls
), "", nullptr, &data
);
172 BT_ASSERT(queryExec
);
174 const bt_value
*queryRes
;
175 const auto status
= bt_query_executor_query(queryExec
, &queryRes
);
177 BT_ASSERT(status
== BT_QUERY_EXECUTOR_QUERY_STATUS_OK
);
178 bt_value_put_ref(queryRes
);
179 bt_query_executor_put_ref(queryExec
);
182 /* Create a dummy sink component */
183 const auto sinkCompCls
= bt_component_class_sink_create("dummy", dummySinkConsume
);
185 BT_ASSERT(sinkCompCls
);
189 bt_component_class_sink_set_initialize_method(sinkCompCls
, dummySinkInit
);
191 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
195 const auto status
= bt_component_class_sink_set_graph_is_configured_method(
196 sinkCompCls
, dummySinkGraphIsConfigured
);
198 BT_ASSERT(status
== BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK
);
202 const auto graph
= bt_graph_create(0);
206 /* Add custom source component (executes `compCtxFunc`) */
207 const bt_component_source
*srcComp
;
210 const auto status
= bt_graph_add_source_component_with_initialize_method_data(
211 graph
, srcCompCls
, "the-source", NULL
, &data
, BT_LOGGING_LEVEL_NONE
, &srcComp
);
213 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
216 /* Add dummy sink component */
217 const bt_component_sink
*sinkComp
;
218 DummySinkData dummySinkData
;
221 const auto status
= bt_graph_add_sink_component_with_initialize_method_data(
222 graph
, sinkCompCls
, "the-sink", NULL
, &dummySinkData
, BT_LOGGING_LEVEL_NONE
, &sinkComp
);
224 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
229 const auto outPort
= bt_component_source_borrow_output_port_by_name_const(srcComp
, "out");
233 const auto inPort
= bt_component_sink_borrow_input_port_by_name_const(sinkComp
, "in");
237 const auto status
= bt_graph_connect_ports(graph
, outPort
, inPort
, nullptr);
239 BT_ASSERT(status
== BT_GRAPH_CONNECT_PORTS_STATUS_OK
);
242 /* Run graph (executes `msgIterCtxFunc`) */
244 const auto status
= bt_graph_run(graph
);
246 BT_ASSERT(status
== BT_GRAPH_RUN_STATUS_OK
);
249 /* Discard owned objects */
250 bt_graph_put_ref(graph
);
251 bt_component_class_source_put_ref(srcCompCls
);
252 bt_component_class_sink_put_ref(sinkCompCls
);
253 bt_message_iterator_class_put_ref(msgIterCls
);
256 void runInCompClsQuery(RunInCompClsQueryFunc func
)
258 runIn(std::move(func
), nullptr, nullptr);
261 void runInCompClsInit(RunInCompClsInitFunc func
)
263 runIn(nullptr, std::move(func
), nullptr);
266 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func
)
268 runIn(nullptr, nullptr, std::move(func
));