Commit | Line | Data |
---|---|---|
484a3024 SM |
1 | /* |
2 | * SPDX-License-Identifier: GPL-2.0-only | |
3 | * | |
4 | * Copyright (C) 2020-2023 EfficiOS, inc. | |
5 | */ | |
6 | ||
7 | #include <utility> | |
8 | ||
484a3024 | 9 | #include "common/assert.h" |
402b595c SM |
10 | #include "cpp-common/bt2/component-class-dev.hpp" |
11 | #include "cpp-common/bt2/component-class.hpp" | |
484a3024 | 12 | |
c802cacb SM |
13 | #include "run-in.hpp" |
14 | ||
cc610c52 PP |
15 | namespace { |
16 | ||
484a3024 SM |
17 | struct RunInData final |
18 | { | |
19 | RunInCompClsQueryFunc compClsCtxFunc; | |
20 | RunInCompClsInitFunc compCtxFunc; | |
21 | RunInMsgIterClsInitFunc msgIterCtxFunc; | |
22 | }; | |
23 | ||
402b595c | 24 | class RunInSource; |
484a3024 | 25 | |
402b595c | 26 | class RunInSourceMsgIter final : public bt2::UserMessageIterator<RunInSourceMsgIter, RunInSource> |
484a3024 | 27 | { |
402b595c SM |
28 | public: |
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"} | |
33 | { | |
34 | const auto& data = port.data<const RunInData>(); | |
484a3024 | 35 | |
402b595c SM |
36 | if (data.msgIterCtxFunc) { |
37 | data.msgIterCtxFunc(self); | |
38 | } | |
484a3024 SM |
39 | } |
40 | ||
402b595c SM |
41 | void _next(bt2::ConstMessageArray&) |
42 | { | |
484a3024 | 43 | } |
402b595c | 44 | }; |
484a3024 | 45 | |
402b595c SM |
46 | class RunInSource final : |
47 | public bt2::UserSourceComponent<RunInSource, RunInSourceMsgIter, const RunInData, | |
48 | const RunInData> | |
484a3024 | 49 | { |
402b595c SM |
50 | public: |
51 | static constexpr auto name = "run-in-src"; | |
52 | ||
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} | |
58 | { | |
59 | this->_addOutputPort("out", *runInData); | |
484a3024 | 60 | |
402b595c SM |
61 | if (_mRunInData->compCtxFunc) { |
62 | _mRunInData->compCtxFunc(self); | |
63 | } | |
484a3024 SM |
64 | } |
65 | ||
402b595c SM |
66 | static bt2::Value::Shared _query(const bt2::SelfComponentClass self, bt2::PrivateQueryExecutor, |
67 | bt2c::CStringView, bt2::ConstValue, | |
68 | const RunInData * const data) | |
69 | { | |
70 | if (data->compClsCtxFunc) { | |
71 | data->compClsCtxFunc(self); | |
72 | } | |
484a3024 | 73 | |
402b595c SM |
74 | return bt2::NullValue {}.shared(); |
75 | } | |
484a3024 | 76 | |
402b595c SM |
77 | private: |
78 | const RunInData *_mRunInData; | |
08b4db41 SM |
79 | }; |
80 | ||
402b595c | 81 | class DummySink : public bt2::UserSinkComponent<DummySink> |
08b4db41 | 82 | { |
402b595c SM |
83 | public: |
84 | static constexpr auto name = "dummy"; | |
cc610c52 | 85 | |
402b595c SM |
86 | explicit DummySink(const bt2::SelfSinkComponent self, bt2::ConstMapValue, void *) : |
87 | bt2::UserSinkComponent<DummySink>(self, "DUMMY-SINK") | |
88 | { | |
89 | this->_addInputPort("in"); | |
90 | } | |
cc610c52 | 91 | |
402b595c SM |
92 | void _graphIsConfigured() |
93 | { | |
94 | _mMsgIter = this->_createMessageIterator(this->_inputPorts()["in"]); | |
95 | } | |
08b4db41 | 96 | |
402b595c SM |
97 | bool _consume() |
98 | { | |
99 | return _mMsgIter->next().has_value(); | |
100 | } | |
cc610c52 | 101 | |
402b595c SM |
102 | private: |
103 | bt2::MessageIterator::Shared _mMsgIter; | |
104 | }; | |
08b4db41 | 105 | |
cc610c52 PP |
106 | } /* namespace */ |
107 | ||
484a3024 SM |
108 | void runIn(RunInCompClsQueryFunc compClsCtxFunc, RunInCompClsInitFunc compCtxFunc, |
109 | RunInMsgIterClsInitFunc msgIterCtxFunc) | |
110 | { | |
111 | RunInData data {std::move(compClsCtxFunc), std::move(compCtxFunc), std::move(msgIterCtxFunc)}; | |
402b595c | 112 | const auto srcCompCls = bt2::SourceComponentClass::create<RunInSource>(); |
484a3024 SM |
113 | |
114 | /* Execute a query (executes `compClsCtxFunc`) */ | |
115 | { | |
116 | const auto queryExec = bt_query_executor_create_with_method_data( | |
402b595c SM |
117 | bt_component_class_source_as_component_class(srcCompCls->libObjPtr()), "", nullptr, |
118 | &data); | |
484a3024 SM |
119 | |
120 | BT_ASSERT(queryExec); | |
121 | ||
122 | const bt_value *queryRes; | |
123 | const auto status = bt_query_executor_query(queryExec, &queryRes); | |
124 | ||
125 | BT_ASSERT(status == BT_QUERY_EXECUTOR_QUERY_STATUS_OK); | |
484a3024 SM |
126 | bt_value_put_ref(queryRes); |
127 | bt_query_executor_put_ref(queryExec); | |
128 | } | |
129 | ||
130 | /* Create graph */ | |
131 | const auto graph = bt_graph_create(0); | |
132 | ||
133 | BT_ASSERT(graph); | |
134 | ||
135 | /* Add custom source component (executes `compCtxFunc`) */ | |
136 | const bt_component_source *srcComp; | |
137 | ||
138 | { | |
139 | const auto status = bt_graph_add_source_component_with_initialize_method_data( | |
402b595c SM |
140 | graph, srcCompCls->libObjPtr(), "the-source", NULL, &data, BT_LOGGING_LEVEL_NONE, |
141 | &srcComp); | |
484a3024 SM |
142 | |
143 | BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK); | |
144 | } | |
145 | ||
08b4db41 | 146 | /* Add dummy sink component */ |
484a3024 SM |
147 | const bt_component_sink *sinkComp; |
148 | ||
149 | { | |
402b595c | 150 | const auto sinkCompCls = bt2::SinkComponentClass::create<DummySink>(); |
08b4db41 | 151 | const auto status = bt_graph_add_sink_component_with_initialize_method_data( |
402b595c SM |
152 | graph, sinkCompCls->libObjPtr(), "the-sink", nullptr, nullptr, BT_LOGGING_LEVEL_NONE, |
153 | &sinkComp); | |
cc610c52 | 154 | |
484a3024 SM |
155 | BT_ASSERT(status == BT_GRAPH_ADD_COMPONENT_STATUS_OK); |
156 | } | |
157 | ||
158 | /* Connect ports */ | |
159 | { | |
160 | const auto outPort = bt_component_source_borrow_output_port_by_name_const(srcComp, "out"); | |
161 | ||
162 | BT_ASSERT(outPort); | |
163 | ||
164 | const auto inPort = bt_component_sink_borrow_input_port_by_name_const(sinkComp, "in"); | |
165 | ||
166 | BT_ASSERT(inPort); | |
167 | ||
168 | const auto status = bt_graph_connect_ports(graph, outPort, inPort, nullptr); | |
169 | ||
170 | BT_ASSERT(status == BT_GRAPH_CONNECT_PORTS_STATUS_OK); | |
171 | } | |
172 | ||
173 | /* Run graph (executes `msgIterCtxFunc`) */ | |
cc610c52 PP |
174 | { |
175 | const auto status = bt_graph_run(graph); | |
484a3024 | 176 | |
cc610c52 PP |
177 | BT_ASSERT(status == BT_GRAPH_RUN_STATUS_OK); |
178 | } | |
484a3024 | 179 | |
cc610c52 | 180 | /* Discard owned objects */ |
484a3024 | 181 | bt_graph_put_ref(graph); |
484a3024 SM |
182 | } |
183 | ||
184 | void runInCompClsQuery(RunInCompClsQueryFunc func) | |
185 | { | |
186 | runIn(std::move(func), nullptr, nullptr); | |
187 | } | |
188 | ||
189 | void runInCompClsInit(RunInCompClsInitFunc func) | |
190 | { | |
191 | runIn(nullptr, std::move(func), nullptr); | |
192 | } | |
193 | ||
194 | void runInMsgIterClsInit(RunInMsgIterClsInitFunc func) | |
195 | { | |
196 | runIn(nullptr, nullptr, std::move(func)); | |
197 | } |