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"
12 #include "cpp-common/bt2/graph.hpp"
18 struct RunInData final
20 RunInCompClsQueryFunc compClsCtxFunc
;
21 RunInCompClsInitFunc compCtxFunc
;
22 RunInMsgIterClsInitFunc msgIterCtxFunc
;
27 class RunInSourceMsgIter final
: public bt2::UserMessageIterator
<RunInSourceMsgIter
, RunInSource
>
30 explicit RunInSourceMsgIter(const bt2::SelfMessageIterator self
,
31 bt2::SelfMessageIteratorConfiguration
,
32 const bt2::SelfComponentOutputPort port
) :
33 bt2::UserMessageIterator
<RunInSourceMsgIter
, RunInSource
> {self
, "RUN-IN-SRC-MSG-ITER"}
35 const auto& data
= port
.data
<const RunInData
>();
37 if (data
.msgIterCtxFunc
) {
38 data
.msgIterCtxFunc(self
);
42 void _next(bt2::ConstMessageArray
&)
47 class RunInSource final
:
48 public bt2::UserSourceComponent
<RunInSource
, RunInSourceMsgIter
, const RunInData
,
52 static constexpr auto name
= "run-in-src";
54 explicit RunInSource(const bt2::SelfSourceComponent self
, bt2::ConstMapValue
,
55 const RunInData
* const runInData
) :
56 bt2::UserSourceComponent
<RunInSource
, RunInSourceMsgIter
, const RunInData
,
57 const RunInData
> {self
, "RUN-IN-SRC"},
58 _mRunInData
{runInData
}
60 this->_addOutputPort("out", *runInData
);
62 if (_mRunInData
->compCtxFunc
) {
63 _mRunInData
->compCtxFunc(self
);
67 static bt2::Value::Shared
_query(const bt2::SelfComponentClass self
, bt2::PrivateQueryExecutor
,
68 bt2c::CStringView
, bt2::ConstValue
,
69 const RunInData
* const data
)
71 if (data
->compClsCtxFunc
) {
72 data
->compClsCtxFunc(self
);
75 return bt2::NullValue
{}.shared();
79 const RunInData
*_mRunInData
;
82 class DummySink
: public bt2::UserSinkComponent
<DummySink
>
85 static constexpr auto name
= "dummy";
87 explicit DummySink(const bt2::SelfSinkComponent self
, bt2::ConstMapValue
, void *) :
88 bt2::UserSinkComponent
<DummySink
>(self
, "DUMMY-SINK")
90 this->_addInputPort("in");
93 void _graphIsConfigured()
95 _mMsgIter
= this->_createMessageIterator(this->_inputPorts()["in"]);
100 return _mMsgIter
->next().has_value();
104 bt2::MessageIterator::Shared _mMsgIter
;
109 void runIn(RunInCompClsQueryFunc compClsCtxFunc
, RunInCompClsInitFunc compCtxFunc
,
110 RunInMsgIterClsInitFunc msgIterCtxFunc
)
112 RunInData data
{std::move(compClsCtxFunc
), std::move(compCtxFunc
), std::move(msgIterCtxFunc
)};
113 const auto srcCompCls
= bt2::SourceComponentClass::create
<RunInSource
>();
115 /* Execute a query (executes `compClsCtxFunc`) */
117 const auto queryExec
= bt_query_executor_create_with_method_data(
118 bt_component_class_source_as_component_class(srcCompCls
->libObjPtr()), "", nullptr,
121 BT_ASSERT(queryExec
);
123 const bt_value
*queryRes
;
124 const auto status
= bt_query_executor_query(queryExec
, &queryRes
);
126 BT_ASSERT(status
== BT_QUERY_EXECUTOR_QUERY_STATUS_OK
);
127 bt_value_put_ref(queryRes
);
128 bt_query_executor_put_ref(queryExec
);
132 const auto graph
= bt2::Graph::create(0);
134 /* Add custom source component (executes `compCtxFunc`) */
135 const auto srcComp
= graph
->addComponent(*srcCompCls
, "the-source", data
);
137 /* Add dummy sink component */
138 const auto sinkComp
=
139 graph
->addComponent(*bt2::SinkComponentClass::create
<DummySink
>(), "the-sink");
142 const auto outPort
= srcComp
.outputPorts()["out"];
145 const auto inPort
= sinkComp
.inputPorts()["in"];
148 graph
->connectPorts(*outPort
, *inPort
);
150 /* Run graph (executes `msgIterCtxFunc`) */
154 void runInCompClsQuery(RunInCompClsQueryFunc func
)
156 runIn(std::move(func
), nullptr, nullptr);
159 void runInCompClsInit(RunInCompClsInitFunc func
)
161 runIn(nullptr, std::move(func
), nullptr);
164 void runInMsgIterClsInit(RunInMsgIterClsInitFunc func
)
166 runIn(nullptr, nullptr, std::move(func
));