11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
21PROMEKI_NAMESPACE_BEGIN
88 using Callback = Function<void(Error)>;
97 MediaIORequest() =
default;
107 explicit MediaIORequest(MediaIOCommand::Ptr cmd) : _cmd(std::move(cmd)) {}
117 static MediaIORequest resolved(Error err);
132 static MediaIORequest resolved(MediaIOCommand::Ptr cmd);
150 Error wait(
unsigned int timeoutMs = 0);
156 bool isReady()
const;
172 void then(Callback cb);
184 bool isCancelled()
const;
195 MediaIOCommand::Ptr command()
const {
return _cmd; }
222 template <
typename CmdT>
const CmdT *commandAs()
const {
223 if (_cmd.isNull())
return nullptr;
224 return static_cast<const CmdT *
>(_cmd.ptr());
246 MediaIOStats stats()
const {
return _cmd.isValid() ? _cmd->stats : MediaIOStats(); }
249 bool isValid()
const {
return _cmd.isValid() || _hasOverride; }
252 MediaIOCommand::Ptr _cmd;
253 Error _overrideError = Error::Invalid;
254 bool _hasOverride =
false;
260 bool _cancelledLocal =
false;
263inline MediaIORequest MediaIORequest::resolved(Error err) {
265 r._overrideError = err;
266 r._hasOverride =
true;
270inline MediaIORequest MediaIORequest::resolved(MediaIOCommand::Ptr cmd) {
271 if (cmd.isValid()) cmd.modify()->markCompleted();
272 return MediaIORequest(std::move(cmd));
275inline Error MediaIORequest::wait(
unsigned int timeoutMs) {
276 if (_hasOverride)
return _overrideError;
277 if (_cmd.isNull())
return Error::Invalid;
278 const Error waitErr = _cmd.modify()->waitForCompletion(timeoutMs);
279 if (waitErr == Error::Timeout)
return Error::Timeout;
283inline bool MediaIORequest::isReady()
const {
284 if (_hasOverride)
return true;
285 return _cmd.isValid() && _cmd->isCompleted();
288inline void MediaIORequest::then(Callback cb) {
294 EventLoop *loop = EventLoop::current();
295 Error err = _overrideError;
296 if (loop !=
nullptr) {
297 loop->postCallable([cb = std::move(cb), err]()
mutable { cb(err); });
303 if (_cmd.isNull())
return;
304 _cmd.modify()->setCompletionCallback(std::move(cb), EventLoop::current());
307inline void MediaIORequest::cancel() {
308 _cancelledLocal =
true;
309 if (_cmd.isValid()) _cmd.modify()->cancelled.setValue(
true);
312inline bool MediaIORequest::isCancelled()
const {
313 if (_cancelledLocal)
return true;
314 return _cmd.isValid() && _cmd->cancelled.value();