Skip to content

Commit

Permalink
one more
Browse files Browse the repository at this point in the history
  • Loading branch information
victimsnino committed Nov 10, 2024
1 parent 39bd29f commit 90fdb5a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
32 changes: 0 additions & 32 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,38 +247,6 @@ All disposable in RPP should be created and used via `rpp::disposable_wrapper_im
- `disposable_wrapper` - wrapper over `interface_disposable`
- `composite_disposable_wrapper` - wrapper over `interface_composite_disposable`
`disposable_wrapper` is kind of smart_pointer (like std::unique_ptr) but for disposables. So, default constructed wrapper is empty wrapper.
```cpp
auto d = rpp::disposable_wrapper{};
```
Comparing to unique_ptr wrapper's methods are safe to use for empty wrapper.
To construct wrapper you have to use `make` method:
```cpp
auto d = rpp::disposable_wrapper::make<SomeSpecificDisposableType>(some_arguments, to_construct_it);
```

Wrapper has popluar methods to work with disposable: `dispose()`, `is_disposed()` and `add()`/`remove()`/`clear()` (for `interface_composite_disposable`).

In case of you want to obtain original disposable, you can use `lock()` method returning shared_ptr.

`disposable_wrapper` can be strong and weak:
- strong (it is default behavior) is keeping disposable as shared_ptr, so, such an instance of wrapper is extending life-time is underlying disposable
- weak (disposable_wrapper can be forced to weak via `as_weak()` method) is keeping disposable as weak_ptr, so, such an instance of wrapper is **NOT** extendning life-time is underlying disposable

This wrapper is needed for 2 goals:
- provide safe usage of disposables avoiding manual handling of empty/weak disposables
- automatically call `dispose()` during destruction of any disposable

To achieve desired performance RPP is avoiding to returning disposable by default. So, it is why `subscribe` method is not returning anything by default. If you want to attach disposable to observer you can use overloading method accepting disposable as first argument like this:
```cpp
auto d = rpp::composite_disposable_wrapper::make();
observable.subscribe(d, [](int v){});
```
or use `subscribe_with_disposable` method instead
```cpp
auto d = observable.subscribe_with_disposable([](int){});
```

### dynamic_* versions to keep classes as variables
Most of the classes inside rpp library including `observable`, `observer` and others are heavy-templated classes. It means, it could has a lot of template params. In most cases you shouldn't worry about it due to it is purely internal problem.
Expand Down
2 changes: 2 additions & 0 deletions src/rpp/rpp/disposables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
* This can be useful in situations where you need to cancel an ongoing operation or release resources before the observable has completed its work.
* To achieve this in rpp you can pass disposable to `subscribe` method or use `subscribe_with_disposable` overload instead.
*
* @note In rpp all disposables should be created via @link rpp::disposable_wrapper_impl @endlink instead of manually.
*
* @ingroup rpp
*/

Expand Down
39 changes: 35 additions & 4 deletions src/rpp/rpp/disposables/disposable_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,35 @@ namespace rpp::details
namespace rpp
{
/**
* @brief Wrapper to keep disposable. Any disposable have to be created right from this wrapper with help of `make` function.
* @details Member functions is safe to call even if internal disposable is gone. Also it provides access to "raw" shared_ptr and it can be nullptr in case of disposable empty/ptr gone.
* @details Can keep weak_ptr in case of not owning disposable
* @brief Main RPP wrapper over @link disposables @endlink.
* @details This wrapper invented to provide safe and easy-to-use access to disposables. It has next core points:
* - disposable_wrapper is kind of smart_pointer (like std::shared_ptr) but for disposables. So, default constructed wrapper is empty wrapper.
* - disposable_wrapper shares ownership like std::shared_ptr
* - disposable_wrapper's methods is safe to use over empty/gone/disposed/weak disposables.
* - as soon as disposable can be actually "any internal state" it provides access to "raw" shared_ptr and it can be nullptr in case of disposable empty/ptr gone.
* - disposable_wrapper can be strong or weak (same as std::shared_ptr). weak disposable is important, for example, when it keeps observer and this observer should keep this disposable at the same time.
* - disposable_wrapper has popluar methods to work with disposable: `dispose()`, `is_disposed()` and `add()`/`remove()`/`clear()` (for `interface_composite_disposable`).
* - any disposable created via disposable_wrapper would have call `dispose()` during it's destruction (during destruction of last disposable_wrapper owning it)
*
* To construct wrapper you have to use `make` method:
* @code{cpp}
* auto d = rpp::disposable_wrapper::make<SomeSpecificDisposableType>(some_arguments, to_construct_it);
* @endcode
*
* To achieve desired performance RPP is avoiding to returning disposable by default. So, it is why `subscribe` method is not returning anything by default. If you want to attach disposable to observer you can use overloading method accepting disposable as first argument like this:
* @code{cpp}
* auto d = rpp::composite_disposable_wrapper::make();
* observable.subscribe(d, [](int v){});
* @endcode
* or use `subscribe_with_disposable` method instead
* @code{cpp}
* auto d = observable.subscribe_with_disposable([](int){});
* @endcode
*
* @note rpp has 2 predefined disposable_wrappers for most popular cases:
* - @link rpp::disposable_wrapper @endlink is wrapper for simple @link rpp::interface_disposable @endlink
* - @link rpp::composite_disposable_wrapper @endlink is wrapper for @link rpp::composite_disposable @endlink
*
* @ingroup disposables
*/
Expand All @@ -126,7 +152,12 @@ namespace rpp
bool operator==(const disposable_wrapper_impl&) const = default;

/**
* @brief Way to create disposable_wrapper. Passed `TTarget` type can be any type derived from `TDisposable`.
* @brief Main way to create disposable_wrapper. Passed `TTarget` type can be any type derived from `TDisposable`.
* @par Example:
*
* \code{cpp}
* rpp::disposable_wrapper<rpp::interface_composite_disposable>::make<rpp::composite_disposable>();
* \endcode
*/
template<std::derived_from<TDisposable> TTarget = TDefaultMake, typename... TArgs>
requires (std::constructible_from<TTarget, TArgs && ...>)
Expand Down

0 comments on commit 90fdb5a

Please sign in to comment.