Loading...
Searching...
No Matches
WorkerBinding.hpp
1#pragma once
2#include <score/tools/ThreadPool.hpp>
3
4#include <avnd/concepts/worker.hpp>
5
6#include <memory>
7#include <type_traits>
8#include <utility>
9
10namespace oscr
11{
30template <typename Object, typename Delivery>
31void bind_worker(Object& obj, std::weak_ptr<Object> obj_wp, Delivery deliver)
32{
33 using worker_type = decltype(obj.worker);
34 auto& tq = score::TaskPool::instance();
35
36 obj.worker.request = [&tq, obj_wp = std::move(obj_wp),
37 deliver = std::move(deliver)]<typename... Args>(Args&&... f) mutable {
38 tq.post([obj_wp, job = deliver.begin(), ... ff = std::forward<Args>(f)]() mutable {
39 auto deliver = std::move(job);
40 // The object was removed meanwhile: not much reason to perform the work,
41 // unless the worker says this job must be done whatever, e.g. a file
42 // the object leaves as it stops: static bool must_run(args...).
43 bool needed = bool(obj_wp.lock());
44 if constexpr(requires { worker_type::must_run(ff...); })
45 needed = needed || worker_type::must_run(ff...);
46 if(!needed)
47 return;
48
49 using type_of_result = decltype(worker_type::work(std::forward<decltype(ff)>(ff)...));
50 if constexpr(std::is_void_v<type_of_result>)
51 {
52 worker_type::work(std::forward<decltype(ff)>(ff)...);
53 }
54 else
55 {
56 auto res = worker_type::work(std::forward<decltype(ff)>(ff)...);
57 if(!res)
58 return;
59
60 // res is mutable so that it can e.g. keep data to free elsewhere.
61 deliver([obj_wp = std::move(obj_wp), res = std::move(res)]() mutable {
62 if(auto o = obj_wp.lock())
63 res(*o);
64 });
65 }
66 });
67 };
68}
69}
Definition Controls.hpp:30
void bind_worker(Object &obj, std::weak_ptr< Object > obj_wp, Delivery deliver)
Definition WorkerBinding.hpp:31