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/component-class-dev.hpp"
11 #include "cpp-common/bt2/component-class.hpp"
17 struct RunInData final
19 RunInCompClsQueryFunc compClsCtxFunc
;
20 RunInCompClsInitFunc compCtxFunc
;
21 RunInMsgIterClsInitFunc msgIterCtxFunc
;
26 class RunInSourceMsgIter final
: public bt2::UserMessageIterator
<RunInSourceMsgIter
, RunInSource
>
29 explicit RunInSourceMsgIter(const bt2::SelfMessageIterator self
,
30 bt2::SelfMessageIteratorConfiguration
,
31 const bt2::SelfComponentOutputPort port
) :
32 bt2::UserMessageIterator
<RunInSourceMsgIter
, RunInSource
> {self
, "RUN-IN-SRC-MSG-ITER"}
34 const auto& data
= port
.data
<const RunInData
>();
36 if (data
.msgIterCtxFunc
) {
37 data
.msgIterCtxFunc(self
);
41 void _next(bt2::ConstMessageArray
&)
46 class RunInSource final
:
47 public bt2::UserSourceComponent
<RunInSource
, RunInSourceMsgIter
, const RunInData
,
51 static constexpr auto name
= "run-in-src";
53 explicit RunInSource(const bt2::SelfSourceComponent self
, bt2::ConstMapValue
,
54 const RunInData
* const runInData
) :
55 bt2::UserSourceComponent
<RunInSource
, RunInSourceMsgIter
, const RunInData
,
56 const RunInData
> {self
, "RUN-IN-SRC"},
57 _mRunInData
{runInData
}
59 this->_addOutputPort("out", *runInData
);
61 if (_mRunInData
->compCtxFunc
) {
62 _mRunInData
->compCtxFunc(self
);
66 static bt2::Value::Shared
_query(const bt2::SelfComponentClass self
, bt2::PrivateQueryExecutor
,
67 bt2c::CStringView
, bt2::ConstValue
,
68 const RunInData
* const data
)
70 if (data
->compClsCtxFunc
) {
71 data
->compClsCtxFunc(self
);
74 return bt2::NullValue
{}.shared();
78 const RunInData
*_mRunInData
;
81 class DummySink
: public bt2::UserSinkComponent
<DummySink
>
84 static constexpr auto name
= "dummy";
86 explicit DummySink(const bt2::SelfSinkComponent self
, bt2::ConstMapValue
, void *) :
87 bt2::UserSinkComponent
<DummySink
>(self
, "DUMMY-SINK")
89 this->_addInputPort("in");
92 void _graphIsConfigured()
94 _mMsgIter
= this->_createMessageIterator(this->_inputPorts()["in"]);
99 return _mMsgIter
->next().has_value();
103 bt2::MessageIterator::Shared _mMsgIter
;
108 void runIn(RunInCompClsQueryFunc compClsCtxFunc
, RunInCompClsInitFunc compCtxFunc
,
109 RunInMsgIterClsInitFunc msgIterCtxFunc
)
111 RunInData data
{std::move(compClsCtxFunc
), std::move(compCtxFunc
), std::move(msgIterCtxFunc
)};
112 const auto srcCompCls
= bt2::SourceComponentClass::create
<RunInSource
>();
114 /* Execute a query (executes `compClsCtxFunc`) */
116 const auto queryExec
= bt_query_executor_create_with_method_data(
117 bt_component_class_source_as_component_class(srcCompCls
->libObjPtr()), "", nullptr,
120 BT_ASSERT(queryExec
);
122 const bt_value
*queryRes
;
123 const auto status
= bt_query_executor_query(queryExec
, &queryRes
);
125 BT_ASSERT(status
== BT_QUERY_EXECUTOR_QUERY_STATUS_OK
);
126 bt_value_put_ref(queryRes
);
127 bt_query_executor_put_ref(queryExec
);
131 const auto graph
= bt_graph_create(0);
135 /* Add custom source component (executes `compCtxFunc`) */
136 const bt_component_source
*srcComp
;
139 const auto status
= bt_graph_add_source_component_with_initialize_method_data(
140 graph
, srcCompCls
->libObjPtr(), "the-source", NULL
, &data
, BT_LOGGING_LEVEL_NONE
,
143 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
146 /* Add dummy sink component */
147 const bt_component_sink
*sinkComp
;
150 const auto sinkCompCls
= bt2::SinkComponentClass::create
<DummySink
>();
151 const auto status
= bt_graph_add_sink_component_with_initialize_method_data(
152 graph
, sinkCompCls
->libObjPtr(), "the-sink", nullptr, nullptr, BT_LOGGING_LEVEL_NONE
,
155 BT_ASSERT(status
== BT_GRAPH_ADD_COMPONENT_STATUS_OK
);
160 const auto outPort
= bt_component_source_borrow_output_port_by_name_const(srcComp
, "out");
164 const auto inPort
= bt_component_sink_borrow_input_port_by_name_const(sinkComp
, "in");
168 const auto status
= bt_graph_connect_ports(graph
, outPort
, inPort
, nullptr);
170 BT_ASSERT(status
== BT_GRAPH_CONNECT_PORTS_STATUS_OK
);
173 /* Run graph (executes `msgIterCtxFunc`) */
175 const auto status
= bt_graph_run(graph
);
177 BT_ASSERT(status
== BT_GRAPH_RUN_STATUS_OK
);
180 /* Discard owned objects */
181 bt_graph_put_ref(graph
);
184 void runInCompClsQuery(RunInCompClsQueryFunc func
)
186 runIn(std::move(func
), nullptr, nullptr);
189 void runInCompClsInit(RunInCompClsInitFunc func
)
191 runIn(nullptr, std::move(func
), nullptr);
194 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func
)
196 runIn(nullptr, nullptr, std::move(func
));