Doxygen updates#647
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe changes involve extensive updates to documentation files for the ReactivePlusPlus library, including the Changes
Possibly related PRs
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
Doxyfile (2)
2070-2070: Remove redundant USE_PDFLATEX setting.Since
GENERATE_LATEXis set to NO, theUSE_PDFLATEXsetting becomes redundant. Consider removing this line to keep the configuration file clean and avoid potential confusion.-USE_PDFLATEX = NO
Line range hint
855-2070: Overall, these changes streamline the documentation process but may affect completeness.The modifications to the Doxyfile configuration aim to reduce warnings, exclude build artifacts, and focus on HTML output. While these changes can improve the documentation generation process, be cautious about potential loss of information due to disabled warnings and removed output formats. Ensure these changes align with your project's documentation requirements.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (10)
- Doxyfile (5 hunks)
- src/extensions/rppasio/rppasio/fwd.hpp (1 hunks)
- src/extensions/rppgrpc/rppgrpc/client_reactor.hpp (3 hunks)
- src/extensions/rppgrpc/rppgrpc/fwd.hpp (1 hunks)
- src/extensions/rppgrpc/rppgrpc/server_reactor.hpp (3 hunks)
- src/extensions/rppqt/rppqt/fwd.hpp (2 hunks)
- src/rpp/rpp/fwd.hpp (1 hunks)
- src/rpp/rpp/observables/observable.hpp (4 hunks)
- src/rpp/rpp/operators/on_error_resume_next.hpp (1 hunks)
- src/rpp/rpp/operators/retry.hpp (2 hunks)
✅ Files skipped from review due to trivial changes (4)
- src/extensions/rppgrpc/rppgrpc/client_reactor.hpp
- src/extensions/rppgrpc/rppgrpc/fwd.hpp
- src/extensions/rppgrpc/rppgrpc/server_reactor.hpp
- src/rpp/rpp/fwd.hpp
🔇 Additional comments (16)
src/extensions/rppasio/rppasio/fwd.hpp (1)
14-16: LGTM: Documentation group name updated for consistency.The change from "RPPASIO" to "rppasio" in the documentation group name improves consistency in the casing style. This update enhances the overall coherence of the documentation without affecting the code functionality.
src/extensions/rppqt/rppqt/fwd.hpp (2)
14-16: LGTM: Documentation group name updateThe change from
@defgroup rppqt RPPQTto@defgroup rppqt rppqtimproves consistency in naming conventions. This aligns the group name with the actual module name, which is a good practice for maintaining clear and consistent documentation.
25-25: Verify compilation after include reorderingThe reordering of include statements, specifically moving
<rppqt/sources/fwd.hpp>after<rppqt/schedulers/fwd.hpp>, looks fine. This change might be to resolve dependencies or follow a specific include order convention.To ensure this change doesn't introduce any compilation issues, please run the following verification script:
If the script reveals any potential issues, please review and address them accordingly.
✅ Verification successful
Compilation Verification Successful
The reordering of include statements in
src/extensions/rppqt/rppqt/fwd.hppdoes not introduce any compilation issues. All dependencies are correctly resolved, and no circular dependencies were detected.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the include reordering doesn't cause compilation issues # Test: Check if there are any circular dependencies or issues in the include hierarchy rg --type cpp -e '#include.*rppqt/sources/fwd\.hpp' -e '#include.*rppqt/schedulers/fwd\.hpp' src/extensions/rppqt # Test: Look for any potential issues in files that include this header rg --type cpp -e '#include.*rppqt/fwd\.hpp' src/extensions/rppqtLength of output: 575
src/rpp/rpp/operators/on_error_resume_next.hpp (1)
Line range hint
127-131: Approve: Improved accuracy in marble diagram representationThe change from
-1-xto-1-#in the marble diagram for the source observable is a positive improvement. This modification more accurately represents an error occurrence in the source observable, which is crucial for understanding theon_error_resume_nextoperator's behavior.In marble diagrams:
- '#' typically denotes an error
- 'x' usually represents a value emission
This update aligns the visual representation with the operator's description: "If an error occurs, take the result from the Selector and subscribe to that instead." It enhances the documentation's clarity without altering the actual functionality of the operator.
src/rpp/rpp/operators/retry.hpp (3)
142-143: Improved accuracy in marble diagram notationThe change from
xto#in the marble diagram enhances the accuracy of the documentation. The#symbol more precisely represents a termination signal (either completion or error) in standard marble diagram notation. This modification provides a clearer representation of theretryoperator's behavior, showing that it handles termination signals from the source observable.
166-166: Consistent update in infinite retry marble diagramThe change from
xto#in the source observable representation of the infinite retry operator's marble diagram is consistent with the previous update. It accurately depicts the termination signal from the source observable. The unchanged output representation (+-1-1-1-1-1-1-1-1-1-1-1->) correctly illustrates the behavior of an infinite retry, where the operator continues to resubscribe indefinitely upon receiving termination signals.
142-143: Summary: Documentation improvements for retry operatorsThe changes in this file focus on improving the accuracy and consistency of the marble diagrams for both the regular and infinite retry operators. By updating the termination signal representation from
xto#, the documentation now aligns better with standard marble diagram notation. These updates enhance the clarity of the operator's behavior documentation without affecting the underlying functionality. This change is in line with the PR objective of "Doxygen updates" and contributes to better overall documentation quality.Also applies to: 166-166
src/rpp/rpp/observables/observable.hpp (5)
92-93: LGTM: Parameter addition and documentation updateThe addition of the
obsparameter to thesubscribefunction and the corresponding documentation update are clear and consistent with the expected changes.
123-124: LGTM: Parameter addition and documentation updateThe addition of the
observer_strategyparameter to thesubscribefunction and the corresponding documentation update are clear and consistent with the expected changes.
247-249: LGTM: Parameter additions and documentation updateThe addition of
on_next,on_error, andon_completedparameters to thesubscribefunction and the corresponding documentation updates are clear and consistent with the expected changes. These additions enhance the flexibility of the subscription process by allowing separate handlers for different types of notifications.
285-287: LGTM: Parameter additions and documentation updateThe addition of
on_nextandon_completedparameters to this overload of thesubscribefunction and the corresponding documentation updates are clear and consistent with the expected changes. This overload provides a simpler interface for cases where explicit error handling is not required.
Line range hint
1-387: Overall assessment: Consistent and well-documented improvementsThe changes made to the
observableclass in this file consistently enhance its functionality by adding new parameters to various overloads of thesubscribefunction. These additions provide more flexibility in handling different aspects of the subscription process, such as specifying observers and individual handlers for next, error, and completed notifications.The documentation has been thoroughly updated to reflect these changes, maintaining the clarity and usability of the API. The consistency in changes across different overloads helps maintain a coherent interface for users of this class.
These improvements align well with the reactive programming paradigm and should enhance the overall usability of the library.
Doxyfile (4)
1051-1051: Appropriate exclusion of build directory.Excluding the 'build' directory from documentation generation is a good practice. It prevents unnecessary build artifacts from being included in the documentation, keeping it focused on the actual source code.
1142-1142: Verify the functionality of the marble diagram generator.The addition of a filter to process .hpp files with a Python script for generating marble diagrams is a good way to enhance the documentation. However, it's important to ensure that this script is working as expected.
#!/bin/bash # Check if the Python script exists and is executable if [ -f "./ci/generate_marbles.py" ] && [ -x "./ci/generate_marbles.py" ]; then echo "generate_marbles.py script found and is executable." else echo "Warning: generate_marbles.py script not found or not executable." fi # Check if any .hpp files contain marble diagram placeholders grep -rn --include="*.hpp" "MARBLE_DIAGRAM" .
1934-1934: Consider the implications of disabling LaTeX output.Disabling LaTeX output will reduce documentation generation time and output size. However, ensure that LaTeX output is not required for your project's documentation needs, as this format can be useful for generating high-quality printable documentation.
#!/bin/bash # Check if there are any explicit references to LaTeX documentation in the codebase grep -rn --include="*.hpp" --include="*.cpp" --include="*.md" -i "latex.*documentation" .
855-855: Consider the impact of disabling undocumented warnings.Setting
WARN_IF_UNDOCUMENTEDto NO will suppress warnings for undocumented entities. While this reduces the number of warnings, it may lead to incomplete documentation. Consider keeping this enabled to ensure comprehensive documentation coverage.
BENCHMARK RESULTS (AUTOGENERATED)
|
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| Subscribe empty callbacks to empty observable | 299.38 ns | 2.16 ns | 2.16 ns | 1.00 |
| Subscribe empty callbacks to empty observable via pipe operator | 315.71 ns | 2.16 ns | 2.16 ns | 1.00 |
Sources
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| from array of 1 - create + subscribe + immediate | 692.34 ns | 0.31 ns | 0.31 ns | 1.00 |
| from array of 1 - create + subscribe + current_thread | 1054.27 ns | 3.71 ns | 3.71 ns | 1.00 |
| concat_as_source of just(1 immediate) create + subscribe | 2296.33 ns | 142.28 ns | 143.72 ns | 0.99 |
| defer from array of 1 - defer + create + subscribe + immediate | 736.81 ns | 0.31 ns | 0.31 ns | 1.00 |
| interval - interval + take(3) + subscribe + immediate | 2129.49 ns | 59.23 ns | 59.23 ns | 1.00 |
| interval - interval + take(3) + subscribe + current_thread | 2993.01 ns | 32.47 ns | 32.43 ns | 1.00 |
| from array of 1 - create + as_blocking + subscribe + new_thread | 31126.89 ns | 27846.76 ns | 27864.95 ns | 1.00 |
| from array of 1000 - create + as_blocking + subscribe + new_thread | 39464.31 ns | 51880.70 ns | 52579.39 ns | 0.99 |
| concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 3584.14 ns | 217.11 ns | 215.51 ns | 1.01 |
Filtering Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take(1)+subscribe | 1074.90 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+filter(true)+subscribe | 840.11 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+skip(1)+subscribe | 983.18 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,1,2)+distinct_until_changed()+subscribe | 857.41 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+first()+subscribe | 1221.56 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+last()+subscribe | 904.34 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+take_last(1)+subscribe | 1114.19 ns | 18.20 ns | 18.22 ns | 1.00 |
| immediate_just(1,2,3)+element_at(1)+subscribe | 822.05 ns | 0.31 ns | 0.31 ns | 1.00 |
Schedulers
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate scheduler create worker + schedule | 265.31 ns | 2.16 ns | 2.18 ns | 0.99 |
| current_thread scheduler create worker + schedule | 368.45 ns | 5.86 ns | 5.91 ns | 0.99 |
| current_thread scheduler create worker + schedule + recursive schedule | 823.76 ns | 56.42 ns | 55.74 ns | 1.01 |
Transforming Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+map(v*2)+subscribe | 847.61 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+scan(10, std::plus)+subscribe | 897.94 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+flat_map(immediate_just(v*2))+subscribe | 2392.12 ns | 191.70 ns | 193.82 ns | 0.99 |
| immediate_just+buffer(2)+subscribe | 1559.41 ns | 13.89 ns | 13.90 ns | 1.00 |
| immediate_just+window(2)+subscribe + subscsribe inner | 2409.12 ns | 1386.55 ns | 1387.36 ns | 1.00 |
Conditional Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take_while(false)+subscribe | 833.39 ns | - | - | 0.00 |
| immediate_just+take_while(true)+subscribe | 830.20 ns | 0.31 ns | 0.31 ns | 1.00 |
Utility Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(1)+subscribe_on(immediate)+subscribe | 1963.89 ns | 0.31 ns | 0.31 ns | 1.00 |
Combining Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 3616.84 ns | 236.35 ns | 243.10 ns | 0.97 |
| immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 3682.90 ns | 189.75 ns | 192.40 ns | 0.99 |
| immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 178.40 ns | 180.16 ns | 0.99 |
| immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 3653.51 ns | 1253.07 ns | 1268.11 ns | 0.99 |
| immediate_just(1) + zip(immediate_just(2)) + subscribe | 2109.11 ns | 223.41 ns | 225.44 ns | 0.99 |
Subjects
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| publish_subject with 1 observer - on_next | 34.49 ns | 14.64 ns | 14.64 ns | 1.00 |
| subscribe 100 observers to publish_subject | 197181.00 ns | 16582.02 ns | 15803.98 ns | 1.05 |
| 100 on_next to 100 observers to publish_subject | 27212.86 ns | 17085.17 ns | 17191.18 ns | 0.99 |
Scenarios
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| basic sample | 1366.93 ns | 12.65 ns | 12.69 ns | 1.00 |
| basic sample with immediate scheduler | 1328.70 ns | 5.55 ns | 5.55 ns | 1.00 |
Aggregating Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+reduce(10, std::plus)+subscribe | 912.32 ns | 0.31 ns | 0.31 ns | 1.00 |
Error Handling Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 2094.56 ns | 919.32 ns | 927.69 ns | 0.99 |
| create(on_error())+retry(1)+subscribe | 592.52 ns | 122.20 ns | 124.02 ns | 0.99 |
ci-macos
General
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| Subscribe empty callbacks to empty observable | 968.85 ns | 3.93 ns | 3.94 ns | 1.00 |
| Subscribe empty callbacks to empty observable via pipe operator | 966.32 ns | 3.93 ns | 3.95 ns | 0.99 |
Sources
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| from array of 1 - create + subscribe + immediate | 1919.70 ns | 0.23 ns | 0.23 ns | 1.00 |
| from array of 1 - create + subscribe + current_thread | 2404.80 ns | 33.34 ns | 33.30 ns | 1.00 |
| concat_as_source of just(1 immediate) create + subscribe | 5911.42 ns | 427.29 ns | 425.60 ns | 1.00 |
| defer from array of 1 - defer + create + subscribe + immediate | 2164.70 ns | 0.25 ns | 0.23 ns | 1.09 |
| interval - interval + take(3) + subscribe + immediate | 5235.01 ns | 288.12 ns | 112.76 ns | 2.56 |
| interval - interval + take(3) + subscribe + current_thread | 6157.54 ns | 95.70 ns | 95.64 ns | 1.00 |
| from array of 1 - create + as_blocking + subscribe + new_thread | 83115.14 ns | 83480.08 ns | 84514.42 ns | 0.99 |
| from array of 1000 - create + as_blocking + subscribe + new_thread | 88409.27 ns | 91993.31 ns | 85963.15 ns | 1.07 |
| concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 8958.28 ns | 647.55 ns | 589.77 ns | 1.10 |
Filtering Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take(1)+subscribe | 2843.59 ns | 0.24 ns | 0.23 ns | 1.01 |
| immediate_just+filter(true)+subscribe | 2108.57 ns | 0.23 ns | 0.23 ns | 1.00 |
| immediate_just(1,2)+skip(1)+subscribe | 2838.48 ns | 0.23 ns | 0.23 ns | 1.00 |
| immediate_just(1,1,2)+distinct_until_changed()+subscribe | 2112.03 ns | 0.47 ns | 0.47 ns | 1.00 |
| immediate_just(1,2)+first()+subscribe | 3202.73 ns | 0.24 ns | 0.23 ns | 1.01 |
| immediate_just(1,2)+last()+subscribe | 2393.58 ns | 0.23 ns | 0.23 ns | 1.00 |
| immediate_just+take_last(1)+subscribe | 3010.12 ns | 0.23 ns | 0.23 ns | 1.00 |
| immediate_just(1,2,3)+element_at(1)+subscribe | 2283.69 ns | 0.27 ns | 0.23 ns | 1.15 |
Schedulers
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate scheduler create worker + schedule | 848.07 ns | 4.26 ns | 4.24 ns | 1.01 |
| current_thread scheduler create worker + schedule | 1180.83 ns | 36.54 ns | 36.32 ns | 1.01 |
| current_thread scheduler create worker + schedule + recursive schedule | 1988.70 ns | 202.45 ns | 201.58 ns | 1.00 |
Transforming Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+map(v*2)+subscribe | 2107.36 ns | 4.20 ns | 4.44 ns | 0.95 |
| immediate_just+scan(10, std::plus)+subscribe | 2312.08 ns | 0.47 ns | 0.47 ns | 1.00 |
| immediate_just+flat_map(immediate_just(v*2))+subscribe | 5310.10 ns | 514.17 ns | 506.03 ns | 1.02 |
| immediate_just+buffer(2)+subscribe | 2538.38 ns | 64.47 ns | 65.70 ns | 0.98 |
| immediate_just+window(2)+subscribe + subscsribe inner | 5348.45 ns | 2365.36 ns | 2377.09 ns | 1.00 |
Conditional Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take_while(false)+subscribe | 2105.44 ns | - | - | 0.00 |
| immediate_just+take_while(true)+subscribe | 2083.85 ns | 0.24 ns | 0.25 ns | 0.97 |
Utility Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(1)+subscribe_on(immediate)+subscribe | 4928.75 ns | 5.14 ns | 4.90 ns | 1.05 |
Combining Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 7715.34 ns | 612.03 ns | 578.88 ns | 1.06 |
| immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 8553.01 ns | 522.48 ns | 495.82 ns | 1.05 |
| immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 594.46 ns | 564.52 ns | 1.05 |
| immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 8002.86 ns | 1910.69 ns | 2006.10 ns | 0.95 |
| immediate_just(1) + zip(immediate_just(2)) + subscribe | 5149.83 ns | 916.48 ns | 955.53 ns | 0.96 |
Subjects
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| publish_subject with 1 observer - on_next | 77.05 ns | 49.04 ns | 48.72 ns | 1.01 |
| subscribe 100 observers to publish_subject | 347081.00 ns | 40907.23 ns | 38878.74 ns | 1.05 |
| 100 on_next to 100 observers to publish_subject | 58716.92 ns | 21994.74 ns | 19655.15 ns | 1.12 |
Scenarios
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| basic sample | 2772.41 ns | 68.64 ns | 68.95 ns | 1.00 |
| basic sample with immediate scheduler | 2769.45 ns | 18.77 ns | 18.70 ns | 1.00 |
Aggregating Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+reduce(10, std::plus)+subscribe | 2407.14 ns | 0.24 ns | 0.23 ns | 1.02 |
Error Handling Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 6436.51 ns | 3974.24 ns | 3887.46 ns | 1.02 |
| create(on_error())+retry(1)+subscribe | 1805.86 ns | 369.02 ns | 361.20 ns | 1.02 |
ci-ubuntu-clang
General
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| Subscribe empty callbacks to empty observable | 265.02 ns | 1.54 ns | 1.54 ns | 1.00 |
| Subscribe empty callbacks to empty observable via pipe operator | 264.27 ns | 1.54 ns | 1.54 ns | 1.00 |
Sources
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| from array of 1 - create + subscribe + immediate | 555.86 ns | 0.31 ns | 0.31 ns | 1.00 |
| from array of 1 - create + subscribe + current_thread | 807.68 ns | 4.01 ns | 4.02 ns | 1.00 |
| concat_as_source of just(1 immediate) create + subscribe | 2352.10 ns | 184.46 ns | 184.95 ns | 1.00 |
| defer from array of 1 - defer + create + subscribe + immediate | 773.14 ns | 0.31 ns | 0.31 ns | 1.01 |
| interval - interval + take(3) + subscribe + immediate | 2201.47 ns | 58.26 ns | 58.31 ns | 1.00 |
| interval - interval + take(3) + subscribe + current_thread | 3168.55 ns | 30.86 ns | 30.88 ns | 1.00 |
| from array of 1 - create + as_blocking + subscribe + new_thread | 28375.89 ns | 27959.11 ns | 27651.68 ns | 1.01 |
| from array of 1000 - create + as_blocking + subscribe + new_thread | 38583.00 ns | 35644.90 ns | 35632.48 ns | 1.00 |
| concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 3696.91 ns | 303.25 ns | 301.42 ns | 1.01 |
Filtering Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take(1)+subscribe | 1138.10 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+filter(true)+subscribe | 859.66 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+skip(1)+subscribe | 1068.43 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,1,2)+distinct_until_changed()+subscribe | 875.72 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+first()+subscribe | 1360.54 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2)+last()+subscribe | 995.36 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+take_last(1)+subscribe | 1214.58 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just(1,2,3)+element_at(1)+subscribe | 885.85 ns | 0.31 ns | 0.31 ns | 1.00 |
Schedulers
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate scheduler create worker + schedule | 278.74 ns | 1.54 ns | 1.54 ns | 1.00 |
| current_thread scheduler create worker + schedule | 392.79 ns | 4.58 ns | 4.59 ns | 1.00 |
| current_thread scheduler create worker + schedule + recursive schedule | 858.69 ns | 55.65 ns | 56.00 ns | 0.99 |
Transforming Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+map(v*2)+subscribe | 838.44 ns | 0.31 ns | 0.31 ns | 1.00 |
| immediate_just+scan(10, std::plus)+subscribe | 955.48 ns | 0.31 ns | 0.31 ns | 0.99 |
| immediate_just+flat_map(immediate_just(v*2))+subscribe | 2245.25 ns | 229.14 ns | 228.60 ns | 1.00 |
| immediate_just+buffer(2)+subscribe | 1509.83 ns | 14.20 ns | 13.89 ns | 1.02 |
| immediate_just+window(2)+subscribe + subscsribe inner | 2437.04 ns | 932.87 ns | 927.30 ns | 1.01 |
Conditional Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take_while(false)+subscribe | 831.12 ns | - | - | 0.00 |
| immediate_just+take_while(true)+subscribe | 858.12 ns | 0.31 ns | 0.31 ns | 1.00 |
Utility Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(1)+subscribe_on(immediate)+subscribe | 1988.55 ns | 0.31 ns | 0.31 ns | 1.00 |
Combining Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 3234.96 ns | 292.09 ns | 290.77 ns | 1.00 |
| immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 3708.99 ns | 219.32 ns | 211.44 ns | 1.04 |
| immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 198.95 ns | 197.74 ns | 1.01 |
| immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 3359.84 ns | 873.29 ns | 841.34 ns | 1.04 |
| immediate_just(1) + zip(immediate_just(2)) + subscribe | 2235.34 ns | 198.63 ns | 196.80 ns | 1.01 |
Subjects
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| publish_subject with 1 observer - on_next | 54.72 ns | 18.23 ns | 18.22 ns | 1.00 |
| subscribe 100 observers to publish_subject | 216378.40 ns | 15932.69 ns | 15942.96 ns | 1.00 |
| 100 on_next to 100 observers to publish_subject | 46100.96 ns | 20955.16 ns | 17544.75 ns | 1.19 |
Scenarios
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| basic sample | 1311.49 ns | 11.42 ns | 11.42 ns | 1.00 |
| basic sample with immediate scheduler | 1277.56 ns | 6.17 ns | 6.17 ns | 1.00 |
Aggregating Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+reduce(10, std::plus)+subscribe | 994.40 ns | 0.31 ns | 0.31 ns | 1.00 |
Error Handling Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 2176.20 ns | 1016.51 ns | 1006.84 ns | 1.01 |
| create(on_error())+retry(1)+subscribe | 648.05 ns | 159.55 ns | 158.27 ns | 1.01 |
ci-windows
General
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| Subscribe empty callbacks to empty observable | 563.87 ns | 4.02 ns | 4.07 ns | 0.99 |
| Subscribe empty callbacks to empty observable via pipe operator | 576.40 ns | 4.01 ns | 4.02 ns | 1.00 |
Sources
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| from array of 1 - create + subscribe + immediate | 1151.37 ns | 9.72 ns | 9.64 ns | 1.01 |
| from array of 1 - create + subscribe + current_thread | 1451.17 ns | 17.91 ns | 17.90 ns | 1.00 |
| concat_as_source of just(1 immediate) create + subscribe | 3789.97 ns | 250.07 ns | 236.23 ns | 1.06 |
| defer from array of 1 - defer + create + subscribe + immediate | 1247.86 ns | 9.43 ns | 9.43 ns | 1.00 |
| interval - interval + take(3) + subscribe + immediate | 3445.54 ns | 145.56 ns | 145.41 ns | 1.00 |
| interval - interval + take(3) + subscribe + current_thread | 3655.37 ns | 63.67 ns | 65.52 ns | 0.97 |
| from array of 1 - create + as_blocking + subscribe + new_thread | 117900.00 ns | 110200.00 ns | 119700.00 ns | 0.92 |
| from array of 1000 - create + as_blocking + subscribe + new_thread | 128112.50 ns | 127900.00 ns | 135625.00 ns | 0.94 |
| concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 5495.96 ns | 330.44 ns | 314.48 ns | 1.05 |
Filtering Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take(1)+subscribe | 1826.79 ns | 25.30 ns | 25.28 ns | 1.00 |
| immediate_just+filter(true)+subscribe | 1330.69 ns | 24.37 ns | 24.35 ns | 1.00 |
| immediate_just(1,2)+skip(1)+subscribe | 1737.86 ns | 24.07 ns | 24.06 ns | 1.00 |
| immediate_just(1,1,2)+distinct_until_changed()+subscribe | 1330.18 ns | 29.01 ns | 28.99 ns | 1.00 |
| immediate_just(1,2)+first()+subscribe | 2042.15 ns | 22.82 ns | 22.82 ns | 1.00 |
| immediate_just(1,2)+last()+subscribe | 1763.41 ns | 24.07 ns | 24.06 ns | 1.00 |
| immediate_just+take_last(1)+subscribe | 2027.55 ns | 70.83 ns | 69.72 ns | 1.02 |
| immediate_just(1,2,3)+element_at(1)+subscribe | 1326.89 ns | 27.46 ns | 27.44 ns | 1.00 |
Schedulers
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate scheduler create worker + schedule | 499.60 ns | 6.18 ns | 6.18 ns | 1.00 |
| current_thread scheduler create worker + schedule | 648.37 ns | 13.94 ns | 13.89 ns | 1.00 |
| current_thread scheduler create worker + schedule + recursive schedule | 1339.37 ns | 103.58 ns | 101.56 ns | 1.02 |
Transforming Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+map(v*2)+subscribe | 1310.10 ns | 24.37 ns | 24.37 ns | 1.00 |
| immediate_just+scan(10, std::plus)+subscribe | 1448.67 ns | 26.84 ns | 26.84 ns | 1.00 |
| immediate_just+flat_map(immediate_just(v*2))+subscribe | 3463.51 ns | 273.72 ns | 263.84 ns | 1.04 |
| immediate_just+buffer(2)+subscribe | 2632.56 ns | 68.85 ns | 69.77 ns | 0.99 |
| immediate_just+window(2)+subscribe + subscsribe inner | 4057.84 ns | 1315.90 ns | 1305.47 ns | 1.01 |
Conditional Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+take_while(false)+subscribe | 1602.83 ns | 23.14 ns | 23.12 ns | 1.00 |
| immediate_just+take_while(true)+subscribe | 1325.62 ns | 24.37 ns | 24.36 ns | 1.00 |
Utility Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(1)+subscribe_on(immediate)+subscribe | 3461.75 ns | 11.10 ns | 11.10 ns | 1.00 |
Combining Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 5038.60 ns | 315.09 ns | 304.98 ns | 1.03 |
| immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 5463.01 ns | 280.27 ns | 264.78 ns | 1.06 |
| immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 313.48 ns | 304.51 ns | 1.03 |
| immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 5238.18 ns | 951.08 ns | 932.17 ns | 1.02 |
| immediate_just(1) + zip(immediate_just(2)) + subscribe | 3534.42 ns | 572.47 ns | 572.12 ns | 1.00 |
Subjects
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| publish_subject with 1 observer - on_next | 36.57 ns | 20.05 ns | 20.14 ns | 1.00 |
| subscribe 100 observers to publish_subject | 263825.00 ns | 30865.71 ns | 27171.05 ns | 1.14 |
| 100 on_next to 100 observers to publish_subject | 55219.05 ns | 32628.13 ns | 32624.24 ns | 1.00 |
Scenarios
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| basic sample | 1872.46 ns | 101.97 ns | 103.28 ns | 0.99 |
| basic sample with immediate scheduler | 1867.68 ns | 74.08 ns | 73.89 ns | 1.00 |
Aggregating Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| immediate_just+reduce(10, std::plus)+subscribe | 1469.09 ns | 24.99 ns | 24.97 ns | 1.00 |
Error Handling Operators
| name | rxcpp | rpp | prev rpp | ratio |
|---|---|---|---|---|
| create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 2135.10 ns | 245.75 ns | 245.96 ns | 1.00 |
| create(on_error())+retry(1)+subscribe | 1154.03 ns | 191.83 ns | 193.60 ns | 0.99 |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (2)
Readme.md (2)
37-38: Improved clarity in the explanation.The rephrasing enhances the explanation of the library's functionality, making it easier for readers to understand the concept.
Consider replacing "till" with "until" for a more formal tone:
-`repeat`-ing it infinite amount of time till termination event happening. +`repeat`-ing it infinite amount of time until termination event happening.🧰 Tools
🪛 LanguageTool
[style] ~37-~37: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
58-62: Improved comparison with existing libraries.The rephrasing provides a clearer comparison between ReactivePlusPlus and other Reactive Extension libraries, highlighting the advantages of ReactivePlusPlus.
Consider the following minor improvements:
- Change "multi-threaded" to "multithreaded" for consistency with common usage.
- Remove the hyphen in "fully-implemented" as it's not necessary when the adverb ends in 'ly'.
- Fix the typo "itt" to "it" and "casues" to "causes" in the sentence about another-rxcpp.
Apply this diff:
-Reactive programming is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunately, at the moment of creating ReactivePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://github.com/ReactiveX/RxCpp). +Reactive programming is a powerful paradigm for creating multithreaded and real-time applications. Unfortunately, at the moment of creating ReactivePlusPlus, there is only one stable and fully implemented library available - [RxCpp](https://github.com/ReactiveX/RxCpp). -Another implementation is [another-rxcpp](https://github.com/CODIANZ/another-rxcpp) which uses type erasure and `std::function`, but itt casues larger observer/observable size and potentially casues performance issues. +Another implementation is [another-rxcpp](https://github.com/CODIANZ/another-rxcpp) which uses type erasure and `std::function`, but it causes larger observer/observable size and potentially causes performance issues.🧰 Tools
🪛 LanguageTool
[misspelling] ~58-~58: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~58-~58: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- Readme.md (4 hunks)
🧰 Additional context used
🪛 LanguageTool
Readme.md
[style] ~37-~37: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
[misspelling] ~58-~58: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~58-~58: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
🔇 Additional comments (3)
Readme.md (3)
75-75: Enhanced emphasis on ReactivePlusPlus advantages.The rephrasing effectively highlights the key advantages of ReactivePlusPlus, including its modern C++ design, performance focus, and adherence to the "zero-overhead principle". The addition of the link to the principle's definition is particularly valuable for readers who may be unfamiliar with the concept.
91-91: Improved documentation navigation.The update to specify the User Guide as a tutorial enhances the clarity of the documentation structure, making it easier for users to find the appropriate resources for their needs.
Line range hint
1-138: Overall improvement in README clarity and readability.The changes throughout the README file have significantly enhanced its quality:
- Improved explanations of the library's functionality and advantages.
- Clearer comparisons with existing Reactive Extension libraries.
- Better emphasis on the unique selling points of ReactivePlusPlus.
- Enhanced navigation through documentation resources.
These updates make the README more informative and user-friendly without altering the core information about the library.
🧰 Tools
🪛 LanguageTool
[misspelling] ~58-~58: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~58-~58: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
for more information, see https://pre-commit.ci
|
Just curious. |
|
Tip For best results, initiate chat on the files or code changes. @victimsnino, I'd be happy to help provide extensive documentation for the ReactivePlusPlus repository. Below is a detailed overview with examples to assist users in understanding and utilizing the library effectively. ReactivePlusPlus DocumentationIntroductionReactivePlusPlus (rpp) is a reactive programming library for C++20, inspired by RxCpp and ReactiveX. It enables developers to compose asynchronous and event-based programs using observables and LINQ-style query operators. Reactive programming allows for handling data streams and propagating changes efficiently, making it ideal for applications that require responsive and scalable architectures. Key Features
Getting StartedInstallationTo include ReactivePlusPlus in your project, clone the repository and incorporate it into your build system. git clone https://github.com/victimsnino/ReactivePlusPlus.gitInclude the necessary headers in your source files: #include <rpp/rpp.hpp>Basic Concepts
ExamplesCreating an ObservableCreate an observable that emits a sequence of integers: #include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::just(1, 2, 3, 4, 5);
observable.subscribe([](int value) {
std::cout << "Received value: " << value << std::endl;
});
return 0;
}Output: Transforming Data with OperatorsUse the #include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::just(1, 2, 3, 4, 5)
.map([](int value) { return value * 10; });
observable.subscribe([](int value) {
std::cout << "Transformed value: " << value << std::endl;
});
return 0;
}Output: Filtering DataFilter emitted values using the #include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::just(1, 2, 3, 4, 5)
.filter([](int value) { return value % 2 == 0; });
observable.subscribe([](int value) {
std::cout << "Even value: " << value << std::endl;
});
return 0;
}Output: Combining ObservablesCombine observables using the #include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable1 = rpp::source::just(1, 3, 5);
auto observable2 = rpp::source::just(2, 4, 6);
auto merged = observable1.merge_with(observable2);
merged.subscribe([](int value) {
std::cout << "Merged value: " << value << std::endl;
});
return 0;
}Output: Error HandlingHandle errors using the #include <rpp/rpp.hpp>
#include <iostream>
#include <stdexcept>
int main() {
auto observable = rpp::source::create<int>([](auto subscriber) {
subscriber.on_next(1);
subscriber.on_error(std::make_exception_ptr(std::runtime_error("An error occurred")));
})
.on_error_resume_next([]() {
return rpp::source::just(2, 3);
});
observable.subscribe(
[](int value) {
std::cout << "Value: " << value << std::endl;
},
[](std::exception_ptr) {
std::cout << "Error handled" << std::endl;
});
return 0;
}Output: Retry MechanismUse the #include <rpp/rpp.hpp>
#include <iostream>
#include <stdexcept>
int main() {
int attempt = 0;
auto observable = rpp::source::create<int>([&](auto subscriber) {
if (attempt < 2) {
attempt++;
subscriber.on_error(std::make_exception_ptr(std::runtime_error("Transient error")));
} else {
subscriber.on_next(42);
subscriber.on_completed();
}
})
.retry(3);
observable.subscribe(
[](int value) {
std::cout << "Received value: " << value << std::endl;
},
[](std::exception_ptr) {
std::cout << "Error after retries" << std::endl;
});
return 0;
}Output: IntegrationsAsio IntegrationReactivePlusPlus can be integrated with Asio for asynchronous I/O operations: #include <rpp/rpp.hpp>
#include <asio.hpp>
#include <iostream>
int main() {
asio::io_context io_context;
auto timer_observable = rpp::source::create<int>([&](auto subscriber) {
asio::steady_timer timer(io_context, std::chrono::seconds(1));
timer.async_wait([subscriber](const asio::error_code& ec) {
if (!ec) {
subscriber.on_next(1);
subscriber.on_completed();
} else {
subscriber.on_error(std::make_exception_ptr(std::runtime_error(ec.message())));
}
});
});
timer_observable.subscribe([](int value) {
std::cout << "Timer tick: " << value << std::endl;
});
io_context.run();
return 0;
}Output: gRPC IntegrationIntegrate with gRPC for remote procedure calls: // Example placeholder for gRPC integration
// Detailed implementation depends on the specific use caseQt IntegrationUse ReactivePlusPlus with Qt for GUI applications: #include <rppqt/rppqt.hpp>
#include <QPushButton>
#include <QApplication>
#include <iostream>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton button("Click Me");
auto clicks = rppqt::from_signal(&button, &QPushButton::clicked);
clicks.subscribe([]() {
std::cout << "Button clicked!" << std::endl;
});
button.show();
return app.exec();
}Output (Terminal): Advanced TopicsCustom OperatorsCreate custom operators to extend functionality: template<typename Predicate>
auto custom_filter(Predicate predicate) {
return [=](auto upstream) {
return upstream.filter(predicate);
};
}Multithreading and SchedulersManage concurrency using schedulers: #include <rpp/rpp.hpp>
#include <rpp/schedulers/new_thread.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::interval(std::chrono::milliseconds(500))
.take(5)
.observe_on(rpp::schedulers::new_thread());
observable.subscribe([](int value) {
std::cout << "Value on thread: " << std::this_thread::get_id() << " - " << value << std::endl;
});
// Keep the main thread alive to see the output
std::this_thread::sleep_for(std::chrono::seconds(3));
return 0;
}Output: ContributingContributions are welcome! Please follow the contribution guidelines to submit issues or pull requests. Documentation
LicenseReactivePlusPlus is distributed under the MIT License. Feel free to let me know if you need more details or specific examples in any other area. |
|
@coderabbitai, cool. Now write details user guide or tutorial for the whole library and reactive functional programming at all. Write about all parts including observable/observer/operator/scheduler/disposable and explain all complex things |
|
Tip For best results, initiate chat on the files or code changes. @victimsnino, I'd be happy to provide a detailed user guide and tutorial for ReactivePlusPlus, covering all the key components including observables, observers, operators, schedulers, and disposables, as well as explaining complex concepts in reactive functional programming. ReactivePlusPlus User Guide and TutorialIntroduction to Reactive ProgrammingReactive programming is a paradigm that focuses on asynchronous data streams and the propagation of change. It allows developers to build applications that are:
In reactive programming, data is modeled as streams that can be observed and processed. This approach is particularly powerful for handling real-time updates, user interactions, and asynchronous tasks. About ReactivePlusPlus (rpp)ReactivePlusPlus (rpp) is a modern C++20 library inspired by RxCpp and ReactiveX. It brings reactive programming to C++ with a focus on performance and ease of use. rpp provides a rich set of tools for working with asynchronous data streams, allowing developers to compose complex event-driven systems. Key Components:
Getting StartedInstallationClone the ReactivePlusPlus repository and include it in your project. git clone https://github.com/victimsnino/ReactivePlusPlus.gitInclude the necessary headers: #include <rpp/rpp.hpp>Ensure your project is set up to use C++20 features. Core ConceptsObservablesAn Observable emits a sequence of values over time. It acts as a data producer. Creating Observables
Subscribing to ObservablesTo receive items from an observable, an observer subscribes to it. observable.subscribe(
[](int value) { /* on_next handler */ },
[](std::exception_ptr e) { /* on_error handler */ },
[]() { /* on_completed handler */ }
);Example: observable.subscribe([](int value) {
std::cout << "Received: " << value << std::endl;
});Output: ObserversAn Observer consumes data emitted by an observable. It implements the following handlers:
Custom Observerauto observer = rpp::observer(
[](int value) {
std::cout << "Value: " << value << std::endl;
},
[](std::exception_ptr e) {
try {
std::rethrow_exception(e);
} catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}
},
[]() {
std::cout << "Completed" << std::endl;
}
);Subscribing with Observer: observable.subscribe(observer);OperatorsOperators transform, filter, and compose observables, allowing complex data manipulations. Common Operators
Operator ChainingOperators can be chained to create complex data pipelines. Example: auto processed = rpp::source::range(1, 10)
.filter([](int value) { return value % 2 != 0; }) // Odd numbers
.map([](int value) { return value * value; }); // Squares
processed.subscribe([](int value) {
std::cout << "Processed Value: " << value << std::endl;
});Output: SchedulersSchedulers control the threading and timing of observable sequences. Scheduler Types
Using SchedulersSpecify Scheduler on Observable Creation: auto observable = rpp::source::interval(
std::chrono::milliseconds(500),
rpp::schedulers::new_thread()
);Observe On a Specific Scheduler: observable.observe_on(rpp::schedulers::new_thread())
.subscribe([](int value) {
std::cout << "Received on thread: " << std::this_thread::get_id()
<< " value: " << value << std::endl;
});DisposablesA Disposable represents a subscription that can be disposed to prevent further emissions and clean up resources. Managing Subscriptionsauto subscription = observable.subscribe([](int value) {
std::cout << "Value: " << value << std::endl;
});
// Dispose of the subscription to stop receiving data
subscription.dispose();Advanced TopicsError HandlingReactivePlusPlus provides operators to manage and recover from errors.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (4)
Readme.md (4)
37-39: Excellent addition of explanatory noteThe added note block significantly enhances the understanding of the code example. It provides a clear and concise explanation of each operator's functionality, which is very helpful for readers.
However, there's a minor grammatical issue that could be improved:
Consider revising this phrase for better clarity:
- `repeat`-ing it infinite amount of time till termination event happening. + `repeat`-ing it an infinite number of times until a termination event occurs.🧰 Tools
🪛 LanguageTool
[style] ~39-~39: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
77-77: Excellent emphasis on performance and zero-overhead principleThe updated text effectively highlights the key advantages of ReactivePlusPlus, particularly its adherence to the zero-overhead principle and its performance benefits. The addition of the link to continuous benchmarking results is a great way to support these claims with concrete data.
To further improve clarity, consider this minor suggestion:
- Main advantages of ReactivePlusPlus are that it is written in Modern C++ with Performance and Usage in mind. v2 written to follow [**"zero-overhead principle"**](https://en.cppreference.com/w/cpp/language/Zero-overhead_principle) As a result it is fast, readable, easy to use and well-documented. + The main advantages of ReactivePlusPlus are that it is written in Modern C++ with performance and usability in mind. Version 2 is designed to follow the [**"zero-overhead principle"**](https://en.cppreference.com/w/cpp/language/Zero-overhead_principle). As a result, it is fast, readable, easy to use, and well-documented.
Line range hint
85-89: Excellent addition of compiler support informationThe new "IMPORTANT" note block is a crucial addition to the README. It clearly specifies the minimum supported compiler versions for different platforms, which is essential information for potential users of the library.
To improve readability, consider this minor formatting suggestion:
>[!IMPORTANT] > ReactivePlusPlus is library for C++20. So, it works only on compilers that supports most C++20 features. List of minimal supported compilers: -> - (ubuntu) gcc-10 -> - (ubuntu) clang-11 -> - (windows) visual studio 2022 -> - (macos) Apple Clang 14 +> - Ubuntu: gcc-10 or clang-11 +> - Windows: Visual Studio 2022 +> - macOS: Apple Clang 14This format makes the information more scannable and consistent in presentation.
Line range hint
1-146: Overall excellent improvements to the READMEThe changes made to this README file significantly enhance its quality and usefulness. Key improvements include:
- Addition of documentation badges for quick access to resources.
- Clearer explanations of code examples.
- More detailed and balanced comparisons with existing libraries.
- Emphasis on performance advantages and the zero-overhead principle.
- Clear specification of compiler support.
- Improved clarity in describing documentation resources.
These updates make the README more informative, user-friendly, and effective in showcasing the advantages of ReactivePlusPlus.
To finalize these excellent changes:
- Please address the minor grammatical and formatting suggestions mentioned in previous comments.
- Consider having another team member proofread the document to catch any remaining typos or unclear phrasings.
Great work on improving this crucial documentation!
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- Readme.md (5 hunks)
🧰 Additional context used
🪛 LanguageTool
Readme.md
[style] ~39-~39: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
[misspelling] ~60-~60: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~60-~60: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
🔇 Additional comments (2)
Readme.md (2)
9-11: Great addition of documentation badges!The new badges for User Guide, API Reference, and Benchmarks are excellent additions. They provide quick and easy access to key documentation resources, which will be very helpful for both new users and contributors.
93-93: Improved clarity in documentation descriptionThe update to refer to the User Guide as a "Tutorial" is a good change. It provides a clearer indication of the document's nature, suggesting a more hands-on and practical approach. This can help users better understand what to expect from this resource.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (3)
Readme.md (3)
37-39: Excellent addition of explanatory noteThe new note provides valuable context for understanding the code example, which is very helpful for users. The use of markdown quote syntax also improves readability.
Consider a minor grammatical improvement:
- `repeat`-ing it infinite amount of time till termination event happening. + `repeat`-ing it an infinite number of times until a termination event occurs.🧰 Tools
🪛 LanguageTool
[style] ~39-~39: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
77-77: Excellent summary of ReactivePlusPlus advantagesThe revised text effectively highlights the key strengths of ReactivePlusPlus, emphasizing its modern C++ design, performance focus, and adherence to the "zero-overhead principle". The mention of continuous benchmarking results adds credibility to these claims.
There's a minor typo to correct:
- continous benchmarking results + continuous benchmarking results
Line range hint
1-138: Overall excellent improvements to the READMEThe changes made to the README significantly enhance its quality and informativeness. The addition of new badges, clearer explanations of code examples, and more detailed comparisons with existing libraries provide valuable information for users and potential contributors.
To perfect the document:
- Consider doing a final proofreading pass to catch any remaining typos or grammatical issues.
- Ensure consistent capitalization of "ReactivePlusPlus" throughout the document (e.g., avoid "ReactivePlusPlus" vs "ReactivePlusPlus").
- Double-check that all links are correct and up-to-date.
These minor refinements will further polish an already greatly improved README.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- Readme.md (5 hunks)
🧰 Additional context used
🪛 LanguageTool
Readme.md
[style] ~39-~39: Consider using the more formal “until”.
Context: ...repeat-ing it infinite amount of time till termination event happening. It emits v...(TILL)
[misspelling] ~60-~60: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~60-~60: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
🔇 Additional comments (3)
Readme.md (3)
9-11: Great addition of resource badges!The new badges for User guide, API Reference, and Benchmarks provide quick and easy access to important documentation resources. This improvement enhances the readme's usability and helps users find essential information more efficiently.
93-93: Improved documentation descriptionThe clarification that the User Guide also serves as a tutorial is helpful. This change provides users with a better understanding of the resource's content and purpose, potentially improving their learning experience with ReactivePlusPlus.
Line range hint
1-138: Changes align with PR objectives, but consider reviewing additional filesThe improvements to the README are consistent with the PR title "Doxygen updates" and contribute to enhancing the documentation. However, the AI summary mentioned modifications to documentation settings and comments across multiple files.
To ensure a comprehensive review:
- Verify if there are other files changed in this PR that require review.
- If additional files exist, ensure they are consistent with the changes made in the README.
You can use the following script to check for other modified files:
This will help ensure that all relevant changes are reviewed and consistent with the PR objectives.
✅ Verification successful
Multiple Files Modified: Ensure Comprehensive Review
The PR includes changes to several files beyond
Readme.md, such as configuration files, build scripts, and test suites. To ensure all modifications align with the PR objectives:
Review configuration and build-related files:
.clang-format.github/workflows/analyzers.ymlCMakeLists.txtcmake/dependencies.cmakeconanfile.pysonar-project.propertiesExamine changes in the test suite:
- All files under
src/tests/Ensure that these modifications maintain consistency and adhere to project standards.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: List all modified files in the PR # Test: List modified files. Expect: List of changed files, including Readme.md git diff --name-only HEAD~1 HEADLength of output: 2140
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## v2 #647 +/- ##
=======================================
Coverage 98.27% 98.27%
=======================================
Files 154 154
Lines 7670 7670
=======================================
Hits 7538 7538
Misses 132 132 ☔ View full report in Codecov by Sentry. |
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (5)
HACKING.md (1)
Line range hint
44-50: LGTM! Consider adding a note about user-specific presets.The changes to the
CMakeUserPresets.jsonexample and the accompanying explanation improve flexibility and clarity. Users can now more easily understand how to inherit from base presets.Consider adding a brief note explaining that
CMakeUserPresets.jsonis git-ignored and meant for user-specific configurations. This could help reinforce the purpose of this file for new contributors.Also applies to: 72-73
BUILDING.md (3)
80-81: Improve grammar and maintain consistent formattingThe additional information about Qt and gRPC targets is valuable. However, there are some grammatical issues and inconsistent formatting. Consider the following improvements:
- Fix the grammar and word order.
- Maintain consistent indentation with the previous list item.
Apply this diff to address these issues:
- - `RPP::rppqt` - additional INTERFACE target to extend functionality for QT. rppqt doesn't include QT or even doesn't link with that itself. - - `RPP::rppgrpc` - additional INTERFACE target to extend functionality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. + - `RPP::rppqt` - additional INTERFACE target to extend functionality for Qt. rppqt doesn't include Qt or even link with it. + - `RPP::rppgrpc` - additional INTERFACE target to extend functionality for gRPC. rppgrpc doesn't include gRPC or even link with it.🧰 Tools
🪛 LanguageTool
[grammar] ~80-~80: Did you mean “doesn't even”?
Context: ...ity for QT. rppqt doesn't include QT or even doesn't link with that itself. - `RPP::rppgrpc...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~81-~81: Possible missing comma found.
Context: ...ality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~81-~81: Did you mean “doesn't even”?
Context: ...r GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. Example usage: ...(DO_NOT_EVEN_WORD_ORDER)
🪛 Markdownlint
80-80: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
81-81: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
103-104: Fix typo and LGTMThe additional information about including RPP modules is helpful. However, there's a minor typo that should be corrected.
Apply this diff to fix the typo:
-to include whole library functionality and don't worry about includes. (same can be applied to rppgrpc or rppqt modules) -Also you can include only forwardings for everyting +to include whole library functionality and don't worry about includes. (same can be applied to rppgrpc or rppqt modules) +Also you can include only forwardings for everythingOther than that, the content is informative and valuable for users.
Line range hint
1-124: Add missing build options to the listThe documentation has been updated with valuable information about new modules and targets. However, the new build options mentioned in the PR summary are missing from the list of build options. To ensure completeness, please add the following options to the list:
Add the following build options to the list (around line 20):
- `RPP_BUILD_QT_CODE` - (ON/OFF) build QT related code (examples/tests)(rppqt module doesn't require this one) (default OFF) - requires QT5/6 to be installed +- `RPP_BUILD_GRPC_CODE` - (ON/OFF) build GRPC related code (examples/tests)(rppgrpc module doesn't require this one) (default OFF) - requires grpc++/protobuf to be installed +- `RPP_BUILD_ASIO_CODE` - (ON/OFF) build RPPASIO related code (examples/tests)(rppasio module doesn't require this one) (default OFF) - requires asio to be installedThis addition will provide users with complete information about all available build options.
🧰 Tools
🪛 LanguageTool
[grammar] ~80-~80: Did you mean “doesn't even”?
Context: ...ity for QT. rppqt doesn't include QT or even doesn't link with that itself. - `RPP::rppgrpc...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~81-~81: Possible missing comma found.
Context: ...ality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~81-~81: Did you mean “doesn't even”?
Context: ...r GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. Example usage: ...(DO_NOT_EVEN_WORD_ORDER)
🪛 Markdownlint
77-77: Expected: dash; Actual: asterisk
Unordered list style(MD004, ul-style)
78-78: Expected: dash; Actual: asterisk
Unordered list style(MD004, ul-style)
79-79: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
80-80: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
81-81: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
Readme.md (1)
37-40: Improved explanation and fixed typoThe refined description of ReactivePlusPlus provides a clearer understanding of its purpose. The typo fix in the example code is also good.
Consider adding a brief explanation of what reactive programming is for newcomers to the concept. This could help broaden the appeal of the library.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
- BUILDING.md (3 hunks)
- HACKING.md (3 hunks)
- Readme.md (6 hunks)
🧰 Additional context used
🪛 LanguageTool
BUILDING.md
[grammar] ~80-~80: Did you mean “doesn't even”?
Context: ...ity for QT. rppqt doesn't include QT or even doesn't link with that itself. - `RPP::rppgrpc...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~81-~81: Possible missing comma found.
Context: ...ality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~81-~81: Did you mean “doesn't even”?
Context: ...r GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. Example usage: ...(DO_NOT_EVEN_WORD_ORDER)
HACKING.md
[uncategorized] ~73-~73: A punctuation mark might be missing here.
Context: ... with the name of some base preset fromCMakePresets.json...(AI_EN_LECTOR_MISSING_PUNCTUATION)
Readme.md
[misspelling] ~61-~61: This word is normally spelled as one.
Context: ...ing is a powerful paradigm for creating multi-threaded and real-time applications. Unfortunate...(EN_COMPOUNDS_MULTI_THREADED)
[uncategorized] ~61-~61: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’.
Context: ...ePlusPlus, there is only one stable and fully-implemented library available - [RxCpp](https://git...(HYPHENATED_LY_ADVERB_ADJECTIVE)
🪛 Markdownlint
BUILDING.md
80-80: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
81-81: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
🔇 Additional comments (5)
HACKING.md (1)
110-111: Please clarify the removal of formatting and spell-checking targets.The description for the
coveragetarget has been simplified, which may reduce clarity for new contributors. Additionally, the sections forformat-check,format-fix,spell-check, andspell-fixtargets have been removed.Could you please clarify:
- Are the formatting and spell-checking tools still part of the development workflow? If so, where can contributors find information about these tools?
- For the
coveragetarget, consider adding a brief explanation of how to interpret or view the processed coverage data.To verify the current state of these tools in the project, we can run the following script:
BUILDING.md (2)
33-33: LGTM: Clear information about default modulesThis addition provides valuable information to users about the default INTERFACE modules provided by the library. It's concise and accurate.
89-93: LGTM: Improved example with new targetThe updated example now includes the new
RPP::rppgrpctarget and has improved formatting for better readability. This change provides users with a clear and up-to-date example of how to link with RPP targets.Readme.md (2)
9-11: Great addition of resource badges!The new badges for User Guide, API Reference, and Benchmarks provide quick access to important resources. This improvement enhances the README's usefulness for users.
94-95: Improved documentation links and compiler informationThe updates to the documentation links, particularly specifying the User Guide as a tutorial, will help users navigate the resources more effectively. The added note about C++20 compiler compatibility is crucial information for potential users and contributors.
These changes significantly improve the README's usefulness and clarity.
Also applies to: 97-107
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (10)
BUILDING.md (3)
33-33: LGTM! Consider improving formatting for consistency.The addition of new build options (RPP_BUILD_SFML_CODE, RPP_BUILD_QT_CODE, RPP_BUILD_GRPC_CODE, and RPP_BUILD_ASIO_CODE) enhances the flexibility of the build process. Setting them to OFF by default is a good choice for backward compatibility.
For consistency, consider formatting the new options in the same style as the existing ones:
- `RPP_BUILD_SFML_CODE` - (ON/OFF) build RPP code related to SFML (default OFF) - requires SFML to be installed - `RPP_BUILD_QT_CODE` - (ON/OFF) build QT related code (examples/tests) (default OFF) - requires QT5/6 to be installed - `RPP_BUILD_GRPC_CODE` - (ON/OFF) build GRPC related code (examples/tests) (default OFF) - requires grpc++/protobuf to be installed - `RPP_BUILD_ASIO_CODE` - (ON/OFF) build RPPASIO related code (examples/tests) (default OFF) - requires asio to be installed
80-82: LGTM! Consider improving grammar in target descriptions.The addition of new targets
RPP::rppasioandRPP::rppgrpcis consistent with the new build options. The clarification about not including or linking with respective libraries is valuable information for users.Consider revising the grammar in the target descriptions:
- `RPP::rppqt` - additional INTERFACE target to extend functionality for QT. rppqt doesn't include QT or even link with it. - `RPP::rppasio` - additional INTERFACE target to extend functionality for ASIO. rppasio doesn't include boost::asio or even link with it. - `RPP::rppgrpc` - additional INTERFACE target to extend functionality for GRPC. rppgrpc doesn't include GRPC or even link with it.🧰 Tools
🪛 LanguageTool
[grammar] ~80-~80: Did you mean “doesn't even”?
Context: ...ity for QT. rppqt doesn't include QT or even doesn't link with that itself. - `RPP::rppasio...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~81-~81: Possible missing comma found.
Context: ...or ASIO. rppasio doesn't include boost::asio or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~81-~81: Did you mean “doesn't even”?
Context: ... rppasio doesn't include boost::asio or even doesn't link with that itself. - `RPP::rppgrpc...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~82-~82: Possible missing comma found.
Context: ...ality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~82-~82: Did you mean “doesn't even”?
Context: ...r GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. Example usage: ...(DO_NOT_EVEN_WORD_ORDER)
🪛 Markdownlint
80-80: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
81-81: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
82-82: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
105-106: LGTM! Consider improving grammar and formatting in usage instructions.The addition of information about including rppgrpc or rppqt modules is helpful for users.
Consider the following improvements:
Add "the" before "whole library functionality":
to include the whole library functionality and don't worry about includes.Add a comma after "modules)":
(same can be applied to rppgrpc or rppqt modules), Also you can include only forwardings for everythingFix the typo "everyting" to "everything":
Also you can include only forwardings for everythingConsider breaking the last sentence into two for better readability:
Also, you can include only forwardings for everything. To avoid including "everything", you can just include some interested part of code (or forward it as well)🧰 Tools
🪛 LanguageTool
[uncategorized] ~105-~105: You might be missing the article “the” here.
Context: ...p #include <rpp/rpp.hpp> ``` to include whole library functionality and don't worry a...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~105-~105: A comma might be missing here.
Context: ...be applied to rppgrpc or rppqt modules) Also you can include only forwardings for ev...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
src/rpp/rpp/operators/switch_on_next.hpp (1)
174-174: Consider the implications of changing@warningto@noteThe documentation tag for the include directive has been changed from
@warningto@note. While this change might seem minor, it could affect how users perceive the importance of including the correct header file.Questions to consider:
- Was the original
@warningtag used to emphasize the importance of including the correct header?- Does changing to
@noteadequately convey the necessity of this include directive?- Is this change consistent with the documentation style used in other parts of the library?
Please clarify the reasoning behind this change to ensure it aligns with the overall documentation strategy of the ReactivePlusPlus library.
Readme.md (3)
38-40: Improved clarity in ReactivePlusPlus descriptionThe refined description of ReactivePlusPlus provides a clearer understanding of the library's purpose and its relation to C++20. The correction of the typo in the code example enhances readability.
Consider adding a brief explanation of what reactive programming is for newcomers to the concept. This could be a single sentence or a link to a more detailed explanation.
43-46: Expanded supported modules and improved readabilityThe addition of GRPC and boost::asio modules to the list of supported integrations enhances the library's appeal and demonstrates its versatility. The restructured list improves readability.
Consider adding a brief description of what each module enables or links to example use cases to help users understand the benefits of each integration.
42-42: Minor grammatical improvement suggestionConsider adding a comma after "Also" at the beginning of this line for improved readability:
- Also RPP supports out of box: + Also, RPP supports out of box:This change aligns with standard English punctuation rules for introductory words or phrases.
🧰 Tools
Also RPP supports out of box: - QT as rppqt...🪛 LanguageTool
[uncategorized] ~42-~42: A comma may be missing after the conjunctive/linking adverb ‘Also’.
Context: ... just printing to console.(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
Doxyfile (2)
855-855: Consider the impact of disabling undocumented warnings.Setting
WARN_IF_UNDOCUMENTEDto NO will suppress warnings for undocumented entities. While this reduces noise in the documentation output, it may lead to less comprehensive documentation. Ensure this aligns with your project's documentation standards.
870-870: Be aware of the implications of disabling incomplete documentation warnings.Setting
WARN_IF_INCOMPLETE_DOCto NO will suppress warnings for incomplete function parameter documentation. This might result in less detailed documentation. Ensure this decision aligns with your team's documentation practices.
src/rpp/rpp/operators/debounce.hpp (1)
Line range hint
53-53: Nitpick: Rename variableneed_to_scheduledtoneeds_to_be_scheduledIn the
emplace_safemethod, the variable nameneed_to_scheduledis grammatically incorrect. Renaming it toneeds_to_be_scheduledenhances readability and clarity.Apply this diff to rename the variable:
-const bool need_to_scheduled = !m_time_when_value_should_be_emitted.has_value(); +const bool needs_to_be_scheduled = !m_time_when_value_should_be_emitted.has_value();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (47)
- BUILDING.md (3 hunks)
- Doxyfile (6 hunks)
- Readme.md (5 hunks)
- src/examples/rpp/doxygen/interval.cpp (2 hunks)
- src/examples/rpp/doxygen/take_until.cpp (2 hunks)
- src/rpp/rpp/disposables/interface_disposable.hpp (1 hunks)
- src/rpp/rpp/observables/observable.hpp (7 hunks)
- src/rpp/rpp/observers/observer.hpp (2 hunks)
- src/rpp/rpp/operators/buffer.hpp (1 hunks)
- src/rpp/rpp/operators/combine_latest.hpp (2 hunks)
- src/rpp/rpp/operators/concat.hpp (1 hunks)
- src/rpp/rpp/operators/debounce.hpp (1 hunks)
- src/rpp/rpp/operators/delay.hpp (1 hunks)
- src/rpp/rpp/operators/distinct_until_changed.hpp (1 hunks)
- src/rpp/rpp/operators/element_at.hpp (1 hunks)
- src/rpp/rpp/operators/filter.hpp (1 hunks)
- src/rpp/rpp/operators/finally.hpp (1 hunks)
- src/rpp/rpp/operators/first.hpp (1 hunks)
- src/rpp/rpp/operators/flat_map.hpp (1 hunks)
- src/rpp/rpp/operators/group_by.hpp (1 hunks)
- src/rpp/rpp/operators/last.hpp (1 hunks)
- src/rpp/rpp/operators/map.hpp (1 hunks)
- src/rpp/rpp/operators/merge.hpp (3 hunks)
- src/rpp/rpp/operators/multicast.hpp (2 hunks)
- src/rpp/rpp/operators/observe_on.hpp (1 hunks)
- src/rpp/rpp/operators/on_error_resume_next.hpp (1 hunks)
- src/rpp/rpp/operators/publish.hpp (1 hunks)
- src/rpp/rpp/operators/reduce.hpp (2 hunks)
- src/rpp/rpp/operators/repeat.hpp (2 hunks)
- src/rpp/rpp/operators/retry.hpp (2 hunks)
- src/rpp/rpp/operators/retry_when.hpp (1 hunks)
- src/rpp/rpp/operators/scan.hpp (2 hunks)
- src/rpp/rpp/operators/skip.hpp (1 hunks)
- src/rpp/rpp/operators/start_with.hpp (3 hunks)
- src/rpp/rpp/operators/subscribe_on.hpp (1 hunks)
- src/rpp/rpp/operators/switch_on_next.hpp (1 hunks)
- src/rpp/rpp/operators/take.hpp (1 hunks)
- src/rpp/rpp/operators/take_last.hpp (1 hunks)
- src/rpp/rpp/operators/take_until.hpp (1 hunks)
- src/rpp/rpp/operators/take_while.hpp (1 hunks)
- src/rpp/rpp/operators/throttle.hpp (1 hunks)
- src/rpp/rpp/operators/timeout.hpp (2 hunks)
- src/rpp/rpp/operators/window.hpp (1 hunks)
- src/rpp/rpp/operators/window_toggle.hpp (1 hunks)
- src/rpp/rpp/operators/with_latest_from.hpp (2 hunks)
- src/rpp/rpp/operators/zip.hpp (2 hunks)
- src/rpp/rpp/sources/concat.hpp (2 hunks)
✅ Files skipped from review due to trivial changes (38)
- src/examples/rpp/doxygen/interval.cpp
- src/examples/rpp/doxygen/take_until.cpp
- src/rpp/rpp/disposables/interface_disposable.hpp
- src/rpp/rpp/observers/observer.hpp
- src/rpp/rpp/operators/buffer.hpp
- src/rpp/rpp/operators/combine_latest.hpp
- src/rpp/rpp/operators/concat.hpp
- src/rpp/rpp/operators/delay.hpp
- src/rpp/rpp/operators/distinct_until_changed.hpp
- src/rpp/rpp/operators/element_at.hpp
- src/rpp/rpp/operators/filter.hpp
- src/rpp/rpp/operators/finally.hpp
- src/rpp/rpp/operators/first.hpp
- src/rpp/rpp/operators/flat_map.hpp
- src/rpp/rpp/operators/group_by.hpp
- src/rpp/rpp/operators/last.hpp
- src/rpp/rpp/operators/map.hpp
- src/rpp/rpp/operators/merge.hpp
- src/rpp/rpp/operators/multicast.hpp
- src/rpp/rpp/operators/observe_on.hpp
- src/rpp/rpp/operators/publish.hpp
- src/rpp/rpp/operators/reduce.hpp
- src/rpp/rpp/operators/repeat.hpp
- src/rpp/rpp/operators/retry_when.hpp
- src/rpp/rpp/operators/scan.hpp
- src/rpp/rpp/operators/skip.hpp
- src/rpp/rpp/operators/start_with.hpp
- src/rpp/rpp/operators/subscribe_on.hpp
- src/rpp/rpp/operators/take.hpp
- src/rpp/rpp/operators/take_last.hpp
- src/rpp/rpp/operators/take_until.hpp
- src/rpp/rpp/operators/take_while.hpp
- src/rpp/rpp/operators/throttle.hpp
- src/rpp/rpp/operators/window.hpp
- src/rpp/rpp/operators/window_toggle.hpp
- src/rpp/rpp/operators/with_latest_from.hpp
- src/rpp/rpp/operators/zip.hpp
- src/rpp/rpp/sources/concat.hpp
🚧 Files skipped from review as they are similar to previous changes (3)
- src/rpp/rpp/observables/observable.hpp
- src/rpp/rpp/operators/on_error_resume_next.hpp
- src/rpp/rpp/operators/retry.hpp
🧰 Additional context used
🪛 LanguageTool
BUILDING.md
[grammar] ~80-~80: Did you mean “doesn't even”?
Context: ...ity for QT. rppqt doesn't include QT or even doesn't link with that itself. - `RPP::rppasio...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~81-~81: Possible missing comma found.
Context: ...or ASIO. rppasio doesn't include boost::asio or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~81-~81: Did you mean “doesn't even”?
Context: ... rppasio doesn't include boost::asio or even doesn't link with that itself. - `RPP::rppgrpc...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~82-~82: Possible missing comma found.
Context: ...ality for GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. ...(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~82-~82: Did you mean “doesn't even”?
Context: ...r GRPC. rppgrpc doesn't include GRPC or even doesn't link with that itself. Example usage: ...(DO_NOT_EVEN_WORD_ORDER)
[uncategorized] ~105-~105: You might be missing the article “the” here.
Context: ...p #include <rpp/rpp.hpp> ``` to include whole library functionality and don't worry a...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~105-~105: A comma might be missing here.
Context: ...be applied to rppgrpc or rppqt modules) Also you can include only forwardings for ev...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
Also RPP supports out of box: - QT as rppqt...Readme.md
[uncategorized] ~42-~42: A comma may be missing after the conjunctive/linking adverb ‘Also’.
Context: ... just printing to console.(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
🪛 Markdownlint
BUILDING.md
80-80: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
81-81: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
82-82: Expected: 0; Actual: 1
Unordered list indentation(MD007, ul-indent)
Readme.md
47-47: null
Fenced code blocks should have a language specified(MD040, fenced-code-language)
🔇 Additional comments (14)
BUILDING.md (2)
33-33: LGTM! Default INTERFACE modules updated correctly.The expansion of default INTERFACE modules to include
rppgrpcandrppasiois consistent with the new build options and provides more out-of-the-box functionality.
90-95: LGTM! Example usage updated correctly.The example usage has been appropriately updated to include the new targets
RPP::rppasioandRPP::rppgrpc. This provides clear guidance for users on how to incorporate these new targets in their projects.src/rpp/rpp/operators/switch_on_next.hpp (2)
174-174: LGTM: Improved resource management inswitch_on_next_observer_strategyThe addition of the
m_last_refcountmember variable and its usage in theon_nextmethod is a good improvement. This change ensures proper disposal of the previous subscription before assigning a new one, which helps prevent potential resource leaks and improves the overall robustness of theswitch_on_nextoperator.The use of
mutableis appropriate here as it allows modification ofm_last_refcountin const member functions likeon_next.
Line range hint
1-190: Summary of changes inswitch_on_next.hppThe changes in this file primarily focus on improving resource management in the
switch_on_next_observer_strategyclass and updating the documentation. Here's a summary:
- Added a new member variable
m_last_refcountto manage the reference count of the last observable subscription.- Updated the
on_nextmethod to properly dispose of the previous subscription before assigning a new one.- Changed the documentation tag for the include directive from
@warningto@note.These changes enhance the robustness of the
switch_on_nextoperator and slightly modify how the documentation is presented. Overall, the modifications appear to be positive improvements to the codebase.Readme.md (3)
9-11: Improved resource accessibility with new badgesThe addition of badges for the User Guide, API Reference, and Benchmarks enhances the README by providing quick access to essential resources. This change improves the document's usefulness for both new and experienced users.
84-84: Improved documentation structure and compiler compatibility informationThe updates to the documentation links, particularly specifying the User Guide as a tutorial, provide clearer guidance for users. This change helps users find the appropriate resources more easily, whether they're looking for a tutorial or detailed API reference.
The addition of the note about C++20 compiler compatibility is crucial information for potential users. It clearly sets expectations about the required development environment.
These changes significantly improve the README's usefulness for both new and experienced users.
Also applies to: 87-95
68-68:⚠️ Potential issueClearer articulation of advantages, but typo remains
The revised section does an excellent job of highlighting the key advantages of ReactivePlusPlus, particularly its modern C++ design and performance focus. However, there's a typo that needs to be corrected:
- Main advantages of ReactivePlusPlus are that it is written in Modern C++ with Performance and Usage in mind. v2 written to follow [**"zero-overhead principle"**](https://en.cppreference.com/w/cpp/language/Zero-overhead_principle) As a result it is fast, readable, easy to use and well-documented. And it is proven with [continous benchmarking results of v2 and comparison with RxCpp](https://victimsnino.github.io/ReactivePlusPlus/v2/benchmark) + Main advantages of ReactivePlusPlus are that it is written in Modern C++ with Performance and Usage in mind. v2 is written to follow the [**"zero-overhead principle"**](https://en.cppreference.com/w/cpp/language/Zero-overhead_principle). As a result, it is fast, readable, easy to use, and well-documented. This is proven by [continuous benchmarking results of v2 and comparison with RxCpp](https://victimsnino.github.io/ReactivePlusPlus/v2/benchmark).This revision corrects the typo "continous" to "continuous" and makes some minor grammatical improvements.
Likely invalid or redundant comment.
Doxyfile (4)
1051-1051: Appropriate exclusion of build directory.Excluding the 'build' directory from documentation generation is a good practice. It prevents build artifacts from being included in the documentation, keeping it focused on the source code.
1934-1934: LaTeX output generation has been disabled.The configuration now disables the generation of LaTeX output (
GENERATE_LATEX = NO) and the use of pdflatex (USE_PDFLATEX = NO). This change simplifies the documentation process by removing LaTeX-related outputs.Ensure that LaTeX output is indeed not required for your project's documentation needs.
Also applies to: 2070-2070
Line range hint
1-2478: Summary of Doxyfile changesThe modifications to the Doxyfile configuration include:
- Disabling warnings for undocumented and incomplete documentation.
- Excluding the 'build' directory from documentation.
- Adding a custom Python script to process .hpp files, likely for generating marble diagrams.
- Disabling LaTeX output generation.
These changes streamline the documentation process by reducing warnings, focusing on relevant content, and removing unnecessary output formats. However, ensure that these adjustments align with your project's documentation standards and requirements.
1142-1142: Verify the functionality of the marble diagram generation script.A Python script (
./ci/generate_marbles.py) is now used to process .hpp files before documentation generation. This is likely for generating marble diagrams or other visualizations.Please ensure that:
- The script is present in the specified location.
- It correctly processes the .hpp files as intended.
- The generated output enhances the documentation as expected.
src/rpp/rpp/operators/debounce.hpp (1)
188-188: Documentation update approvedChanging
@warningto@notein the documentation comment improves clarity and aligns with the documentation style.src/rpp/rpp/operators/timeout.hpp (2)
192-192: Appropriate change from@warningto@notein documentationUpdating the Doxygen tag from
@warningto@noteaccurately reflects the nature of the information provided. It serves as an informational note about the inclusion of the header file rather than a warning, enhancing the clarity of the documentation.
216-216: Consistent use of@noteenhances documentation clarityChanging the documentation tag to
@noteensures consistency across the codebase and makes the documentation clearer for users. It correctly indicates that the line is an informational note regarding the inclusion of the header file.
There was a problem hiding this comment.
@coderabbitai, please, rewrite whole this file. Make it as 100% complete tutorial over reactive programming and RPP including asio/qt/grpc
There was a problem hiding this comment.
@victimsnino, here is the updated docs/readme.md file with a comprehensive tutorial on reactive programming and ReactivePlusPlus, including integration with Asio, Qt, and gRPC:
# ReactivePlusPlus Tutorial
[TOC]
## Introduction
Welcome to the comprehensive tutorial on **ReactivePlusPlus (RPP)**, a reactive programming library for C++20 inspired by RxCpp and ReactiveX. This tutorial will guide you through the concepts of reactive programming using RPP, including integration with Boost.Asio, Qt, and gRPC.
## What is Reactive Programming?
**Reactive Programming** is a programming paradigm centered around data streams and the propagation of change. It enables the development of asynchronous, event-driven applications that can respond to data changes and user inputs efficiently.
At its core, reactive programming deals with the following concepts:
- **Observable**: A data stream that emits data over time.
- **Observer**: A consumer that receives data from an Observable.
- **Operators**: Functions that enable functional-style composition and transformation of data streams.
- **Schedulers**: Components that control the threading and concurrency of data emissions.
Reactive programming allows developers to construct applications that are resilient, responsive, and scalable.
## Getting Started with ReactivePlusPlus
### Installation
To use ReactivePlusPlus in your project, follow these steps:
1. **Clone the Repository**
```bash
git clone https://github.com/victimsnino/ReactivePlusPlus.git-
Build the Library
cd ReactivePlusPlus mkdir build && cd build cmake .. make
-
Include in Your Project
Add the following to your CMakeLists.txt:
find_package(RPP REQUIRED) target_link_libraries(your_target PRIVATE RPP::rpp)
Ensure that you include the RPP headers in your source files:
#include <rpp/rpp.hpp>
Basic Concepts
Observable
An Observable emits a sequence of items over time. It can be finite or infinite and can emit zero or more items, followed by either a completion or an error signal.
Observer
An Observer subscribes to an Observable to receive emissions. It defines how to handle each item, errors, and completion notifications.
Subscription
A Subscription represents the connection between an Observer and an Observable. It can be used to unsubscribe and stop receiving emissions.
Operator
An Operator is a function that transforms or modifies the data emitted by an Observable, allowing you to compose complex data flows.
Scheduler
A Scheduler determines the threading model for the Observables and Observers, controlling concurrency.
Basic Usage
Creating an Observable and Observer
#include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::just(1, 2, 3);
auto observer = rpp::make_lambda_observer(
[](int value) { std::cout << "Received: " << value << std::endl; },
[](std::exception_ptr) { std::cout << "Error occurred." << std::endl; },
[]() { std::cout << "Completed." << std::endl; }
);
observable.subscribe(observer);
return 0;
}Output:
Received: 1
Received: 2
Received: 3
Completed.
Using Operators
Map Operator
Transforms each item emitted by an Observable.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::map([](int value) { return value * 10; });
observable.subscribe([](int value) {
std::cout << "Transformed Value: " << value << std::endl;
});Output:
Transformed Value: 10
Transformed Value: 20
Transformed Value: 30
Filter Operator
Emits only those items from an Observable that pass a predicate test.
auto observable = rpp::source::just(1, 2, 3, 4, 5)
| rpp::operators::filter([](int value) { return value % 2 == 0; });
observable.subscribe([](int value) {
std::cout << "Even Value: " << value << std::endl;
});Output:
Even Value: 2
Even Value: 4
Advanced Concepts
Combining Observables
Merge Operator
Combines multiple Observables into one by merging their emissions.
auto observable1 = rpp::source::just(1, 3, 5);
auto observable2 = rpp::source::just(2, 4, 6);
auto merged = observable1 | rpp::operators::merge_with(observable2);
merged.subscribe([](int value) {
std::cout << "Merged Value: " << value << std::endl;
});Output (order may vary):
Merged Value: 1
Merged Value: 2
Merged Value: 3
Merged Value: 4
Merged Value: 5
Merged Value: 6
Zip Operator
Combines emissions from multiple Observables by pairing emissions of the same index.
auto observable1 = rpp::source::just(1, 2, 3);
auto observable2 = rpp::source::just("A", "B", "C");
auto zipped = rpp::source::zip(observable1, observable2);
zipped.subscribe([](const std::tuple<int, std::string>& value) {
std::cout << "Zipped Value: " << std::get<0>(value) << ", " << std::get<1>(value) << std::endl;
});Output:
Zipped Value: 1, A
Zipped Value: 2, B
Zipped Value: 3, C
Error Handling
Handle errors gracefully using the on_error handler.
auto observable = rpp::source::create<int>([](const auto& observer) {
observer.on_next(42);
observer.on_error(std::make_exception_ptr(std::runtime_error("Oops!")));
});
observable.subscribe(
[](int value) { std::cout << "Received: " << value << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
},
[]() { std::cout << "Completed." << std::endl; }
);Output:
Received: 42
Error: Oops!
Multithreading and Schedulers
Using Schedulers
Schedulers control the execution context (threading) of Observables.
subscribe_on
Specifies the scheduler on which an Observable will begin emitting items.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::subscribe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::cout << "Received on thread " << std::this_thread::get_id() << ": " << value << std::endl;
});observe_on
Specifies the scheduler on which an Observer will observe the emissions.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::observe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::cout << "Observed on thread " << std::this_thread::get_id() << ": " << value << std::endl;
});Integration with Boost.Asio
Boost.Asio is a cross-platform C++ library for network and low-level I/O programming.
Asynchronous Networking with RPP and Asio
#include <rpp/rpp.hpp>
#include <boost/asio.hpp>
#include <iostream>
int main() {
boost::asio::io_context io_context;
auto timer_observable = rpp::source::create<void>([&](const auto& observer) {
boost::asio::steady_timer timer(io_context, std::chrono::seconds(1));
timer.async_wait([observer](const boost::system::error_code& ec) {
if (!ec) {
observer.on_next();
observer.on_completed();
} else {
observer.on_error(std::make_exception_ptr(boost::system::system_error(ec)));
}
});
});
timer_observable.subscribe(
[]() { std::cout << "Timer expired!" << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
}
);
io_context.run();
return 0;
}Explanation:
- We create an Observable that emits when a
boost::asio::steady_timerexpires. - The Observable notifies the Observer upon timer completion or error.
Integration with Qt
Qt is a widely used framework for building GUI applications.
Reactive GUI Events with RPP and Qt
#include <rpp/rpp.hpp>
#include <QApplication>
#include <QPushButton>
#include <iostream>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QPushButton button("Click Me!");
button.show();
auto click_observable = rpp::source::create<void>([&](const auto& observer) {
QObject::connect(&button, &QPushButton::clicked, [&observer]() {
observer.on_next();
});
});
click_observable.subscribe([]() {
std::cout << "Button was clicked!" << std::endl;
});
return app.exec();
}Explanation:
- We create an Observable that emits every time the button is clicked.
- The Observer reacts by printing a message to the console.
Integration with gRPC
gRPC is a high-performance framework that can use reactive streams for client-server communication.
Streaming RPCs with RPP and gRPC
#include <rpp/rpp.hpp>
#include <grpcpp/grpcpp.h>
#include "your_service.grpc.pb.h"
#include <iostream>
int main() {
auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
auto stub = YourService::NewStub(channel);
grpc::ClientContext context;
YourRequest request;
auto reader = stub->YourStreamingRPC(&context, request);
auto stream_observable = rpp::source::create<YourResponse>([&](const auto& observer) {
YourResponse response;
while (reader->Read(&response)) {
observer.on_next(response);
}
grpc::Status status = reader->Finish();
if (status.ok()) {
observer.on_completed();
} else {
observer.on_error(std::make_exception_ptr(std::runtime_error(status.error_message())));
}
});
stream_observable.subscribe(
[](const YourResponse& response) { std::cout << "Received response." << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "gRPC Error: " << e.what() << std::endl;
}
},
[]() { std::cout << "Stream completed." << std::endl; }
);
return 0;
}Explanation:
- We create an Observable that emits responses from a gRPC streaming RPC.
- The Observer handles each response, any errors, and stream completion.
Creating Custom Operators
Extend RPP by creating your own operators to encapsulate reusable logic.
Example: delay
A custom operator that delays emissions by a specified duration.
template<typename Duration>
auto delay(Duration duration) {
return [duration](const auto& observable) {
using T = typename decltype(observable)::value_type;
return rpp::source::create<T>([observable, duration](const auto& observer) {
observable.subscribe(
[observer, duration](const T& value) {
std::this_thread::sleep_for(duration);
observer.on_next(value);
},
[observer](std::exception_ptr eptr) { observer.on_error(eptr); },
[observer]() { observer.on_completed(); }
);
});
};
}Usage:
auto delayed_observable = rpp::source::just(1, 2, 3)
| delay(std::chrono::seconds(1));
delayed_observable.subscribe([](int value) {
std::cout << "Received after delay: " << value << std::endl;
});Output:
Emits each value with a 1-second delay.
Thread Safety and Synchronization
RPP ensures that emissions are serial, adhering to the Observable contract. However, when dealing with shared resources or state, you should manage synchronization appropriately.
Example: Protecting Shared State
#include <mutex>
std::mutex mtx;
int shared_counter = 0;
auto observable = rpp::source::create<int>([](const auto& observer) {
for (int i = 0; i < 5; ++i) {
observer.on_next(i);
}
observer.on_completed();
})
| rpp::operators::subscribe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::lock_guard<std::mutex> lock(mtx);
shared_counter += value;
std::cout << "Shared Counter: " << shared_counter << std::endl;
});Memory Management
RPP provides options for managing memory models to optimize performance.
Using Memory Models
- Use Stack: For small objects that are inexpensive to copy.
- Use Shared: For larger objects where copying is expensive.
Example:
auto observable = rpp::source::just<rpp::memory_model::use_shared>(my_large_object);Exception Handling and Guarantees
Exceptions are communicated via the on_error callback. RPP ensures that subscribers are notified of any errors, and resources are cleaned up appropriately.
Further Resources
- ReactiveX Documentation: reactivex.io
- Boost.Asio: Boost.Asio Documentation
- Qt Framework: Qt Documentation
- gRPC: gRPC Documentation
- ReactivePlusPlus API Reference: RPP API
Conclusion
This tutorial covered the fundamentals of reactive programming using ReactivePlusPlus, including integration with Boost.Asio, Qt, and gRPC. With RPP, you can build robust, scalable, and responsive applications in modern C++.
We encourage you to explore the library further, contribute to its development, and become part of the ReactivePlusPlus community.
License
ReactivePlusPlus is licensed under the MIT License.
Feel free to reach out if you need any further adjustments or additions.
<!-- This is an auto-generated reply by CodeRabbit -->
There was a problem hiding this comment.
Make it less readme.md but more as tutorial. remove installation part, lisensing and etc. Just tutorial over rpp in addition to main readme.md
There was a problem hiding this comment.
@victimsnino, here is the updated docs/readme.md file rewritten as a comprehensive tutorial over ReactivePlusPlus (RPP), focusing on reactive programming and RPP, including integration with Asio, Qt, and gRPC, and excluding the installation and licensing sections as per your request:
# ReactivePlusPlus Tutorial
[TOC]
## Introduction
Welcome to the comprehensive tutorial on **ReactivePlusPlus (RPP)**, a reactive programming library for C++20 inspired by RxCpp and ReactiveX. This tutorial will guide you through the concepts of reactive programming using RPP, including integration with Boost.Asio, Qt, and gRPC.
### What is Reactive Programming?
**Reactive Programming** is a programming paradigm centered around data streams and the propagation of change. It enables the development of asynchronous, event-driven applications that can respond to data changes and user inputs efficiently.
At its core, reactive programming deals with the following concepts:
- **Observable**: A data stream that emits data over time.
- **Observer**: A consumer that receives data from an Observable.
- **Operators**: Functions that enable functional-style composition and transformation of data streams.
- **Schedulers**: Components that control the threading and concurrency of data emissions.
Reactive programming allows developers to construct applications that are resilient, responsive, and scalable.
## Basic Concepts in RPP
### Observable
An **Observable** emits a sequence of items over time. It can be finite or infinite and can emit zero or more items, followed by either a completion or an error signal.
### Observer
An **Observer** subscribes to an Observable to receive emissions. It defines how to handle each item, errors, and completion notifications.
### Subscription
A **Subscription** represents the connection between an Observer and an Observable. It can be used to unsubscribe and stop receiving emissions.
### Operator
An **Operator** is a function that transforms or modifies the data emitted by an Observable, allowing you to compose complex data flows.
### Scheduler
A **Scheduler** determines the threading model for the Observables and Observers, controlling concurrency.
## Getting Started with RPP
### Creating an Observable and Observer
```cpp
#include <rpp/rpp.hpp>
#include <iostream>
int main() {
auto observable = rpp::source::just(1, 2, 3);
observable.subscribe(
[](int value) { std::cout << "Received: " << value << std::endl; },
[](std::exception_ptr) { std::cout << "Error occurred." << std::endl; },
[]() { std::cout << "Completed." << std::endl; }
);
return 0;
}Output:
Received: 1
Received: 2
Received: 3
Completed.
Using Operators
Map Operator
Transforms each item emitted by an Observable.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::map([](int value) { return value * 10; });
observable.subscribe([](int value) {
std::cout << "Transformed Value: " << value << std::endl;
});Output:
Transformed Value: 10
Transformed Value: 20
Transformed Value: 30
Filter Operator
Emits only those items from an Observable that pass a predicate test.
auto observable = rpp::source::just(1, 2, 3, 4, 5)
| rpp::operators::filter([](int value) { return value % 2 == 0; });
observable.subscribe([](int value) {
std::cout << "Even Value: " << value << std::endl;
});Output:
Even Value: 2
Even Value: 4
Combining Observables
Merge Operator
Combines multiple Observables into one by merging their emissions.
auto observable1 = rpp::source::just(1, 3, 5);
auto observable2 = rpp::source::just(2, 4, 6);
auto merged = observable1 | rpp::operators::merge_with(observable2);
merged.subscribe([](int value) {
std::cout << "Merged Value: " << value << std::endl;
});Output (order may vary):
Merged Value: 1
Merged Value: 2
Merged Value: 3
Merged Value: 4
Merged Value: 5
Merged Value: 6
Zip Operator
Combines emissions from multiple Observables by pairing emissions of the same index.
auto observable1 = rpp::source::just(1, 2, 3);
auto observable2 = rpp::source::just("A", "B", "C");
auto zipped = rpp::source::zip(observable1, observable2);
zipped.subscribe([](const std::tuple<int, std::string>& value) {
std::cout << "Zipped Value: " << std::get<0>(value) << ", " << std::get<1>(value) << std::endl;
});Output:
Zipped Value: 1, A
Zipped Value: 2, B
Zipped Value: 3, C
Error Handling
Handle errors gracefully using the on_error handler.
auto observable = rpp::source::create<int>([](const auto& observer) {
observer.on_next(42);
observer.on_error(std::make_exception_ptr(std::runtime_error("Oops!")));
});
observable.subscribe(
[](int value) { std::cout << "Received: " << value << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
},
[]() { std::cout << "Completed." << std::endl; }
);Output:
Received: 42
Error: Oops!
Multithreading and Schedulers
Using Schedulers
Schedulers control the execution context (threading) of Observables.
subscribe_on
Specifies the scheduler on which an Observable will begin emitting items.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::subscribe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::cout << "Received on thread " << std::this_thread::get_id() << ": " << value << std::endl;
});observe_on
Specifies the scheduler on which an Observer will observe the emissions.
auto observable = rpp::source::just(1, 2, 3)
| rpp::operators::observe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::cout << "Observed on thread " << std::this_thread::get_id() << ": " << value << std::endl;
});Integration with Boost.Asio
Boost.Asio is a cross-platform C++ library for network and low-level I/O programming.
Asynchronous Networking with RPP and Asio
#include <rpp/rpp.hpp>
#include <boost/asio.hpp>
#include <iostream>
int main() {
boost::asio::io_context io_context;
auto timer_observable = rpp::source::create<void>([&](const auto& observer) {
auto timer = std::make_shared<boost::asio::steady_timer>(io_context, std::chrono::seconds(1));
timer->async_wait([observer, timer](const boost::system::error_code& ec) {
if (!ec) {
observer.on_next();
observer.on_completed();
} else {
observer.on_error(std::make_exception_ptr(boost::system::system_error(ec)));
}
});
});
timer_observable.subscribe(
[]() { std::cout << "Timer expired!" << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl; }
}
);
io_context.run();
return 0;
}Explanation:
- We create an Observable that emits when a
boost::asio::steady_timerexpires. - The Observable notifies the Observer upon timer completion or error.
Integration with Qt
Qt is a widely used framework for building GUI applications.
Reactive GUI Events with RPP and Qt
#include <rpp/rpp.hpp>
#include <QApplication>
#include <QPushButton>
#include <iostream>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QPushButton button("Click Me!");
button.show();
auto click_observable = rpp::source::create<void>([&](const auto& observer) {
QObject::connect(&button, &QPushButton::clicked, [&observer]() {
observer.on_next();
});
});
click_observable.subscribe([]() {
std::cout << "Button was clicked!" << std::endl;
});
return app.exec();
}Explanation:
- We create an Observable that emits every time the button is clicked.
- The Observer reacts by printing a message to the console.
Integration with gRPC
gRPC is a high-performance framework that can use reactive streams for client-server communication.
Streaming RPCs with RPP and gRPC
#include <rpp/rpp.hpp>
#include <grpcpp/grpcpp.h>
#include "your_service.grpc.pb.h"
#include <iostream>
int main() {
auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
auto stub = YourService::NewStub(channel);
grpc::ClientContext context;
YourRequest request;
auto reader = stub->YourStreamingRPC(&context, request);
auto stream_observable = rpp::source::create<YourResponse>([&](const auto& observer) {
YourResponse response;
while (reader->Read(&response)) {
observer.on_next(response);
}
grpc::Status status = reader->Finish();
if (status.ok()) {
observer.on_completed();
} else {
observer.on_error(std::make_exception_ptr(std::runtime_error(status.error_message())));
}
});
stream_observable.subscribe(
[](const YourResponse& response) { std::cout << "Received response." << std::endl; },
[](std::exception_ptr eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "gRPC Error: " << e.what() << std::endl;
}
},
[]() { std::cout << "Stream completed." << std::endl; }
);
return 0;
}Explanation:
- We create an Observable that emits responses from a gRPC streaming RPC.
- The Observer handles each response, any errors, and stream completion.
Creating Custom Operators
Extend RPP by creating your own operators to encapsulate reusable logic.
Example: delay
A custom operator that delays emissions by a specified duration.
template<typename Duration>
auto delay(Duration duration) {
return [duration](const auto& observable) {
using T = typename decltype(observable)::value_type;
return rpp::source::create<T>([observable, duration](const auto& observer) {
observable.subscribe(
[observer, duration](const T& value) {
std::this_thread::sleep_for(duration);
observer.on_next(value);
},
[observer](std::exception_ptr eptr) { observer.on_error(eptr); },
[observer]() { observer.on_completed(); }
);
});
};
}Usage:
auto delayed_observable = rpp::source::just(1, 2, 3)
| delay(std::chrono::seconds(1));
delayed_observable.subscribe([](int value) {
std::cout << "Received after delay: " << value << std::endl;
});Output:
Emits each value with a 1-second delay.
Thread Safety and Synchronization
RPP ensures that emissions are serial, adhering to the Observable contract. However, when dealing with shared resources or state, you should manage synchronization appropriately.
Example: Protecting Shared State
#include <mutex>
std::mutex mtx;
int shared_counter = 0;
auto observable = rpp::source::create<int>([](const auto& observer) {
for (int i = 0; i < 5; ++i) {
observer.on_next(i);
}
observer.on_completed();
})
| rpp::operators::subscribe_on(rpp::schedulers::new_thread{});
observable.subscribe([](int value) {
std::lock_guard<std::mutex> lock(mtx);
shared_counter += value;
std::cout << "Shared Counter: " << shared_counter << std::endl;
});Memory Management in RPP
RPP provides options for managing memory models to optimize performance.
Using Memory Models
- Use Stack: For small objects that are inexpensive to copy.
- Use Shared: For larger objects where copying is expensive.
Example:
auto observable = rpp::source::just<rpp::memory_model::use_shared>(my_large_object);Exception Handling and Guarantees
Exceptions are communicated via the on_error callback. RPP ensures that subscribers are notified of any errors, and resources are cleaned up appropriately.
Conclusion
This tutorial covered the fundamentals of reactive programming using ReactivePlusPlus, including integration with Boost.Asio, Qt, and gRPC. With RPP, you can build robust, scalable, and responsive applications in modern C++.
We encourage you to explore the library further, contribute to its development, and become part of the ReactivePlusPlus community.
Is there anything else you'd like me to add or adjust?
<!-- This is an auto-generated reply by CodeRabbit -->
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (4)
Readme.md (4)
38-46: Improved clarity in introduction and exampleThe grammatical improvements and typo fix in the code example enhance the overall quality of the README. However, there's a minor suggestion:
Consider adding a comma after "Also" in line 43:
-Also RPP supports out of box: +Also, RPP supports out of the box:This change improves readability and addresses a potential grammatical issue.
Also RPP supports out of box: - QT as rppqt module. Checkout [RPPQT...🧰 Tools
Also RPP supports out of box: - QT as rppqt...🪛 LanguageTool
[uncategorized] ~42-~42: A comma may be missing after the conjunctive/linking adverb ‘Also’.
Context: ... just printing to console.(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~43-~43: You might be missing the article “the” here.
Context: ....(AI_EN_LECTOR_MISSING_DETERMINER_THE)
51-55: Improved comparison of existing libraries
The revised text provides a more balanced and detailed comparison of existing Reactive Extension libraries. The explanation of RxCpp's limitations and the addition of information about another-rxcpp are particularly helpful.
There's a minor typo in line 53:
-Sometimes it has bad perfomance due to tremendous amount of usage of heap or just non-effective logic.
+Sometimes it has bad performance due to tremendous amount of usage of heap or just non-effective logic.64-68: Clearer articulation of ReactivePlusPlus advantages
The revised section does an excellent job of highlighting the key advantages of ReactivePlusPlus, particularly its modern C++ design and performance focus. The addition of the zero-overhead principle provides valuable context for the library's design philosophy.
There's a minor typo in line 64:
-ReactivePlusPlus is fast: every part of code written with perfomance in mind.
+ReactivePlusPlus is fast: every part of code written with performance in mind.84-93: Enhanced documentation and resource links
The updates to the documentation section and the addition of new useful links greatly improve the README's value as a starting point for users. The inclusion of links to examples and continuous benchmarking results is particularly helpful.
To improve the markdown quality, consider specifying a language for the fenced code block in the Licensing section. For example:
-```
+```text
Boost Software License - Version 1.0 - August 17th, 2003
...This change will enhance syntax highlighting and conform to markdown best practices.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
- Readme.md (4 hunks)
- docs/readme.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
- docs/readme.md
🧰 Additional context used
🪛 LanguageTool
Also RPP supports out of box: - QT as rppqt...Readme.md
[uncategorized] ~42-~42: A comma may be missing after the conjunctive/linking adverb ‘Also’.
Context: ... just printing to console.(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~43-~43: You might be missing the article “the” here.
Context: ....
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
🪛 Markdownlint
Readme.md
47-47: null
Fenced code blocks should have a language specified(MD040, fenced-code-language)
🔇 Additional comments (1)
Readme.md (1)
9-11: Great additions to the README header!The new badges for the User Guide, API Reference, and Benchmarks provide quick access to important resources. This improvement enhances the README's usefulness for both new and existing users.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (6)
docs/readme.md (2)
35-39: Enhanced code example and explanation of distributed input/outputThe changes in this section improve the document's clarity:
- The code example is now better formatted, making it easier to read.
- The explanations of pulling and pushing data are more concise and to the point.
These modifications help readers better understand the concepts of distributed input/output.
Consider adding a brief comment in the code example to explain what the
::getchar()function does, as some readers might not be familiar with it.Also applies to: 45-47
275-277: Added resources and maintained content in Schedulers and Exception Guarantee sectionsThe changes in these sections enhance the document's value:
- Links to the API Reference and ReactiveX documentation provide readers with additional resources.
- The content of the "Exception Guarantee" section is preserved, maintaining important information.
These modifications offer readers more avenues for in-depth learning while retaining the document's core content.
Consider adding a brief introduction to the "Exception Guarantee" section to provide context for why this information is important in reactive programming.
Also applies to: 291-291
Doxyfile (4)
839-839: Consider the trade-offs of enabling QUIET mode.Enabling QUIET mode (YES) will suppress standard output messages during documentation generation. This can be beneficial in CI/CD pipelines or automated processes. However, be aware that it might hide useful information during manual runs.
Consider adding a comment explaining the reason for this change, especially if it's intended for a specific use case (e.g., "Enabled for CI/CD pipeline integration").
855-855: Be cautious about disabling undocumented warnings.Disabling WARN_IF_UNDOCUMENTED (NO) will suppress warnings about undocumented members. While this can reduce noise in the output, especially for large projects, it might lead to overlooking important documentation gaps.
Consider adding a TODO comment to re-enable this in the future once the documentation coverage has improved, or explain the rationale behind this decision.
870-870: Consider the implications of disabling incomplete documentation warnings.Disabling WARN_IF_INCOMPLETE_DOC (NO) will suppress warnings about incomplete function parameter documentation. This can reduce noise in the output, but it might lead to overlooking important documentation gaps, potentially affecting the overall quality of the documentation.
Consider adding a comment explaining the rationale behind this decision, or set a reminder to re-evaluate this setting in the future to ensure documentation completeness.
1142-1142: Good update: Explicitly using Python 3 for file processing.Updating FILTER_PATTERNS to use "python3" instead of "python" is a good change. This ensures that Python 3 is used for processing .hpp files, which is important if the script relies on Python 3 features or if the system's default Python is version 2.
Consider adding a comment explaining why Python 3 is required, especially if there are specific version dependencies or features being used in the processing script.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (42)
- Doxyfile (9 hunks)
- docs/readme.md (5 hunks)
- src/rpp/rpp/operators/buffer.hpp (1 hunks)
- src/rpp/rpp/operators/combine_latest.hpp (2 hunks)
- src/rpp/rpp/operators/concat.hpp (1 hunks)
- src/rpp/rpp/operators/debounce.hpp (1 hunks)
- src/rpp/rpp/operators/delay.hpp (1 hunks)
- src/rpp/rpp/operators/distinct_until_changed.hpp (1 hunks)
- src/rpp/rpp/operators/element_at.hpp (1 hunks)
- src/rpp/rpp/operators/filter.hpp (1 hunks)
- src/rpp/rpp/operators/finally.hpp (1 hunks)
- src/rpp/rpp/operators/first.hpp (1 hunks)
- src/rpp/rpp/operators/flat_map.hpp (1 hunks)
- src/rpp/rpp/operators/group_by.hpp (1 hunks)
- src/rpp/rpp/operators/last.hpp (1 hunks)
- src/rpp/rpp/operators/map.hpp (1 hunks)
- src/rpp/rpp/operators/merge.hpp (3 hunks)
- src/rpp/rpp/operators/multicast.hpp (2 hunks)
- src/rpp/rpp/operators/observe_on.hpp (1 hunks)
- src/rpp/rpp/operators/on_error_resume_next.hpp (1 hunks)
- src/rpp/rpp/operators/publish.hpp (1 hunks)
- src/rpp/rpp/operators/reduce.hpp (2 hunks)
- src/rpp/rpp/operators/repeat.hpp (2 hunks)
- src/rpp/rpp/operators/retry.hpp (2 hunks)
- src/rpp/rpp/operators/retry_when.hpp (1 hunks)
- src/rpp/rpp/operators/scan.hpp (2 hunks)
- src/rpp/rpp/operators/skip.hpp (1 hunks)
- src/rpp/rpp/operators/start_with.hpp (3 hunks)
- src/rpp/rpp/operators/subscribe.hpp (3 hunks)
- src/rpp/rpp/operators/subscribe_on.hpp (1 hunks)
- src/rpp/rpp/operators/switch_on_next.hpp (1 hunks)
- src/rpp/rpp/operators/take.hpp (1 hunks)
- src/rpp/rpp/operators/take_last.hpp (1 hunks)
- src/rpp/rpp/operators/take_until.hpp (1 hunks)
- src/rpp/rpp/operators/take_while.hpp (1 hunks)
- src/rpp/rpp/operators/throttle.hpp (1 hunks)
- src/rpp/rpp/operators/timeout.hpp (2 hunks)
- src/rpp/rpp/operators/window.hpp (1 hunks)
- src/rpp/rpp/operators/window_toggle.hpp (1 hunks)
- src/rpp/rpp/operators/with_latest_from.hpp (2 hunks)
- src/rpp/rpp/operators/zip.hpp (2 hunks)
- src/rpp/rpp/sources/concat.hpp (2 hunks)
✅ Files skipped from review due to trivial changes (2)
- src/rpp/rpp/operators/merge.hpp
- src/rpp/rpp/operators/subscribe.hpp
🚧 Files skipped from review as they are similar to previous changes (37)
- src/rpp/rpp/operators/buffer.hpp
- src/rpp/rpp/operators/combine_latest.hpp
- src/rpp/rpp/operators/concat.hpp
- src/rpp/rpp/operators/debounce.hpp
- src/rpp/rpp/operators/delay.hpp
- src/rpp/rpp/operators/distinct_until_changed.hpp
- src/rpp/rpp/operators/element_at.hpp
- src/rpp/rpp/operators/filter.hpp
- src/rpp/rpp/operators/finally.hpp
- src/rpp/rpp/operators/first.hpp
- src/rpp/rpp/operators/flat_map.hpp
- src/rpp/rpp/operators/group_by.hpp
- src/rpp/rpp/operators/last.hpp
- src/rpp/rpp/operators/map.hpp
- src/rpp/rpp/operators/multicast.hpp
- src/rpp/rpp/operators/observe_on.hpp
- src/rpp/rpp/operators/on_error_resume_next.hpp
- src/rpp/rpp/operators/publish.hpp
- src/rpp/rpp/operators/reduce.hpp
- src/rpp/rpp/operators/repeat.hpp
- src/rpp/rpp/operators/retry.hpp
- src/rpp/rpp/operators/retry_when.hpp
- src/rpp/rpp/operators/scan.hpp
- src/rpp/rpp/operators/skip.hpp
- src/rpp/rpp/operators/start_with.hpp
- src/rpp/rpp/operators/subscribe_on.hpp
- src/rpp/rpp/operators/switch_on_next.hpp
- src/rpp/rpp/operators/take.hpp
- src/rpp/rpp/operators/take_last.hpp
- src/rpp/rpp/operators/take_until.hpp
- src/rpp/rpp/operators/take_while.hpp
- src/rpp/rpp/operators/throttle.hpp
- src/rpp/rpp/operators/window.hpp
- src/rpp/rpp/operators/window_toggle.hpp
- src/rpp/rpp/operators/with_latest_from.hpp
- src/rpp/rpp/operators/zip.hpp
- src/rpp/rpp/sources/concat.hpp
🧰 Additional context used
🪛 LanguageTool
docs/readme.md
[uncategorized] ~62-~62: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
🔇 Additional comments (9)
src/rpp/rpp/operators/timeout.hpp (4)
Line range hint
132-141: Excellent addition ofoperator_traitsfor improved type safety!The new
operator_traitsstruct intimeout_tenhances type safety by statically asserting that theTFallbackObservabletype matches the expected typeT. This is a great improvement that aligns with C++ best practices for template metaprogramming.
192-192: Appropriate documentation updateThe change from
@warningto@notefor the include directive is a good adjustment. It correctly reflects that including a header file is a note-worthy point rather than a warning.
216-216: Consistent documentation improvementThe change from
@warningto@notefor the include directive is consistent with the earlier update. This maintains a uniform documentation style throughout the file.
Line range hint
1-234: Overall excellent improvements to thetimeoutoperatorThe changes in this file significantly enhance the
timeoutoperator implementation:
- The addition of
operator_traitsintimeout_timproves type safety.- Documentation updates provide clearer guidance for users.
- The implementation of
timeout_with_error_tadds flexibility to the operator's behavior.These changes align well with C++ best practices and improve the overall quality of the ReactivePlusPlus library.
docs/readme.md (3)
1-1: Improved clarity and readability in the introductionThe changes in the introduction and "What is Reactive Programming?" section enhance the document's readability:
- The title "Getting started" is more appropriate for this type of document.
- The grammar correction in the important note improves clarity.
- The refined description of input/output types is more concise and easier to understand.
These modifications make the document more user-friendly without altering its core content.
Also applies to: 8-8, 14-14, 20-22, 28-28
55-65: Improved formatting and clarity in Core Concepts sectionThe changes in the "Core Concepts of Reactive Programming" section enhance the document's readability:
- The list items are now more consistently formatted.
- The descriptions of Observable notifications are more precise and easier to understand.
These modifications make the core concepts clearer for readers without changing their fundamental meaning.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~62-~62: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
131-134: Enhanced document structure in Documentation sectionsThe changes in the "Documentation" and "Observable contract" sections improve the document's structure:
- The formatting of section headers is now more consistent.
- The content remains unchanged, preserving the original information.
These modifications enhance the overall organization of the document, making it easier for readers to navigate.
Also applies to: 138-140
Doxyfile (2)
1051-1051: Good practice: Excluding build directory from documentation.Excluding the "build" directory from Doxygen processing is a good practice. This prevents build artifacts from being included in the documentation, which can significantly reduce processing time and avoid cluttering the documentation with irrelevant information.
Line range hint
1-2070: Overall, the Doxyfile changes improve configuration for specific use cases.The modifications to the Doxygen configuration file appear to be intentional and address specific project needs. Key changes include:
- Enabling quiet mode for cleaner output in automated processes.
- Disabling certain warnings to reduce noise, particularly for undocumented or incompletely documented elements.
- Excluding the build directory to prevent processing of build artifacts.
- Explicitly using Python 3 for file processing.
While these changes can improve the documentation generation process, be mindful of the potential long-term effects on documentation quality, especially regarding the disabled warnings. Consider periodically reviewing these settings to ensure they continue to meet the project's documentation needs and quality standards.
| - **on_next(T)** - notifies about a new event/emission | ||
| - **on_error(std::exception_ptr)** - notifies about an error. This is a termination event. (no more calls from this observable should be expected) | ||
| - **on_completed()** - notifies about successful completion. This is a termination event. (no more calls from this observable should be expected) | ||
| - **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state |
There was a problem hiding this comment.
Correct possessive pronoun usage
There's a grammatical error in this line:
- **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state
+ **set_upstream(disposable)** - observable could pass to observer its own disposable to provide ability for observer to terminate observable's internal actions/stateThe possessive pronoun "its" should be used here instead of the contraction "it's" (which means "it is").
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state | |
| - **set_upstream(disposable)** - observable could pass to observer its own disposable to provide ability for observer to terminate observable's internal actions/state |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~62-~62: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Outside diff range and nitpick comments (3)
DoxygenLayout.xml (2)
8-12: Consider keeping the "API reference" title and LGTM on modules tab.
The removal of the "API reference" title from the "topics" tab might reduce clarity for users. Consider keeping this title or replacing it with an equally descriptive one.
The addition of the "modules" tab with "modulelist" and "modulemembers" sub-tabs is a good improvement for projects using modules.
Would you like to reconsider keeping a descriptive title for the "topics" tab?
Line range hint
215-215: LGTM: Properties added to group documentation.The addition of properties to both the
memberdeclandmemberdefsections of the group layout is a good improvement. This can be useful for documenting group-level metadata or attributes.To enhance clarity for users and maintainers:
- Consider adding a comment in the XML file explaining the intended use of properties in group documentation.
- Update the project's documentation guidelines to explain how and when to use these properties in group documentation.
Would you like assistance in drafting these documentation updates?
Also applies to: 240-240
Doxyfile (1)
1432-1435: HTML output configuration enhancedThe HTML output configuration has been improved:
- HTML_OUTPUT directory set to 'html'.
- Custom stylesheets and JavaScript files added for enhanced appearance.
- HTML_COLORSTYLE set to LIGHT.
These changes will result in a modern and responsive documentation style.
Consider adding a dark mode toggle for better accessibility:
HTML_COLORSTYLE = LIGHT +HTML_COLORSTYLE = AUTO_LIGHTThis change allows users to switch between light and dark modes, improving readability in different environments.
Also applies to: 1445-1446, 1458-1458
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
- .gitmodules (1 hunks)
- Doxyfile (107 hunks)
- DoxygenLayout.xml (6 hunks)
- docs/custom.css (1 hunks)
- docs/doxygen-awesome-css (1 hunks)
- docs/header.html (1 hunks)
- docs/readme.md (5 hunks)
✅ Files skipped from review due to trivial changes (2)
- docs/custom.css
- docs/doxygen-awesome-css
🧰 Additional context used
🪛 LanguageTool
docs/readme.md
[uncategorized] ~62-~62: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
🔇 Additional comments (13)
DoxygenLayout.xml (3)
Line range hint
246-266: Acknowledge C++20 module support and suggest future updates.The module section, supporting C++20 modules, remains unchanged. This indicates good preparation for modern C++ features.
To ensure continued relevance:
- Regularly review this section as new C++ standards are released.
- Consider adding a comment indicating the latest C++ standard version this layout supports.
- Establish a process for updating this section when new module-related features are introduced in future C++ standards.
Would you like assistance in creating a reminder or process for keeping this section up to date?
Line range hint
1-270: Summary of DoxygenLayout.xml changesOverall, the updates to the Doxygen layout file are positive, supporting a newer Doxygen version and enhancing the documentation structure. Here are the key points to address:
- Verify compatibility with Doxygen 1.12.0 throughout the project.
- Reconsider removing the "API reference" title from the topics tab.
- Evaluate the decision to disable inheritance graphs for all classes.
- Clarify the purpose and usage of properties in namespace and file documentation.
- Consider adding explanatory comments for the use of properties in group documentation.
- Establish a process for keeping the C++20 module section up to date with future C++ standards.
These changes will significantly improve the documentation structure and clarity. Please review the individual comments for more detailed suggestions and let me know if you need any further assistance or clarification.
3-3: LGTM: Doxygen version updated.The Doxygen version has been updated from 1.9.8 to 1.12.0 in the comment. This change is appropriate and reflects the use of a newer version of Doxygen.
To ensure compatibility with the new Doxygen version, please run the following command and verify that there are no warnings or errors:
docs/readme.md (6)
1-1: Improved clarity and grammar in the introductionThe changes in the introduction section enhance the overall readability and correctness of the document. The new title "Manual documentation" is more appropriate, and the grammatical corrections make the text more professional. The refined explanations of input/output types and reactive programming concepts are now more concise and easier to understand.
Also applies to: 8-8, 14-14, 17-17, 20-20, 22-22, 28-28, 35-39, 45-45, 47-47, 49-49, 53-53, 55-55, 58-62
131-131: Improved document structureThe changes to the "Documentation" and "Observable contract" sections enhance the overall structure of the document. The consistent use of heading levels and the restructuring of the "Observable contract" section improve readability and make the document more organized.
Also applies to: 134-134, 138-138, 140-140, 142-142
275-275: Enhanced resources for schedulersThe addition of links to the API Reference and more detailed information about schedulers is a valuable improvement. These resources will help readers dive deeper into the concept of schedulers in RPP and reactive programming, enhancing the overall usefulness of the documentation.
Also applies to: 277-277
291-291: Improved explanation of exception handling in reactive programmingThe rewritten "Exception Guarantee" section provides a much clearer explanation of how exceptions are handled in reactive programming. It effectively contrasts this approach with traditional exception handling and emphasizes the use of the
on_errorfunction. The explanation of unsubscribing and re-subscribing in error handling mechanisms adds valuable context for understanding RPP's behavior.Also applies to: 322-323
1-1: Overall documentation improvementsThe changes made to this documentation file significantly enhance its quality, readability, and usefulness. The improvements include:
- Better document structure and consistency in heading levels.
- Clearer explanations of reactive programming concepts.
- Grammatical corrections and improved phrasing.
- Addition of valuable resources and links.
- Enhanced explanation of exception handling in reactive programming.
These changes will make it easier for users to understand and work with ReactivePlusPlus. The only remaining issue is a minor grammatical error in line 62, which can be easily corrected.
62-62:⚠️ Potential issueCorrect possessive pronoun usage
There's a grammatical error in this line:
- **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state + **set_upstream(disposable)** - observable could pass to observer its own disposable to provide ability for observer to terminate observable's internal actions/stateThe possessive pronoun "its" should be used here instead of the contraction "it's" (which means "it is").
Likely invalid or redundant comment.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~62-~62: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
Doxyfile (4)
57-57: PROJECT_BRIEF updated for clarityThe PROJECT_BRIEF has been modified to provide a more concise description of the project: "ReactiveX implementation for C++20". This change improves the clarity of the project's purpose.
1078-1079: EXCLUDE setting updatedThe EXCLUDE setting has been updated to exclude the 'build' directory and 'docs/doxygen-awesome-css'. This change affects which directories are excluded from documentation.
Excluding the 'build' directory is a good practice. However, ensure that excluding 'docs/doxygen-awesome-css' doesn't remove any necessary documentation files.
Line range hint
1-2922: Overall assessment of Doxyfile changesThe Doxyfile has been significantly updated, focusing on modernizing the documentation appearance and streamlining the generation process. Key changes include:
- Updating to Doxygen version 1.12.0
- Enhancing HTML output with custom stylesheets
- Disabling LaTeX and PDF generation
- Suppressing certain warnings
While these changes generally improve the documentation process, consider the following recommendations:
- Re-enable warnings for undocumented and incomplete documentation to maintain high-quality documentation.
- Reconsider enabling LaTeX and PDF generation for users who prefer offline documentation.
- Enable advanced features like call graphs for more comprehensive documentation.
Overall, the changes are positive, but some adjustments could further improve the documentation quality and accessibility.
1-1: Doxyfile version updated to 1.12.0The Doxyfile version has been updated from 1.9.8 to 1.12.0. This update may introduce new features or changes in behavior. Please ensure that all new settings are properly configured and that the documentation generation process works as expected with this new version.
To verify the impact of this version change, please run the following command and check for any warnings or errors:
| [submodule "docs/doxygen-awesome-css"] | ||
| path = docs/doxygen-awesome-css | ||
| url = https://github.com/jothepro/doxygen-awesome-css.git |
There was a problem hiding this comment.
💡 Codebase verification
Missing HTML_HEADER Configuration for doxygen-awesome-css
While the HTML_EXTRA_STYLESHEET is correctly set to include doxygen-awesome-css, the HTML_HEADER is not configured to use the doxygen-awesome-css theme. This may result in incomplete theming of your Doxygen documentation.
- File to Update:
Doxyfile - Add or Verify the Following Line:
HTML_HEADER = docs/doxygen-awesome-css/header.html
Ensure that the HTML_HEADER points to the correct header file within the doxygen-awesome-css submodule to fully integrate the theme.
🔗 Analysis chain
Excellent addition of the doxygen-awesome-css submodule!
The inclusion of the doxygen-awesome-css submodule is a great choice for enhancing the visual appeal and user experience of your project's documentation. This modern and customizable Doxygen theme will likely make your documentation more engaging and easier to navigate.
To ensure proper integration, please verify that the Doxygen configuration (typically Doxyfile) has been updated to use this theme. You can run the following script to check for the necessary configuration:
If the script doesn't find the necessary configurations, consider updating your Doxyfile to include:
HTML_EXTRA_STYLESHEET = docs/doxygen-awesome-css/doxygen-awesome.css
HTML_HEADER = docs/doxygen-awesome-css/header.html
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify Doxygen configuration for doxygen-awesome-css theme
# Test: Check if HTML_EXTRA_STYLESHEET is set to use doxygen-awesome-css
rg --type-add 'doxyfile:*.Doxyfile' --type doxyfile 'HTML_EXTRA_STYLESHEET.*doxygen-awesome-css'
# Test: Check if HTML_HEADER is set to use doxygen-awesome-css
rg --type-add 'doxyfile:*.Doxyfile' --type doxyfile 'HTML_HEADER.*doxygen-awesome-css'
Length of output: 485
Script:
#!/bin/bash
# Description: Locate all Doxygen configuration files and verify the use of doxygen-awesome-css theme
# Step 1: Find all potential Doxygen configuration files
fd --extension Doxyfile --type file > doxyfiles_list.txt
# Step 2: Display the list of found Doxygen configuration files
cat doxyfiles_list.txt
# Step 3: Search for HTML_EXTRA_STYLESHEET and HTML_HEADER settings in each found Doxyfile
while IFS= read -r file; do
echo "Checking $file for doxygen-awesome-css configurations:"
rg 'HTML_EXTRA_STYLESHEET.*doxygen-awesome-css' "$file" || echo "HTML_EXTRA_STYLESHEET not set correctly in $file"
rg 'HTML_HEADER.*doxygen-awesome-css' "$file" || echo "HTML_HEADER not set correctly in $file"
echo ""
done < doxyfiles_list.txt
Length of output: 84
Script:
#!/bin/bash
# Description: Search for any Doxygen configuration references in the repository
# Step 1: Find all files with 'Doxygen' in their name, case-insensitive
fd -i 'Doxygen' --type file > doxygen_files_list.txt
# Step 2: Display the list of found files
if [ -s doxygen_files_list.txt ]; then
echo "Found Doxygen-related configuration files:"
cat doxyfiles_list.txt
else
echo "No files with 'Doxygen' in their name were found."
fi
# Step 3: Search all files for 'Doxygen' mentions, case-insensitive
echo "Searching for 'Doxygen' mentions in the codebase..."
rg -i 'Doxygen' > doxygen_mentions.txt
if [ -s doxygen_mentions.txt ]; then
echo "Found the following 'Doxygen' mentions:"
cat doxygen_mentions.txt
else
echo "No mentions of 'Doxygen' were found in the codebase."
fi
Length of output: 23080
| <briefdescription visible="yes"/> | ||
| <includes visible="$SHOW_HEADERFILE"/> | ||
| <inheritancegraph visible="$CLASS_GRAPH"/> | ||
| <inheritancegraph visible="no"/> |
There was a problem hiding this comment.
Reconsider disabling inheritance graphs for all classes.
The inheritance graph visibility has been set to "no" for all classes. While this can reduce clutter for simple classes, it might hide valuable information for complex class hierarchies.
Consider a more flexible approach:
- Keep the original
$CLASS_GRAPHvariable to allow per-project configuration. - Use a threshold (e.g., minimum number of derived classes) to determine when to show the graph.
- Provide a way to enable/disable graphs for specific classes using special comments.
Would you like assistance in implementing a more flexible solution?
| <enums title=""/> | ||
| <functions title=""/> | ||
| <variables title=""/> | ||
| <properties title=""/> |
There was a problem hiding this comment.
Clarify the purpose of adding properties to namespaces.
Properties have been added to both the memberdecl and memberdef sections of the namespace layout. This is unusual for C++ namespaces, which typically don't have properties.
Please clarify:
- What types of elements are intended to be documented as "properties" within namespaces?
- Is this meant to document static members or global variables within namespaces?
- If this is not applicable to C++ namespaces, consider removing these entries to avoid confusion.
Would you like assistance in refining this section to better reflect C++ namespace documentation needs?
Also applies to: 134-134
| <enums title=""/> | ||
| <functions title=""/> | ||
| <variables title=""/> | ||
| <properties title=""/> |
There was a problem hiding this comment.
Clarify the purpose of adding properties to file documentation.
Properties have been added to both the memberdecl and memberdef sections of the file layout. This is unusual for C++ file documentation, as files typically don't have properties in the traditional sense.
Please clarify:
- What types of elements are intended to be documented as "properties" for files?
- Is this meant to document file-level attributes, metadata, or some other information?
- If this is not applicable to C++ file documentation, consider removing these entries to avoid confusion.
Would you like assistance in refining this section to better reflect C++ file documentation needs?
Also applies to: 183-183
| # The default value is: NO. | ||
|
|
||
| QUIET = NO | ||
| QUIET = YES |
There was a problem hiding this comment.
QUIET option set to YES
The QUIET option has been changed from NO to YES. This will suppress standard output messages during documentation generation. While this can make the process less verbose, it might also hide important information or warnings.
Consider setting QUIET back to NO to ensure you don't miss any important messages during the documentation generation process.
| # dependency graph for every global function or class method. | ||
| # |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Consider enabling advanced documentation features
The current configuration uses mostly default settings for advanced features. Consider enabling call graphs and caller graphs to provide more comprehensive documentation:
-CALL_GRAPH = NO
+CALL_GRAPH = YES
-CALLER_GRAPH = NO
+CALLER_GRAPH = YESThese changes will generate visual representations of function call relationships, which can be helpful for understanding the codebase structure.
Also applies to: 2761-2762
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| <html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO" class="light-mode"> | ||
| <head> | ||
| <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> |
There was a problem hiding this comment.
Correct the MIME type in the Content-Type meta tag
The Content-Type meta tag specifies an incorrect MIME type of "text/xhtml", which is not standard. The correct MIME type for XHTML documents is "application/xhtml+xml". Additionally, a semicolon should separate the MIME type and the charset parameter.
Apply this diff to fix the MIME type and syntax:
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8"/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | |
| <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8"/> |
| <tbody> | ||
| <tr id="projectrow"> | ||
| <!--BEGIN PROJECT_LOGO--> | ||
| <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td> |
There was a problem hiding this comment.
Add missing space before $logosize in the img tag
In the img tag for the project logo, there's no space between $projectlogo" and $logosize. This could cause the attributes to concatenate incorrectly, resulting in invalid HTML.
Apply this diff to add the missing space:
-<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td>
+<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo" $logosize/></td>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td> | |
| <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo" $logosize/></td> |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (2)
docs/readme.md (2)
Line range hint
275-289: New Disposable section adds valuable informationThe addition of the Disposable section provides crucial information about resource management in RPP. The explanation of Upstream and External disposables helps users understand how to properly manage resources in their reactive programming applications.
To further improve this section:
Consider adding a brief code example demonstrating the use of both Upstream and External disposables. This would help reinforce the concepts and provide a practical reference for users.
320-321: Comprehensive Advanced details sectionThe new Advanced details section provides valuable in-depth information about disposables and dynamic_* versions of classes. This information is crucial for users who need to work with disposables at a lower level or deal with type-erased wrappers. The explanations are detailed and offer good insights into the internal workings of RPP.
To further enhance this section:
Consider adding a brief summary at the beginning of the Advanced details section to give readers an overview of what to expect. This could help users quickly determine if they need this level of detail.
Also applies to: 323-445
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
- Doxyfile (107 hunks)
- DoxygenLayout.xml (5 hunks)
- docs/custom.css (1 hunks)
- docs/readme.md (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/custom.css
🧰 Additional context used
🪛 LanguageTool
docs/readme.md
[uncategorized] ~61-~61: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
🔇 Additional comments (12)
DoxygenLayout.xml (4)
3-3: Improved documentation structure and navigationThe update to Doxygen 1.12.0 and the new navigation structure are excellent improvements:
- The version update ensures compatibility with the latest Doxygen features.
- The new "usergroup" tab with multiple sub-tabs provides more granular access to different parts of the documentation, which should significantly improve user navigation and overall documentation usability.
These changes will make it easier for users to find and access specific parts of the API documentation.
Also applies to: 8-44
52-52: Reconsider disabling inheritance graphs for all classesThe inheritance graph visibility has been set to "no" for all classes. While this can reduce clutter for simple classes, it might hide valuable information for complex class hierarchies.
Consider a more flexible approach:
- Keep the original
$CLASS_GRAPHvariable to allow per-project configuration.- Use a threshold (e.g., minimum number of derived classes) to determine when to show the graph.
- Provide a way to enable/disable graphs for specific classes using special comments.
This approach would maintain flexibility while still allowing for cleaner documentation where appropriate.
Would you like assistance in implementing a more flexible solution?
124-124: Clarify the purpose of adding properties to namespacesProperties have been added to both the
memberdeclandmemberdefsections of the namespace layout. This is unusual for C++ namespaces, which typically don't have properties.Please clarify:
- What types of elements are intended to be documented as "properties" within namespaces?
- Is this meant to document static members or global variables within namespaces?
- If this is not applicable to C++ namespaces, consider removing these entries to avoid confusion.
Would you like assistance in refining this section to better reflect C++ namespace documentation needs?
Also applies to: 136-136
172-172: Clarify the purpose of adding properties to file documentationProperties have been added to both the
memberdeclandmemberdefsections of the file layout. This is unusual for C++ file documentation, as files typically don't have properties in the traditional sense.Please clarify:
- What types of elements are intended to be documented as "properties" for files?
- Is this meant to document file-level attributes, metadata, or some other information?
- If this is not applicable to C++ file documentation, consider removing these entries to avoid confusion.
Would you like assistance in refining this section to better reflect C++ file documentation needs?
Also applies to: 185-185
docs/readme.md (3)
1-1: Improved clarity and grammatical accuracyThe changes in the introduction section enhance the overall readability and correctness of the document. The new title "Manual documentation" is more descriptive, and the rephrasing of recommendations and descriptions of input/output types provides better clarity for the readers.
Also applies to: 8-8, 13-13, 16-16, 19-19, 21-21, 27-27, 34-38, 44-46, 48-48, 52-52
273-275: Improved Schedulers documentationThe changes in the Schedulers section greatly enhance the explanation of this important concept in RPP. The expanded description and the addition of code examples for
subscribe_onandobserve_onprovide valuable insights into how Schedulers work and how they can be used effectively. This will help users better understand and implement multithreading in their reactive programming applications.
Line range hint
1-445: Overall documentation improvements are substantial and valuableThe changes made to the
docs/readme.mdfile significantly enhance the RPP documentation. Key improvements include:
- Better structure and formatting throughout the document.
- Expanded explanations of core concepts, including Observables and Schedulers.
- New sections on Disposables and Advanced details, providing valuable information for both beginners and advanced users.
- Addition of code examples to illustrate key concepts.
These changes will greatly benefit users of the RPP library by providing clearer, more comprehensive, and more practical documentation.
To further polish the document:
- Correct the grammatical error in the Core Concepts section (replace "it's" with "its").
- Consider adding a brief code example in the Disposable section.
- Add a summary at the beginning of the Advanced details section.
Great work on improving the documentation!
🧰 Tools
🪛 LanguageTool
[uncategorized] ~61-~61: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
Doxyfile (5)
57-57: Project brief description updated.The project brief has been concisely defined as "ReactiveX implementation for C++20". This provides a clear and succinct description of the project's purpose.
1078-1079: Build directory excluded from documentation.The EXCLUDE setting has been updated to exclude the 'build' directory. This is a good practice as it prevents generated build files from being included in the documentation.
Line range hint
970-976: Input configuration appropriately set for C++ project.The INPUT setting includes relevant source and documentation directories. FILE_PATTERNS covers a wide range of file types commonly used in C++ projects. Setting RECURSIVE to YES ensures all subdirectories are processed. These configurations will result in comprehensive documentation coverage.
Also applies to: 1013-1064, 1072-1072
1432-1435: Custom styling and scripts added for HTML output.Custom stylesheets and JavaScript files have been added to enhance the appearance and functionality of the HTML documentation. This includes:
- Doxygen Awesome CSS for improved styling
- Dark mode toggle functionality
- Fragment copy button for code snippets
These additions will likely improve the user experience of the generated documentation.
Also applies to: 1445-1446
Line range hint
1-2922: Overall Doxyfile configuration review summaryThe Doxyfile has been configured with a focus on generating HTML documentation for the ReactivePlusPlus project. Key points:
- Project information and output settings are well-defined.
- Custom styling and scripts have been added to enhance the HTML output.
- LaTeX and PDF generation have been disabled, which may limit documentation format options.
- Warnings for undocumented and incomplete documentation have been turned off, potentially affecting documentation thoroughness.
- The Dot tool for generating graphs is disabled, limiting visual representations in the documentation.
Consider addressing the issues raised in the previous comments to further improve the documentation generation process and output quality.
| ## Core Concepts | ||
|
|
||
| In short, Reactive Programming can be described as follows: | ||
| Reactive Programming can be described as follows: |
There was a problem hiding this comment.
Enhanced Core Concepts explanation
The changes in the Core Concepts section improve the structure and completeness of the documentation. The consistent formatting of headings and the expanded explanation of Observable notifications provide more comprehensive guidance for users.
However, there's a minor grammatical error that should be corrected:
In line 61, replace "it's" with "its":
- **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state
+ **set_upstream(disposable)** - observable could pass to observer its own disposable to provide ability for observer to terminate observable's internal actions/stateAlso applies to: 57-63
| # The default value is: YES. | ||
|
|
||
| WARN_IF_UNDOCUMENTED = YES | ||
| WARN_IF_UNDOCUMENTED = NO |
There was a problem hiding this comment.
Warning: Undocumented and incomplete documentation warnings disabled.
WARN_IF_UNDOCUMENTED and WARN_IF_INCOMPLETE_DOC have been set to NO. This will suppress warnings for undocumented members and incomplete function parameter documentation. While this reduces noise in the documentation generation process, it may lead to less comprehensive documentation.
Consider re-enabling these warnings to ensure thorough documentation coverage:
-WARN_IF_UNDOCUMENTED = NO
+WARN_IF_UNDOCUMENTED = YES
-WARN_IF_INCOMPLETE_DOC = NO
+WARN_IF_INCOMPLETE_DOC = YESAlso applies to: 892-892
|
|
||
| GENERATE_LATEX = YES | ||
| GENERATE_LATEX = NO | ||
|
|
There was a problem hiding this comment.
LaTeX and PDF generation disabled.
GENERATE_LATEX and USE_PDFLATEX have been set to NO, disabling the generation of LaTeX and PDF documentation.
While this may reduce documentation build time, it removes the option for users to generate PDF documentation. Consider re-enabling these options if PDF documentation would be useful for your users:
-GENERATE_LATEX = NO
+GENERATE_LATEX = YES
-USE_PDFLATEX = NO
+USE_PDFLATEX = YESAlso applies to: 2169-2169
| # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed | ||
| # to run in parallel. When set to 0 doxygen will base this on the number of | ||
| # The DOT_NUM_THREADS specifies the number of dot invocations Doxygen is allowed | ||
| # to run in parallel. When set to 0 Doxygen will base this on the number of |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Consider enabling the Dot tool for enhanced documentation.
The HAVE_DOT option is set to NO, which disables the use of the Graphviz Dot tool. Enabling this tool can greatly enhance your documentation by providing visual representations of class hierarchies, collaboration diagrams, and call graphs.
Consider setting HAVE_DOT to YES if Graphviz is available in your environment:
-HAVE_DOT = NO
+HAVE_DOT = YESThis will allow you to generate helpful diagrams that can aid in understanding the structure and relationships within your codebase.
Committable suggestion was skipped due to low confidence.
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (6)
.github/workflows/ci v2.yml (4)
220-221: Consider updating the Python version.The current setup uses Python 3.8, which might be outdated. Consider using a more recent version of Python, such as 3.9 or later, to ensure you have access to the latest features and security updates.
You can update the Python version like this:
- uses: actions/setup-python@v5 - with: { python-version: "3.8" } + uses: actions/setup-python@v5 + with: { python-version: "3.11" }
Line range hint
232-233: Specify the Doxygen configuration file.The current Doxygen command doesn't specify a configuration file. It's a good practice to explicitly specify the Doxyfile to ensure consistency across different environments.
Consider updating the Doxygen command to:
- run: doxygen + run: doxygen Doxyfile
Line range hint
235-241: Add explicit permissions for the GitHub token.While the deployment step uses the
GITHUB_TOKENsecret, it's a good practice to explicitly declare the required permissions for security reasons.Consider adding a
permissionsblock at the job level:jobs: docs: permissions: contents: write # ... rest of the job configuration
Line range hint
243-271: Consider updating GCC version and adding tests.
The job is using GCC 10, which might be outdated. Consider using a more recent version of GCC or allowing the use of the default compiler on the runner.
The Qt sample build is commented out without explanation. If it's not needed, consider removing it entirely. If it's temporarily disabled, add a comment explaining why.
The job builds the project and a sample, but doesn't include any testing steps. Consider adding a step to run tests on the built sample to ensure it works as expected.
Here's a suggested update to address these points:
use_rpp_as_package: timeout-minutes: 20 runs-on: ubuntu-latest name: Test RPP as package - ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Qt uses: jurplel/install-qt-action@v4 with: cache: true - name: Install project and build - env: - CC: gcc-10 - CXX: g++-10 run: | cmake -B build sudo cmake --build build --target install --parallel 2 --config Release cmake -B sample_build -S src/examples/rpp/package cmake --build sample_build --parallel 2 --config Release - # cmake -B qt_sample_build -S src/examples/rppqt/package - # cmake --build qt_sample_build --parallel 2 --config Release + # TODO: Re-enable Qt sample build when it's ready + # cmake -B qt_sample_build -S src/examples/rppqt/package + # cmake --build qt_sample_build --parallel 2 --config Release + - name: Run tests + run: | + cd sample_build + ctest -C Release --output-on-failureThis update removes the GCC version constraint, adds a TODO comment for the Qt sample build, and includes a step to run tests on the built sample.
docs/readme.md (2)
52-52: Enhanced Core Concepts explanation with minor grammatical issueThe changes in this section significantly improve the documentation:
- Consistent formatting of headings enhances readability.
- Expanded explanation of Observable notifications provides more comprehensive guidance.
However, there's a minor grammatical error that should be corrected:
In line 61, replace "it's" with "its":
- **set_upstream(disposable)** - observable could pass to observer it's own disposable to provide ability for observer to terminate observable's internal actions/state + **set_upstream(disposable)** - observable could pass to observer its own disposable to provide ability for observer to terminate observable's internal actions/stateAlso applies to: 54-63, 64-64
414-432: Valuable Extensions section added with minor grammatical issueThe new Extensions section is a great addition to the documentation:
- It provides information about integrating RPP with other frameworks and libraries.
- Specific extensions (rppqt, rppgrpc, rppasio) are introduced with links to their respective API references.
This information will help users leverage RPP in a wider range of applications.
However, there's a minor grammatical issue that should be corrected:
In line 416, replace "much more better" with "much better":
- Below you can find list of extensions for RPP with adaption to external frameworks for much more easiser integeration with RPP. These extensions are part of RPP library: + Below you can find a list of extensions for RPP with adaptation to external frameworks for much easier integration with RPP. These extensions are part of the RPP library:🧰 Tools
🪛 LanguageTool
[grammar] ~416-~416: Use only “better” (without ‘more’) when you use the comparative.
Context: ...f them RPP can be unified to build much more better software. Below you can find list of ex...(MOST_COMPARATIVE)
🪛 Markdownlint
414-414: Punctuation: ':'
Trailing punctuation in heading(MD026, no-trailing-punctuation)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
- .github/workflows/ci v2.yml (1 hunks)
- docs/readme.md (6 hunks)
- src/extensions/rppgrpc/rppgrpc/fwd.hpp (1 hunks)
- src/extensions/rppqt/rppqt/fwd.hpp (1 hunks)
- src/rpp/rpp/fwd.hpp (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/extensions/rppgrpc/rppgrpc/fwd.hpp
- src/extensions/rppqt/rppqt/fwd.hpp
- src/rpp/rpp/fwd.hpp
🧰 Additional context used
🪛 LanguageTool
docs/readme.md
[uncategorized] ~61-~61: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
[grammar] ~416-~416: Use only “better” (without ‘more’) when you use the comparative.
Context: ...f them RPP can be unified to build much more better software. Below you can find list of ex...(MOST_COMPARATIVE)
🪛 Markdownlint
docs/readme.md
414-414: Punctuation: ':'
Trailing punctuation in heading(MD026, no-trailing-punctuation)
🔇 Additional comments (6)
docs/readme.md (6)
1-1: Improved clarity and readability in the Introduction sectionThe changes in this section enhance the overall quality of the document:
- The title is now more specific and descriptive.
- Grammar improvements make the text more professional.
- The explanation of input/output types is more concise and easier to understand.
These updates will help readers grasp the concepts more easily.
Also applies to: 8-8, 13-13, 16-16, 19-21, 27-27, 34-38, 44-46, 48-48
132-132: Improved structure of the Observable contract sectionThe restructuring of this section enhances readability without altering the underlying information. This change will help users better understand the Observable contract, which is a crucial concept in reactive programming.
136-136: Enhanced explanation of Operators with examplesThe updates to the Operators section significantly improve the documentation:
- The purpose and usage of operators are now more clearly explained.
- The added examples illustrate how operators work in practice.
These changes will help users better understand how to implement and use operators effectively in their RPP projects.
Also applies to: 138-138, 140-140
273-275: Added valuable resources for SchedulersThe updates to the Schedulers section enhance the documentation by providing links to additional resources:
- A link to the API Reference for more details about schedulers in RPP.
- A link to the ReactiveX documentation for general information about schedulers.
These additions will help users find more in-depth information about schedulers when needed.
289-289: Comprehensive explanation of Disposables addedThe Disposable section has been significantly improved:
- A more detailed explanation of the concept and purpose of disposables has been added.
- Different types of disposables (upstream and external) are now explained.
- The advanced details section provides in-depth information about disposable-related classes and their usage.
These additions will greatly help users understand and implement proper resource management in their RPP applications.
Also applies to: 320-321, 323-413
Line range hint
1-432: Overall significant improvements to the RPP documentationThe changes made to this documentation file greatly enhance its quality and usefulness:
- Improved clarity and readability throughout the document.
- Enhanced explanations of core concepts, operators, and disposables.
- Addition of valuable examples and links to external resources.
- New Extensions section providing information on integrating RPP with other frameworks.
These updates will significantly benefit users of the RPP library by providing clearer explanations, more examples, and additional resources for learning and implementing reactive programming concepts.
The few minor grammatical issues identified have been addressed in previous comments and do not significantly impact the overall quality of the document.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~61-~61: Did you mean “its” (the possessive pronoun)?
Context: ...)** - observable could pass to observer it's own disposable to provide ability for o...(ITS_PREMIUM)
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
Readme.md (3)
43-46: Enhanced information on supported modules.The addition of GRPC and boost::asio modules provides valuable information about the library's capabilities. This improvement helps users understand the full range of integrations available.
Consider adding a brief description of each module's purpose to provide more context for users unfamiliar with these technologies.
🧰 Tools
Also RPP supports out of box: - QT as rppqt module. Checkout [RPPQT...🪛 LanguageTool
[uncategorized] ~43-~43: You might be missing the article “the” here.
Context: ....(AI_EN_LECTOR_MISSING_DETERMINER_THE)
51-55: Improved comparison with existing libraries.
The rephrasing of this section provides a clearer and more balanced comparison of ReactivePlusPlus with existing Reactive Extension libraries. The corrections address previous review comments and enhance the overall readability.
However, there's a minor typo that needs correction:
- While RxCpp is a great and powerful library, it has some disadvantages. It is written in C++11 and contains parts written in pre-C++11 style. This leads to a mess of old-style classes and wrappers. Additionally, the `rxcpp::observable` type has a long chain of template parameters, which can lead to slower IDE performance and larger binaries. Sometimes it has bad performance due to tremendous amount of usage of heap or just non-effective logic.
+ While RxCpp is a great and powerful library, it has some disadvantages. It is written in C++11 and contains parts written in pre-C++11 style. This leads to a mess of old-style classes and wrappers. Additionally, the `rxcpp::observable` type has a long chain of template parameters, which can lead to slower IDE performance and larger binaries. Sometimes it has bad performance due to a tremendous amount of usage of heap or just non-effective logic.Line range hint 76-81: Valuable addition of compiler requirements.
The inclusion of minimum compiler requirements is an excellent addition to the Usage section. It clearly communicates the C++20 dependency and helps users quickly determine if their development environment is compatible.
Consider adding a link to the C++20 feature support page for each compiler, which would help users verify their compiler's compatibility in more detail.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- Readme.md (6 hunks)
🧰 Additional context used
🪛 LanguageTool
Also RPP supports out of box: - QT as rppqt...Readme.md
[uncategorized] ~42-~42: A comma may be missing after the conjunctive/linking adverb ‘Also’.
Context: ... just printing to console.(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[uncategorized] ~43-~43: You might be missing the article “the” here.
Context: ....
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
🪛 Markdownlint
Readme.md
47-47: null
Fenced code blocks should have a language specified(MD040, fenced-code-language)
🔇 Additional comments (4)
Readme.md (4)
9-11: Improved badge selection enhances project information.The addition of badges for the User Guide, API Reference, and Benchmarks provides quick access to essential resources. The removal of the C++20 badge is appropriate as this information is now explicitly mentioned in the usage section.
38-40: Improved clarity in introduction and code example.The rephrasing in the "What is that?" section enhances clarity. The typo correction in the code example (changing "takeing" to "taking") improves the accuracy of the demonstration.
64-64: Enhanced clarity in describing ReactivePlusPlus advantages.The refinements in this section provide a clearer and more accurate description of ReactivePlusPlus's advantages. The corrections address previous review comments and improve the overall readability. The emphasis on performance, modern C++ design, and adherence to the "zero-overhead principle" effectively communicates the library's strengths.
Also applies to: 68-68
84-93: Improved organization and accessibility of documentation and resources.The refinements to the Documentation section and the expansion of the Useful links section enhance the README's value to users. The clear distinction between the User Guide/Tutorial and the API Reference helps users find the appropriate resource for their needs. The addition of links to examples, interactive diagrams, and benchmarking results provides a comprehensive set of resources for users to explore and understand the library.
|



Summary by CodeRabbit
New Features
Documentation
Readme.mdfile, emphasizing the library's purpose and advantages, and correcting typos.Readme.mdfor better user navigation.rppgrpcmodule for improved discoverability.