libzypp 17.37.17
asyncop.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------/
9*
10* This file contains private API, this might break at any time between releases.
11* You have been warned!
12*
13*/
14#ifndef ZYPPNG_ASYNC_ASYNCOP_H_INCLUDED
15#define ZYPPNG_ASYNC_ASYNCOP_H_INCLUDED
16
18#include <zypp-core/zyppng/base/Base>
20#include <zypp-core/zyppng/base/Signals>
21#include <optional>
22#include <memory>
23
24namespace zyppng {
25
26 template <typename Result> struct AsyncOp;
28
29 namespace detail {
30 template <typename T, typename Enable = std::void_t<> >
31 struct has_value_type : public std::false_type{};
32
33 template <typename T>
34 struct has_value_type<T, std::void_t<typename T::value_type>> : public std::true_type {};
35
36 template <typename T>
38
39 template <typename T, typename Enable = void >
40 struct is_asyncop_type : public std::false_type{};
41
42 template <typename T>
43 struct is_asyncop_type<T, std::enable_if_t< std::is_convertible_v<T*, AsyncOp<typename T::value_type>*> >> : public std::true_type{};
44
45 template <typename T>
47
54 template <typename T>
58 >;
59
60 template < typename T>
62 }
63
69 {
70 public:
72 : Exception( "AsyncOp instance not ready" )
73 {}
75 };
77
79 {
80 public:
82 : Exception ("AsyncOp does not support cancelling the operation")
83 {}
85 };
87
88
89 class AsyncOpBase : public Base {
90
91 public:
92
96 virtual bool canCancel () {
97 return false;
98 }
99
108 virtual void cancel () {
110 }
111
116 return _sigStarted;
117 }
118
123 SignalProxy<void( const std::string & /*text*/, int /*current*/, int /*max*/ )> sigProgress () {
124 return _sigProgress;
125 }
126
132 return _sigReady;
133 }
134
135 protected:
138 Signal<void( const std::string & /*text*/, int /*current*/, int /*max*/ )> _sigProgress;
139 };
140
160 template <typename Result>
161 struct AsyncOp : public AsyncOpBase {
162
163 static_assert(!detail::is_async_op_v<Result>, "A async op can never have a async result");
164
165 using value_type = Result;
166 using Ptr = std::shared_ptr<AsyncOp<Result>>;
167
168 AsyncOp () = default;
169
170 AsyncOp ( const AsyncOp &other ) = delete;
171 AsyncOp& operator= ( const AsyncOp &other ) = delete;
172
173 AsyncOp& operator= ( AsyncOp &&other ) noexcept = default;
174 AsyncOp ( AsyncOp &&other ) noexcept = default;
175
176 ~AsyncOp() override{}
177
183 void setReady ( value_type && val ) {
184 if ( _readyCb ) {
185 // use a weak reference to know if `this` was deleted by the callback()
186 auto weak = weak_from_this();
187 _readyCb( std::move( val ) );
188 if ( !weak.expired() )
189 _readyCb = {};
190 }
191 else { //we need to cache the value because no callback is available
192 _maybeValue = std::move(val);
193 _sigReady.emit();
194 }
195 }
196
202 bool isReady () const {
203 return _maybeValue.has_value();
204 }
205
217 template< typename Fun >
218 void onReady ( Fun &&cb ) {
219 this->_readyCb = std::forward<Fun>(cb);
220
221 if ( isReady() ) {
222 // use a weak reference to know if `this` was deleted by the callback()
223 auto weak = weak_from_this();
224
225 _readyCb( std::move( _maybeValue.value()) );
226
227 if ( !weak.expired() ) {
228 // value was passed on, reset the optional
229 _maybeValue.reset();
230
231 // reset the callback, it might be a lambda with captured ressources
232 // that need to be released after returning from the func
233 _readyCb = {};
234 }
235 }
236 }
237
243 if ( !isReady() )
245 return _maybeValue.value();
246 }
247
248 private:
249 std::function<void(value_type &&)> _readyCb;
250 std::optional<value_type> _maybeValue;
251 };
252
253
254 template <typename T>
255 using AsyncOpRef = std::shared_ptr<AsyncOp<T>>;
256
257
265 template <typename Base, typename Result = typename Base::value_type>
267 {
268 template <typename ...Args>
269 void operator ()( Args &&...args ) {
270 assert(!_nestedPipeline);
271 _nestedPipeline = static_cast<Base *>(this)->makePipeline( std::forward<Args>(args)...);
272 _nestedPipeline->onReady([this]( auto &&val ){
273 static_cast<Base *>(this)->setReady( std::forward<decltype(val)>(val) );
274 });
275 }
276
277 private:
279 };
280
281 namespace detail {
282 //A async result that is ready right away
283 template <typename T>
284 struct ReadyResult : public zyppng::AsyncOp< T >
285 {
286 ReadyResult( T &&val ) {
287 this->setReady( std::move(val) );
288 }
289 };
290 }
291
296 template <typename T, bool isAsync = true>
298 if constexpr ( isAsync ) {
299 return std::make_shared<detail::ReadyResult<T>>( std::forward<T>(result) );
300 } else {
301 return result;
302 }
303 }
304
305}
306
307
308
309#endif
Base class for Exception.
Definition Exception.h:153
Exception()
Default ctor.
Definition Exception.cc:94
virtual void cancel()
Definition asyncop.h:108
SignalProxy< void()> sigStarted()
Definition asyncop.h:115
Signal< void()> _sigReady
Definition asyncop.h:137
Signal< void(const std::string &, int, int)> _sigProgress
Definition asyncop.h:138
SignalProxy< void(const std::string &, int, int)> sigProgress()
Definition asyncop.h:123
SignalProxy< void()> sigReady()
Definition asyncop.h:131
virtual bool canCancel()
Definition asyncop.h:96
Signal< void()> _sigStarted
Definition asyncop.h:136
Definition Arch.h:364
typename conditional< B, T, F >::type conditional_t
Definition TypeTraits.h:39
constexpr bool is_async_op_v
Definition asyncop.h:61
std::conjunction< has_value_type< remove_smart_ptr_t< T > >, is_asyncop_type< remove_smart_ptr_t< T > > > is_async_op
Definition asyncop.h:55
constexpr bool has_value_type_v
Definition asyncop.h:37
constexpr bool is_asyncop_type_v
Definition asyncop.h:46
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition asyncop.h:297
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition asyncop.h:255
AsyncOp(AsyncOp &&other) noexcept=default
bool isReady() const
Definition asyncop.h:202
std::optional< value_type > _maybeValue
Definition asyncop.h:250
void setReady(value_type &&val)
Definition asyncop.h:183
Result value_type
Definition asyncop.h:165
value_type & get()
Definition asyncop.h:242
AsyncOp & operator=(const AsyncOp &other)=delete
AsyncOp()=default
std::function< void(value_type &&)> _readyCb
Definition asyncop.h:249
AsyncOp(const AsyncOp &other)=delete
std::shared_ptr< AsyncOp< Result > > Ptr
Definition asyncop.h:166
void onReady(Fun &&cb)
Definition asyncop.h:218
~AsyncOp() override
Definition asyncop.h:176
void operator()(Args &&...args)
Definition asyncop.h:269
AsyncOpRef< Result > _nestedPipeline
Definition asyncop.h:278
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define ZYPP_FWD_DECL_TYPE_WITH_REFS(T)
Definition zyppglobal.h:126