summaryrefslogtreecommitdiffhomepage
path: root/compat/util.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-10-26 07:25:50 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-10-26 07:25:50 +0200
commit644494f7cf27cb8dbe89a50885f57a7266a06e63 (patch)
treeab5fbd8ed026677c0669cd991b4d7461a23736b1 /compat/util.hpp
parent869ada0bca37aafc9a803f3226458f163db5f3c8 (diff)
compat/util: split out run-in-thread{,-async}
Diffstat (limited to 'compat/util.hpp')
-rw-r--r--compat/util.hpp87
1 files changed, 1 insertions, 86 deletions
diff --git a/compat/util.hpp b/compat/util.hpp
index 528ae1a8..7a6858a3 100644
--- a/compat/util.hpp
+++ b/compat/util.hpp
@@ -1,16 +1,10 @@
#pragma once
#include "make-unique.hpp"
+#include "run-in-thread.hpp"
#include <memory>
#include <cmath>
-#include <utility>
-#include <type_traits>
-#include <thread>
-#include <condition_variable>
-
-#include <QObject>
-#include <QDebug>
#define progn(...) ([&]() { __VA_ARGS__ }())
template<typename t> using mem = std::shared_ptr<t>;
@@ -47,82 +41,3 @@ inline auto clamp(const t& val, const u& min, const w& max) -> decltype(val * mi
{
return ::detail::clamp_<decltype(val * min * max)>(val, min, max);
}
-
-namespace detail {
-
-template<typename t>
-struct run_in_thread_traits
-{
- using type = t;
- using ret_type = t&&;
- static inline void assign(t& lvalue, t&& rvalue) { lvalue = rvalue; }
- static inline ret_type&& pass(ret_type&& val) { return std::move(val); }
- template<typename F> static ret_type call(F& fun) { return std::move(fun()); }
-};
-
-template<>
-struct run_in_thread_traits<void>
-{
- using type = unsigned char;
- using ret_type = void;
- static inline void assign(unsigned char&, unsigned char&&) {}
- static inline void pass(type&&) {}
- template<typename F> static type&& call(F& fun) { fun(); return std::move(type(0)); }
-};
-
-}
-
-template<typename F>
-auto run_in_thread_sync(QObject* obj, F&& fun)
- -> typename detail::run_in_thread_traits<decltype(std::forward<F>(fun)())>::ret_type
-{
- using lock_guard = std::unique_lock<std::mutex>;
-
- std::mutex mtx;
- lock_guard guard(mtx);
- std::condition_variable cvar;
-
- std::thread::id waiting_thread = std::this_thread::get_id();
-
- using traits = detail::run_in_thread_traits<decltype(std::forward<F>(fun)())>;
-
- typename traits::type ret;
-
- bool skip_wait = false;
-
- {
- QObject src;
- src.moveToThread(obj->thread());
- QObject::connect(&src,
- &QObject::destroyed,
- obj,
- [&]() {
- std::thread::id calling_thread = std::this_thread::get_id();
- if (waiting_thread == calling_thread)
- {
- skip_wait = true;
- traits::assign(ret, traits::call(fun));
- }
- else
- {
- lock_guard guard(mtx);
- traits::assign(ret, traits::call(fun));
- cvar.notify_one();
- }
- },
- Qt::AutoConnection);
- }
-
- if (!skip_wait)
- cvar.wait(guard);
- return traits::pass(std::move(ret));
-}
-
-template<typename F>
-void run_in_thread_async(QObject* obj, F&& fun)
-{
- QObject src;
- src.moveToThread(obj->thread());
- QObject::connect(&src, &QObject::destroyed, obj, std::move(fun), Qt::AutoConnection);
-}
-