libzypp  17.35.15
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 
24 namespace 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  {}
74  ~AsyncOpNotReadyException() override;
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 
242  value_type &get (){
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
SignalProxy< void(const std::string &, int, int)> sigProgress()
Definition: asyncop.h:123
virtual void cancel()
Definition: asyncop.h:108
Signal< void(const std::string &, int, int)> _sigProgress
Definition: asyncop.h:138
AsyncOp()=default
typename make_void< Ts... >::type void_t
Definition: type_traits.h:12
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:424
Signal< void()> _sigReady
Definition: asyncop.h:137
virtual bool canCancel()
Definition: asyncop.h:96
constexpr bool has_value_type_v
Definition: asyncop.h:37
Definition: Arch.h:363
void setReady(value_type &&val)
Definition: asyncop.h:183
constexpr bool is_asyncop_type_v
Definition: asyncop.h:46
void operator()(Args &&...args)
Definition: asyncop.h:269
std::function< void(value_type &&)> _readyCb
Definition: asyncop.h:249
ZYPP_FWD_DECL_TYPE_WITH_REFS(Context)
~AsyncOpNotReadyException() override
Definition: asyncop.h:76
typename enable_if< B, T >::type enable_if_t
Definition: TypeTraits.h:45
SignalProxy< void()> sigStarted()
Definition: asyncop.h:115
std::optional< value_type > _maybeValue
Definition: asyncop.h:250
typename conditional< B, T, F >::type conditional_t
Definition: TypeTraits.h:39
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition: asyncop.h:297
constexpr bool is_async_op_v
Definition: asyncop.h:61
SignalProxy< void()> sigReady()
Definition: asyncop.h:131
Signal< void()> _sigStarted
Definition: asyncop.h:136
AsyncOp & operator=(const AsyncOp &other)=delete
~AsyncOp() override
Definition: asyncop.h:176
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition: asyncop.h:255
bool isReady() const
Definition: asyncop.h:202
Base class for Exception.
Definition: Exception.h:146
void onReady(Fun &&cb)
Definition: asyncop.h:218
AsyncOpRef< Result > _nestedPipeline
Definition: asyncop.h:278
std::shared_ptr< Base > Ptr
Definition: base.h:65