Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ include(cmake/prelude.cmake)

project(
ReactivePlusPlus
VERSION 0.1.4
VERSION 0.2.0
DESCRIPTION "ReactivePlusPlus is library for building asynchronous event-driven streams of data with help of sequences of primitive operators in the declarative form"
HOMEPAGE_URL "https://github.com/victimsnino/ReactivePlusPlus"
LANGUAGES CXX
Expand Down
1 change: 1 addition & 0 deletions src/examples/rppqt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(interactive_window)
add_subdirectory(doxygen)
add_subdirectory(multi_threaded)
9 changes: 9 additions & 0 deletions src/examples/rppqt/multi_threaded/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SET(TARGET multi_threaded)
add_executable(${TARGET}
${TARGET}.cpp
)

target_link_libraries(${TARGET} PRIVATE rppqt ${RPP_QT_TARGET}::Widgets)
set_target_properties(${TARGET} PROPERTIES FOLDER Examples/rppqt)

rpp_add_qt_support_to_executable(${TARGET})
71 changes: 71 additions & 0 deletions src/examples/rppqt/multi_threaded/multi_threaded.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <rpp/rpp.hpp>
#include <rppqt/rppqt.hpp>

#include <iostream>

#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QMainWindow>
#include <QVBoxLayout>

int main(int argc, char* argv[])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ bugprone-exception-escape ⚠️
an exception may be thrown in function main which should not throw exceptions

{
QApplication app{argc, argv};
QVBoxLayout vbox{};

QLabel label{};
QPushButton button{"CLick me"};
vbox.addWidget(&label);
vbox.addWidget(&button);
QMainWindow window{};

window.setCentralWidget(new QWidget);
window.centralWidget()->setLayout(&vbox);

window.show();

rpp::source::interval(std::chrono::seconds{1})
.tap([](const auto&)
{
std::cout << "Interval from thread: " << std::this_thread::get_id() << std::endl;
})
.combine_latest([](size_t index, size_t amount_of_clicks)
{
return QString("Seconds since start: %1 Clicks since start: %2").arg(index).arg(amount_of_clicks);
},
rppqt::source::from_signal(button, &QPushButton::pressed).scan(size_t{},
[](size_t seed, const auto&)
{
return seed + 1;
})
.tap([](const auto&)
{
std::cout << "Click from thread: " <<
std::this_thread::get_id() << std::endl;
})
.start_with(size_t{0}))
.subscribe_on(rpp::schedulers::new_thread{})
.observe_on(rppqt::schedulers::main_thread_scheduler{})
.subscribe([&](const QString& text)
{
std::cout << "Text updated from thread: " << std::this_thread::get_id() << std::endl;
label.setText(text);
});

std::cout << "Application thread: " << std::this_thread::get_id() << std::endl;

// There we have application's thread, "new_thread" where observable subscribed and interval events happened.
// But we need to update GUI's objects in main thread, so, we forces observable to emit items to subscribe in QT's main thread
// Example of output:
/*
Application thread: 19748 <----- main thread
Interval from thread: 30604 <----- interval happens from another thread
Text updated from thread: 19748 <----- but update then transfered to main thread
Click from thread: 19748 <----- click happens from main thread due to QT logic
Text updated from thread: 19748 <----- and update happens in main thread
Interval from thread: 30604
Text updated from thread: 19748
*/
return app.exec();
}
2 changes: 1 addition & 1 deletion src/rppqt/rppqt/schedulers/main_thread_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class main_thread_scheduler final : public rpp::schedulers::details::scheduler_t
throw utils::no_active_qapplication{
"Pointer to application is null. Create QApplication before using main_thread_scheduler!"};

const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now() - time_point).count();
const auto duration = std::max(std::chrono::milliseconds{0}, std::chrono::duration_cast<std::chrono::milliseconds>(time_point - now()));
QTimer::singleShot(duration, application, std::move(fn));
}

Expand Down