The Battle for Wesnoth  1.19.8+dev
events.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include <SDL2/SDL_events.h>
19 #include <vector>
20 #include <list>
21 #include <functional>
22 
23 //our user-defined double-click event type
24 #define DOUBLE_CLICK_EVENT SDL_USEREVENT
25 #define TIMER_EVENT (SDL_USEREVENT + 1)
26 #define HOVER_REMOVE_POPUP_EVENT (SDL_USEREVENT + 2)
27 #define DRAW_EVENT (SDL_USEREVENT + 3)
28 #define CLOSE_WINDOW_EVENT (SDL_USEREVENT + 4)
29 #define SHOW_HELPTIP_EVENT (SDL_USEREVENT + 5)
30 #define INVOKE_FUNCTION_EVENT (SDL_USEREVENT + 6)
31 
32 namespace events
33 {
34 
35 class sdl_handler;
36 
37 typedef std::list<sdl_handler*> handler_list;
38 
39 class context
40 {
41 public:
42  context() :
43  handlers(),
46  {
47  }
48 
49  ~context();
50 
51  context(const context&) = delete;
52 
53  void add_handler(sdl_handler* ptr);
54  /** Returns true if @a ptr is found in either the handlers or staging_handlers lists */
55  bool has_handler(const sdl_handler* ptr) const;
56  bool remove_handler(sdl_handler* ptr);
57  void cycle_focus();
58  void set_focus(const sdl_handler* ptr);
59  void add_staging_handlers();
60 
63  std::vector<sdl_handler*> staging_handlers;
64 };
65 
66 //any classes that derive from this class will automatically
67 //receive sdl events through the handle function for their lifetime,
68 //while the event context they were created in is active.
69 //
70 //NOTE: an event_context object must be initialized before a handler object
71 //can be initialized, and the event_context must be destroyed after
72 //the handler is destroyed.
74 {
75 friend class context;
76 public:
77  virtual void handle_event(const SDL_Event& event) = 0;
78  virtual void handle_window_event(const SDL_Event&) {};
79  virtual void process_event() {}
80 
81  virtual bool requires_event_focus(const SDL_Event * = nullptr) const { return false; }
82 
83  virtual void process_tooltip_string(int /*mousex*/, int /*mousey*/) {}
84 
85  virtual void join(); /*joins the current event context*/
86  virtual void join(context &c); /*joins the specified event context*/
87  virtual void join_same(sdl_handler* parent); /*joins the same event context as the parent is already associated with */
88  virtual void leave(); /*leave the event context*/
89 
90  virtual void join_global(); /*join the global event context*/
91  virtual void leave_global(); /*leave the global event context*/
92 
93  virtual bool has_joined() { return has_joined_;}
94  virtual bool has_joined_global() { return has_joined_global_;}
95 
96  /**
97  * Moving would require two instances' context membership to be handled,
98  * it's simpler to delete these and require the two instances to be
99  * separately constructed / destructed.
100  */
102  sdl_handler(sdl_handler &&) = delete;
103 
104 protected:
105  sdl_handler(const bool auto_join=true);
106  sdl_handler(const sdl_handler &);
108  virtual ~sdl_handler();
109  virtual std::vector<sdl_handler*> handler_members()
110  {
111  return std::vector<sdl_handler*>();
112  }
113 
114 private:
117 };
118 
119 void focus_handler(const sdl_handler* ptr);
120 
121 bool has_focus(const sdl_handler* ptr, const SDL_Event* event);
122 
123 void set_main_thread();
124 
125 // whether the currently executing thread is the main thread.
126 bool is_in_main_thread();
127 
128 void call_in_main_thread(const std::function<void (void)>& f);
129 
130 //event_context objects control the handler objects that SDL events are sent
131 //to. When an event_context is created, it will become the current event context.
132 //event_context objects MUST be created in LIFO ordering in relation to each other,
133 //and in relation to handler objects. That is, all event_context objects should be
134 //created as automatic/stack variables.
135 //
136 //handler objects need not be created as automatic variables (e.g. you could put
137 //them in a vector) however you must guarantee that handler objects are destroyed
138 //before their context is destroyed
140 {
141  event_context();
142  ~event_context();
143 };
144 
145 /** Process all events currently in the queue. */
146 void pump();
147 
148 /** Trigger a draw cycle. */
149 void draw();
150 
151 /** pump() then immediately draw() */
152 inline void pump_and_draw() { pump(); draw(); }
153 // TODO: draw_manager - should this also raise_process_event? Some things do some don't
154 
156 //pump_monitors receive notification after an events::pump() occurs
157 public:
158  pump_monitor();
159  virtual ~pump_monitor();
160  virtual void process() = 0;
161 };
162 
163 void raise_process_event();
164 void raise_resize_event();
165 /**
166  * Triggered by mouse-motion, sends the cursor position to all handlers to
167  * check whether a tooltip should be shown.
168  */
169 void process_tooltip_strings(int mousex, int mousey);
170 
171 
172 /**
173  * Is the event an input event?
174  *
175  * @returns Whether or not the event is an input event.
176  */
177 bool is_input(const SDL_Event& event);
178 
179 /** Discards all input events. */
180 void discard_input();
181 
182 }
183 
184 typedef std::vector<events::sdl_handler*> sdl_handler_vector;
void set_focus(const sdl_handler *ptr)
Definition: events.cpp:186
bool has_handler(const sdl_handler *ptr) const
Returns true if ptr is found in either the handlers or staging_handlers lists.
Definition: events.cpp:98
void cycle_focus()
Definition: events.cpp:153
handler_list::iterator focused_handler
Definition: events.hpp:62
std::vector< sdl_handler * > staging_handlers
Definition: events.hpp:63
handler_list handlers
Definition: events.hpp:61
context(const context &)=delete
void add_handler(sdl_handler *ptr)
Definition: events.cpp:89
bool remove_handler(sdl_handler *ptr)
Definition: events.cpp:106
void add_staging_handlers()
Definition: events.cpp:194
virtual ~pump_monitor()
Definition: events.cpp:227
virtual void process()=0
virtual bool requires_event_focus(const SDL_Event *=nullptr) const
Definition: events.hpp:81
virtual void process_tooltip_string(int, int)
Definition: events.hpp:83
virtual void handle_window_event(const SDL_Event &)
Definition: events.hpp:78
virtual bool has_joined_global()
Definition: events.hpp:94
virtual bool has_joined()
Definition: events.hpp:93
virtual std::vector< sdl_handler * > handler_members()
Definition: events.hpp:109
virtual void join()
Definition: events.cpp:308
virtual void leave()
Definition: events.cpp:353
virtual void handle_event(const SDL_Event &event)=0
virtual void process_event()
Definition: events.hpp:79
virtual void join_global()
Definition: events.cpp:374
virtual void join_same(sdl_handler *parent)
Definition: events.cpp:337
virtual void leave_global()
Definition: events.cpp:394
sdl_handler & operator=(sdl_handler &&)=delete
Moving would require two instances' context membership to be handled, it's simpler to delete these an...
virtual ~sdl_handler()
Definition: events.cpp:297
sdl_handler(sdl_handler &&)=delete
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:184
Handling of system events.
void raise_resize_event()
Definition: events.cpp:741
bool has_focus(const sdl_handler *hand, const SDL_Event *event)
Definition: events.cpp:412
void discard_input()
Discards all input events.
Definition: events.cpp:772
void draw()
Trigger a draw cycle.
Definition: events.cpp:725
bool is_input(const SDL_Event &event)
Is the event an input event?
Definition: events.cpp:767
void set_main_thread()
Definition: events.cpp:471
void call_in_main_thread(const std::function< void(void)> &f)
Definition: events.cpp:777
void raise_process_event()
Definition: events.cpp:730
void process_tooltip_strings(int mousex, int mousey)
Triggered by mouse-motion, sends the cursor position to all handlers to check whether a tooltip shoul...
Definition: events.cpp:754
std::list< sdl_handler * > handler_list
Definition: events.hpp:35
bool is_in_main_thread()
Definition: events.cpp:478
void pump_and_draw()
pump() then immediately draw()
Definition: events.hpp:152
void pump()
Process all events currently in the queue.
Definition: events.cpp:483
void focus_handler(const sdl_handler *ptr)
Definition: events.cpp:405
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
mock_char c
#define f