Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using the rxqt::run_loop in a large code base #28

Open
michalfapso opened this issue Feb 23, 2021 · 1 comment
Open

Using the rxqt::run_loop in a large code base #28

michalfapso opened this issue Feb 23, 2021 · 1 comment
Labels

Comments

@michalfapso
Copy link

Hi Tetsuro. Thanks for this library.

What is the preferred way to use the rxqt::run_loop in a larger codebase with a lot of classes?

As all qt gui related methods have to be run in the main (gui) thread, in all such cases, I need to add .observe_on(main_thread) before each .subscribe(...). I saw your example https://github.com/tetsurom/rxqt/blob/master/sample/thread/main.cpp, but when the code is spread among multiple source files, these options come to my mind:

  1. Encapsulate the rxqt::run_loop in a singleton and initialize it after QApplication
  2. Create the rxqt::run_loop after QApplication, and then put just the result of rxqt_run_loop.observe_on_run_loop() into a singleton.
  3. Before each place where I'd like to use .observe_on(main_thread), I'd put
    rxqt::run_loop rxqt_run_loop;
    auto main_thread = rxqt_run_loop.observe_on_run_loop();
    

Are these approaches equivalent in functionality? The 2. option would lead to the least code bloat. What would you prefer?

Thanks for any hints.
Michal

@michalfapso
Copy link
Author

The singleton approach could look like this:

foo.cpp where we need to subscribe on the gui thread:

#include "rxqt_gui_thread.h"
#include <cassert>
...
some_request
.observe_on(RxqtGuiThread::GetInstance().Get()) // <-- This is the important part
.subscribe([](auto){
	assert(qApp->thread() == QThread::currentThread());
});
...

main.cpp:

int main(int argc, char** argv)
{
	QApplication app(argc, argv);
	RxqtGuiThread::GetInstance(); // Initialization must happen in the gui thread
	...
}

rxqt_gui_thread.h:

#ifndef RXQTGUITHREAD_H
#define RXQTGUITHREAD_H

#include "singleton.h"
#include "rxcpp/rx.hpp"
#include "rxqt.hpp"
#include <QCoreApplication>
#include <cassert>

namespace detail {
class RxqtGuiThread
{
	public:
		RxqtGuiThread()
			: mLoop()
			, mWorker(mLoop.observe_on_run_loop())
		{
			assert(qApp->thread() == QThread::currentThread());
		}

		rxcpp::observe_on_one_worker Get() const { return mWorker; }
	private:
		rxqt::run_loop mLoop;
		rxcpp::observe_on_one_worker mWorker;
};
}

typedef Singleton<detail::RxqtGuiThread> RxqtGuiThread;

#endif // RXQTGUITHREAD_H

singleton.h (just for completeness):

#ifndef SINGLETON_H
#define SINGLETON_H

template <class T>
class Singleton
{
	public:
		static T& GetInstance()
		{
			static T instance;
			return instance;
		}
    private:
        Singleton();                      // Don't implement
        Singleton(Singleton const&);      // Don't Implement
        void operator=(Singleton const&); // Don't implement
};

#endif // SINGLETON_H

It seems to work well :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants