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
10namespace fz {
11
13struct invoker_event_type{};
14
16typedef simple_event<invoker_event_type, std::function<void()>> invoker_event;
17
19class FZ_PUBLIC_SYMBOL thread_invoker final : public event_handler
20{
21public:
22 thread_invoker(event_loop& loop);
23 virtual ~thread_invoker();
24
25 virtual void operator()(event_base const& ev) override;
26};
27
29template<typename... Args>
30std::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.
43template<typename Ret, typename F, typename ... Args>
44constexpr std::function<Ret(Args...)> get_func_type(Ret(F::*)(Args...) const);
45
53template<typename F>
54auto 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}
58template<typename F>
59auto 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
65typedef std::function<void(std::function<void()>)> invoker_factory;
66
73invoker_factory FZ_PUBLIC_SYMBOL get_invoker_factory(event_loop& loop);
74
76template<typename... Args>
77std::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
94template<typename F>
95auto 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