source: filezilla/trunk/fuentes/src/include/event_loop.h @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 2.7 KB
Line 
1#ifndef FILEZILLA_ENGINE_EVENT_LOOP_HEADER
2#define FILEZILLA_ENGINE_EVENT_LOOP_HEADER
3
4#include "apply.h"
5#include "event.h"
6#include "mutex.h"
7#include "timeex.h"
8
9#include <deque>
10#include <functional>
11#include <vector>
12
13class CEventHandler;
14struct timer_data final
15{
16        CEventHandler* handler_{};
17        timer_id id_{};
18        CMonotonicClock deadline_;
19        duration interval_{};
20};
21
22// Timers have precedence over queued events. Too many or too frequent timers can starve processing queued events.
23// If the deadline of multiple timers have expired, they get processed in an unspecified order
24class CEventLoop final : private wxThread
25{
26public:
27        typedef std::deque<std::pair<CEventHandler*, CEventBase*>> Events;
28
29        // Spawns a thread
30        CEventLoop();
31        virtual ~CEventLoop();
32
33        CEventLoop(CEventLoop const&) = delete;
34        CEventLoop& operator=(CEventLoop const&) = delete;
35
36        // Puts all queued events through the filter function.
37        // The filter function can freely change the passed events.
38        // If the filter function returns true, the corresponding event
39        // gets removed.
40        void FilterEvents(std::function<bool (Events::value_type&)> const& filter);
41
42protected:
43        friend class CEventHandler;
44
45        void RemoveHandler(CEventHandler* handler);
46
47        timer_id AddTimer(CEventHandler* handler, duration const& interval, bool one_shot);
48        void StopTimer(timer_id id);
49
50        void SendEvent(CEventHandler* handler, CEventBase* evt);
51
52        // Process timers. Returns true if a timer has been triggered
53        bool ProcessTimers(scoped_lock & l, CMonotonicClock const& now);
54
55        virtual wxThread::ExitCode Entry();
56
57        typedef std::vector<timer_data> Timers;
58
59        Events pending_events_;
60        Timers timers_;
61
62        mutex sync_;
63        condition cond_;
64
65        bool quit_{};
66
67        CEventHandler * active_handler_{};
68
69        // Process the next (if any) event. Returns true if an event has been processed
70        bool ProcessEvent(scoped_lock & l);
71
72        CMonotonicClock deadline_;
73
74        timer_id next_timer_id_{};
75};
76
77
78// Dispatch for CEvent<> based events. See event_handler.h for usage example
79template<typename T, typename H, typename F>
80bool Dispatch(CEventBase const& ev, F&& f)
81{
82        bool const same = same_type<T>(ev);
83        if (same) {
84                T const* e = static_cast<T const*>(&ev);
85                apply(std::forward<F>(f), e->v_);
86        }
87        return same;
88}
89
90
91template<typename T, typename H, typename F>
92bool Dispatch(CEventBase const& ev, H* h, F&& f)
93{
94        bool const same = same_type<T>(ev);
95        if (same) {
96                T const* e = static_cast<T const*>(&ev);
97                apply(h, std::forward<F>(f), e->v_);
98        }
99        return same;
100}
101
102template<typename T, typename ... Ts, typename H, typename F, typename ... Fs>
103bool Dispatch(CEventBase const& ev, H* h, F&& f, Fs&& ... fs)
104{
105        if (Dispatch<T>(ev, h, std::forward<F>(f))) {
106                return true;
107        }
108
109        return Dispatch<Ts...>(ev, h, std::forward<Fs>(fs)...);
110}
111
112#endif
Note: See TracBrowser for help on using the repository browser.