libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
bufferrequest.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <functional>
14#include <utility>
15#include <promeki/function.h>
16#include <promeki/namespace.h>
17#include <promeki/error.h>
19#include <promeki/eventloop.h>
20
21PROMEKI_NAMESPACE_BEGIN
22
58class BufferRequest {
59 public:
61 using Callback = Function<void(Error)>;
62
70 BufferRequest() = default;
71
78 explicit BufferRequest(BufferCommand::Ptr cmd) : _cmd(std::move(cmd)) {}
79
88 static BufferRequest resolved(Error err) {
89 BufferRequest r;
90 r._overrideError = err;
91 r._hasOverride = true;
92 return r;
93 }
94
108 static BufferRequest resolved(BufferCommand::Ptr cmd) {
109 if (cmd.isValid()) cmd.modify()->markCompleted();
110 return BufferRequest(std::move(cmd));
111 }
112
129 Error wait(unsigned int timeoutMs = 0) {
130 if (_hasOverride) return _overrideError;
131 if (_cmd.isNull()) return Error::Invalid;
132 const Error waitErr = _cmd.modify()->waitForCompletion(timeoutMs);
133 if (waitErr == Error::Timeout) return Error::Timeout;
134 return _cmd->result;
135 }
136
141 bool isReady() const {
142 if (_hasOverride) return true;
143 return _cmd.isValid() && _cmd->isCompleted();
144 }
145
156 void then(Callback cb) {
157 if (_hasOverride) {
158 EventLoop *loop = EventLoop::current();
159 Error err = _overrideError;
160 if (loop != nullptr) {
161 loop->postCallable(
162 [cb = std::move(cb), err]() mutable { cb(err); });
163 } else {
164 cb(err);
165 }
166 return;
167 }
168 if (_cmd.isNull()) return;
169 _cmd.modify()->setCompletionCallback(std::move(cb), EventLoop::current());
170 }
171
180 void cancel() {
181 _cancelledLocal = true;
182 if (_cmd.isValid()) _cmd.modify()->cancelled.setValue(true);
183 }
184
186 bool isCancelled() const {
187 if (_cancelledLocal) return true;
188 return _cmd.isValid() && _cmd->cancelled.value();
189 }
190
200 BufferCommand::Ptr command() const { return _cmd; }
201
217 template <typename CmdT> const CmdT *commandAs() const {
218 if (_cmd.isNull()) return nullptr;
219 return static_cast<const CmdT *>(_cmd.ptr());
220 }
221
223 bool isValid() const { return _cmd.isValid() || _hasOverride; }
224
225 private:
226 BufferCommand::Ptr _cmd;
227 Error _overrideError = Error::Invalid;
228 bool _hasOverride = false;
229 // Sentinel-path cancellation flag — when there is no
230 // command, cancel() has nothing to forward to, so the
231 // bit lives here. When _cmd is valid, the cmd's own
232 // atomic flag is the source of truth and isCancelled
233 // ORs both.
234 bool _cancelledLocal = false;
235};
236
237PROMEKI_NAMESPACE_END
238
239#endif // PROMEKI_ENABLE_CORE