libfilezilla
invoker.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_INVOKER_HEADER
2 #define LIBFILEZILLA_INVOKER_HEADER
3 
8 #include "event_handler.hpp"
9 
10 namespace fz {
11 
13 struct invoker_event_type{};
14 
16 typedef simple_event<invoker_event_type, std::function<void()>> invoker_event;
17 
19 class FZ_PUBLIC_SYMBOL thread_invoker final : public event_handler
20 {
21 public:
22  thread_invoker(event_loop& loop);
23  virtual ~thread_invoker();
24 
25  virtual void operator()(event_base const& ev) override;
26 };
27 
29 template<typename... Args>
30 std::function<void(Args...)> do_make_invoker(event_loop& loop, std::function<void(Args...)> && f)
31 {
32  return [handler = thread_invoker(loop), f](Args&&... args) mutable {
33  auto cb = [f, targs = std::make_tuple(std::forward<Args>(args)...)] {
34  std::apply(f, targs);
35  };
36  handler.send_event<invoker_event>(std::move(cb));
37  };
38 }
39 
40 // libc++ as shipped with Xcode does not have deduction guides for lambda -> std::function
41 // Help it along a bit.
43 template<typename Ret, typename F, typename ... Args>
44 constexpr std::function<Ret(Args...)> get_func_type(Ret(F::*)(Args...) const);
45 
53 template<typename F>
54 auto make_invoker(event_loop& loop, F && f)
55 {
56  return do_make_invoker(loop, decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
57 }
58 template<typename F>
59 auto make_invoker(event_handler& h, F && f)
60 {
61  return do_make_invoker(h.event_loop_, decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
62 }
63 
64 
65 typedef std::function<void(std::function<void()>)> invoker_factory;
66 
73 invoker_factory FZ_PUBLIC_SYMBOL get_invoker_factory(event_loop& loop);
74 
76 template<typename... Args>
77 std::function<void(Args...)> do_make_invoker(invoker_factory const& inv, std::function<void(Args...)> && f)
78 {
79  return [inv, f](Args&&... args) mutable {
80  auto cb = [f, targs = std::make_tuple(std::forward<Args>(args)...)] {
81  std::apply(f, targs);
82  };
83  inv(cb);
84  };
85 }
86 
94 template<typename F>
95 auto make_invoker(invoker_factory const& inv, F && f)
96 {
97  return do_make_invoker(inv, decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
98 }
99 
100 }
101 
102 #endif
A threaded event loop that supports sending events and timers.
Definition: event_loop.hpp:34
Declares the event_handler class.
The namespace used by libfilezilla.
Definition: apply.hpp:17
auto apply(Obj &&obj, F &&f, Tuple &&args) -> decltype(apply_(std::forward< Obj >(obj), std::forward< F >(f), std::forward< Tuple >(args), Seq()))
Apply tuple to pointer to member.
Definition: apply.hpp:48
invoker_factory get_invoker_factory(event_loop &loop)
Creates an invoker factory.
auto make_invoker(event_loop &loop, F &&f)
Wraps the passed function, so that it is always invoked in the context of the loop.
Definition: invoker.hpp:54