Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
window.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef SIMULANT_WINDOW_BASE_H
20 #define SIMULANT_WINDOW_BASE_H
21 
22 #include <memory>
23 
24 #include "logging.h"
25 
26 #include "generic/property.h"
27 #include "generic/object_manager.h"
28 #include "generic/data_carrier.h"
29 
30 #include "input/input_state.h"
31 #include "types.h"
32 #include "loader.h"
33 #include "event_listener.h"
34 #include "stats_recorder.h"
35 #include "screen.h"
36 
37 namespace smlt {
38 
39 class AssetManager;
40 class InputManager;
41 
42 namespace ui {
43  class Interface;
44 }
45 
46 namespace scenes {
47  class Loading;
48 }
49 
50 class Application;
51 class InputState;
52 class Compositor;
53 class SceneImpl;
54 class Renderer;
55 class Panel;
56 class SoundDriver;
57 class StageNode;
58 
59 typedef sig::signal<void (std::string, Screen*)> ScreenAddedSignal;
60 typedef sig::signal<void (std::string, Screen*)> ScreenRemovedSignal;
61 
62 class Window :
63  public Loadable,
64  public RenderTarget,
65  public EventListenerManager {
66 
67  DEFINE_SIGNAL(ScreenAddedSignal, signal_screen_added);
68  DEFINE_SIGNAL(ScreenRemovedSignal, signal_screen_removed);
69 
70  friend class Screen; /* Screen needs to call render_screen */
71  friend class Application; /* ContextLock stuff */
72 public:
73  typedef std::shared_ptr<Window> ptr;
74 
75  template<typename T>
76  static std::shared_ptr<Window> create(Application* app) {
77  auto window = std::make_shared<T>();
78  window->set_application(app);
79  return window;
80  }
81 
82  virtual ~Window();
83 
84  virtual bool create_window(
85  uint16_t width,
86  uint16_t height,
87  uint8_t bpp,
88  bool fullscreen,
89  bool enable_vsync
90  );
91 
92  virtual void set_title(const std::string& title) = 0;
93  virtual void cursor_position(int32_t& mouse_x, int32_t& mouse_y) = 0;
94  virtual void show_cursor(bool cursor_shown=true) = 0;
95  virtual void lock_cursor(bool cursor_locked=true) = 0;
96 
97  virtual void check_events() = 0;
98  virtual void swap_buffers() = 0;
99 
100  uint16_t width() const override { return width_; }
101  uint16_t height() const override { return height_; }
102  bool is_fullscreen() const { return fullscreen_; }
103  bool vsync_enabled() const { return vsync_enabled_; }
104 
105  float aspect_ratio() const;
106  void set_logging_level(LogLevel level);
107 
108  void reset();
109 
110  Vec2 coordinate_from_normalized(Ratio rx, Ratio ry) {
111  return Vec2(
112  uint16_t(float(width()) * rx),
113  uint16_t(float(height()) * ry)
114  );
115  }
116 
117  void on_finger_down(
118  TouchPointID touch_id,
119  float normalized_x, float normalized_y, float pressure=1.0
120  );
121 
122  void on_finger_up(
123  TouchPointID touch_id,
124  float normalized_x, float normalized_y
125  );
126 
127  void on_finger_motion(
128  TouchPointID touch_id,
129  float normalized_x, float normalized_y,
130  float dx, float dy // Between -1.0 and +1.0
131  );
132 
133  void on_key_down(KeyboardCode code, ModifierKeyState modifiers);
134  void on_key_up(KeyboardCode code, ModifierKeyState modifiers);
135 
136  /* Return the number of screens connected */
137  std::size_t screen_count() const;
138 
139  /* Return a specific screen given its name */
140  Screen* screen(const std::string& name) const;
141 
142  void each_screen(std::function<void (std::string, Screen*)> callback);
143 
144  /* Private API for Window subclasses (public for testing)
145  don't call this directly
146  */
147  Screen* _create_screen(
148  const std::string& name,
149  uint16_t width,
150  uint16_t height,
151  ScreenFormat format,
152  uint16_t refresh_rate);
153 
154  void _destroy_screen(const std::string& name);
155 
156  /* Creates the window, but doesn't do any context initialisation */
157  virtual bool _init_window() = 0;
158 
159  /* Initialises any renderer context */
160  virtual bool _init_renderer(Renderer* renderer) = 0;
161 
162  bool initialize_assets_and_devices();
163  void _clean_up();
164 
165  /* Audio listener stuff */
166 
167  /* Returns the current audio listener, or NULL if there
168  * is no explicit audio listener set, and there are no current
169  * render pipelines.
170  *
171  * Behaviour is:
172  *
173  * - Explictly set listener
174  * - Or, First camera of first render pipeline
175  * - Or, NULL
176  */
177  StageNode* audio_listener();
178 
179  /* Sets a stage node explicitly as the audio listener */
180  void set_audio_listener(StageNode* node);
181 
182  /* Returns true if an explicit audio listener is being used */
183  bool has_explicit_audio_listener() const;
184 
186  bool has_context() const { return has_context_; }
187 
189  bool has_focus() const { return has_focus_; }
190 
193  void set_has_focus(bool v=true) {
194  has_focus_ = v;
195  }
196 
198  void create_panels();
199 
201  void destroy_panels();
202 protected:
203  std::shared_ptr<Renderer> renderer_;
204 
205  void set_vsync_enabled(bool vsync) {
206  vsync_enabled_ = vsync;
207  }
208 
209  void set_width(uint16_t width) {
210  width_ = width;
211  }
212 
213  void set_height(uint16_t height) {
214  height_ = height;
215  }
216 
217  void set_bpp(uint16_t bpp) {
218  bpp_ = bpp;
219  }
220 
221  void set_fullscreen(bool val) {
222  fullscreen_ = val;
223  }
224 
225  virtual void destroy_window() = 0;
226 
227  Window();
228 
229  void set_has_context(bool value=true);
230  thread::Mutex& context_lock() { return context_lock_; }
231 
232  void set_application(Application* app) { application_ = app; }
233 
234  void set_escape_to_quit(bool value=true) { escape_to_quit_ = value; }
235  bool escape_to_quit_enabled() const { return escape_to_quit_; }
236 public:
237  // Panels
238  void register_panel(uint8_t function_key, std::shared_ptr<Panel> panel);
239  void unregister_panel(uint8_t function_key);
240  void toggle_panel(uint8_t id);
241  void activate_panel(uint8_t id);
242  void deactivate_panel(uint8_t id);
243  bool panel_is_active(uint8_t id);
244 private:
245  Application* application_ = nullptr;
246 
247  void create_defaults();
248  virtual void initialize_input_controller(InputState& controller) = 0;
249 
250  bool can_attach_sound_by_id() const { return false; }
251 
252  bool initialized_;
253 
254  uint16_t width_ = 0;
255  uint16_t height_ = 0;
256  uint16_t bpp_ = 0;
257  bool fullscreen_ = false;
258  bool vsync_enabled_ = false;
259 
260  bool escape_to_quit_ = true;
261 
262  bool has_context_ = false;
263  bool has_focus_ = false;
264 
265  struct PanelEntry {
266  std::shared_ptr<Panel> panel;
267  };
268 
269  std::unordered_map<uint8_t, PanelEntry> panels_;
270 
271  /*
272  * Sometimes we need to destroy or recreate the GL context, if that happens while we are rendering in the
273  * main thread, then bad things happen. This lock exists so that we don't destroy the context while we are rendering.
274  * We obtain the lock before rendering, and release it after. Likewise we obtain the lock while destroying the context
275  * (we can use has_context to make sure we don't start rendering when there is no context) */
276  thread::Mutex context_lock_;
277 
278  void destroy() {}
279 
280  std::shared_ptr<smlt::Compositor> compositor_;
281  generic::DataCarrier data_carrier_;
282 
283  virtual std::shared_ptr<SoundDriver> create_sound_driver(const std::string& from_config) = 0;
284 
285  std::shared_ptr<InputState> input_state_;
286  std::shared_ptr<InputManager> input_manager_;
287 
288  std::unordered_map<std::string, Screen::ptr> screens_;
289 
290  /* This is called by Screens to render themselves to devices. Default behaviour is a no-op */
291  virtual void render_screen(Screen* screen, const uint8_t* data) {
292  _S_UNUSED(screen);
293  _S_UNUSED(data);
294  }
295 
296  /* To be overridden by subclasses if external screens need some kind of initialization/clean_up */
297  virtual bool initialize_screen(Screen* screen) {
298  _S_UNUSED(screen);
299  return true;
300  }
301 
302  virtual void shutdown_screen(Screen* screen) {
303  _S_UNUSED(screen);
304  }
305 
306  StageNode* audio_listener_ = nullptr;
307 protected:
308  InputState* _input_state() const { return input_state_.get(); }
309 public:
310  //Read only properties
311  S_DEFINE_PROPERTY(application, &Window::application_);
312  S_DEFINE_PROPERTY(renderer, &Window::renderer_);
313  S_DEFINE_PROPERTY(data, &Window::data_carrier_);
314  S_DEFINE_PROPERTY(input, &Window::input_manager_);
315  S_DEFINE_PROPERTY(input_state, &Window::input_state_);
316  S_DEFINE_PROPERTY(compositor, &Window::compositor_);
317 };
318 
319 }
320 
321 #endif
smlt::Application
Definition: application.h:167
smlt
Definition: animation.cpp:25
smlt::Window
Definition: window.h:65
smlt::Window::reset
void reset()
Window::reset.
Definition: window.cpp:295
smlt::Window::set_has_focus
void set_has_focus(bool v=true)
Definition: window.h:193
smlt::RenderTarget
Definition: interfaces.h:27
smlt::Window::has_context
bool has_context() const
Definition: window.h:186
smlt::Loadable
Definition: loadable.h:26
smlt::ModifierKeyState
Definition: event_listener.h:39
smlt::StageNode
Definition: stage_node.h:61
smlt::Screen
Definition: screen.h:20
smlt::Renderer
Definition: renderer.h:40
smlt::Window::create_panels
void create_panels()
Definition: window.cpp:273
smlt::Window::destroy_panels
void destroy_panels()
Definition: window.cpp:281
smlt::EventListenerManager
Definition: event_listener.h:103
smlt::Window::has_focus
bool has_focus() const
Definition: window.h:189
smlt::Vec2
Definition: vec2.h:13
smlt::sig::signal
Definition: signal.h:319