Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
application.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 APPLICATION_H
20 #define APPLICATION_H
21 
22 #include <cstdint>
23 #include <memory>
24 #include <list>
25 
26 #include "arg_parser.h"
27 #include "keycodes.h"
28 #include "utils/deprecated.h"
29 #include "types.h"
30 #include "utils/unicode.h"
31 #include "scenes/scene_manager.h"
32 #include "generic/property.h"
33 #include "generic/data_carrier.h"
34 #include "scenes/scene_manager.h"
35 #include "screen.h"
36 #include "logging.h"
37 #include "path.h"
38 #include "loader.h"
39 #include "nodes/stage_node_pool.h"
40 
41 
42 #define DEFAULT_LANGUAGE_CODE "en-us"
43 
44 
45 namespace smlt {
46 
47 class Window;
48 class Stage;
49 class SharedAssetManager;
50 class TimeKeeper;
51 class StatsRecorder;
52 class VirtualFileSystem;
53 class SoundDriver;
54 
55 class BackgroundLoadException : public std::runtime_error {
56 public:
58  std::runtime_error("An error occurred while running a background task") {}
59 };
60 
61 struct AppConfig {
62  unicode title = _u("Simulant Application");
63  uint32_t width = 0;
64  uint32_t height = 0;
65  uint32_t bpp = 0;
66  bool fullscreen = true;
67 
68  /* This is the frame limit; set to 0 to disable */
69  uint16_t target_frame_rate = 60;
70 
71  /* This is how many fixed updates should happen per second */
72  uint16_t target_fixed_step_rate = 60;
73 
74  /* Whether to enable vsync or not */
75  bool enable_vsync = false;
76 
77  // Additional paths for asset loading
78  std::vector<Path> search_paths;
79 
80  // Program arguments
81  std::vector<unicode> arguments;
82 
83  smlt::LogLevel log_level = smlt::LOG_LEVEL_WARN;
84 
85  /* If set to true, the mouse cursor will not be hidden by default */
86  bool show_cursor = false;
87 
88  std::string source_language_code = DEFAULT_LANGUAGE_CODE;
89 
90  struct General {
91  uint32_t stage_node_pool_size = 64;
92  } general;
93 
94  struct UI {
97  std::vector<Path> font_directories = {
98 #ifdef __DREAMCAST__
99  "/cd/simulant/fonts/Orbitron",
100  "/cd/assets/simulant/fonts/Orbitron"
101  "/pc/simulant/fonts/Orbitron",
102  "/pc/assets/simulant/fonts/Orbitron"
103 #else
104  "simulant/fonts/Orbitron",
105  "assets/simulant/fonts/Orbitron"
106 #endif
107  };
108 
110  std::string font_family = "Orbitron";
111 
114  uint16_t font_size = 16;
115  } ui;
116 
117  struct Desktop {
118  bool enable_virtual_screen = false;
119  ScreenFormat virtual_screen_format = SCREEN_FORMAT_G1;
120  uint16_t virtual_screen_width = 48;
121  uint16_t virtual_screen_height = 32;
122  uint16_t virtual_screen_integer_scale = 1;
123  } desktop;
124 
125  struct Development {
126  /* If set to true, profiling mode will be enabled
127  * regardless of the SIMULANT_PROFILE environment variable.
128  *
129  * When profiling mode is enabled, the frame limit is uncapped
130  * and on some platforms a profiler is enabled.
131  */
132 #ifdef SIMULANT_PROFILE
133  bool force_profiling = true;
134 #else
135  bool force_profiling = false;
136 #endif
137  /*
138  * Set to gl1x or gl2x to force that renderer if available
139  FIXME: Not yet working
140  */
141  std::string force_renderer = "";
142  std::string force_sound_driver = "";
143 
144  /* If not empty, logging entries will be written to this
145  * file as well as stdout */
146  std::string log_file = "";
147  } development;
148 };
149 
150 class Loader;
151 class LoaderType;
152 
153 typedef std::shared_ptr<Loader> LoaderPtr;
154 typedef std::shared_ptr<LoaderType> LoaderTypePtr;
155 
156 typedef sig::signal<void ()> FrameStartedSignal;
157 typedef sig::signal<void ()> FrameFinishedSignal;
158 typedef sig::signal<void ()> PreSwapSignal;
159 typedef sig::signal<void ()> PostCoroutinesSignal;
160 
161 typedef sig::signal<void (float)> FixedUpdateSignal;
162 typedef sig::signal<void (float)> UpdateSignal;
163 typedef sig::signal<void (float)> LateUpdateSignal;
164 typedef sig::signal<void ()> PostLateUpdateSignal;
165 typedef sig::signal<void ()> ShutdownSignal;
166 
167 class Application {
168  friend class Window;
169 
170  DEFINE_SIGNAL(PreSwapSignal, signal_pre_swap);
171  DEFINE_SIGNAL(PostCoroutinesSignal, signal_post_coroutines);
172  DEFINE_SIGNAL(FixedUpdateSignal, signal_fixed_update);
173  DEFINE_SIGNAL(UpdateSignal, signal_update);
174  DEFINE_SIGNAL(LateUpdateSignal, signal_late_update);
175  DEFINE_SIGNAL(PostLateUpdateSignal, signal_post_late_update);
176  DEFINE_SIGNAL(ShutdownSignal, signal_shutdown);
177 
178  DEFINE_SIGNAL(FrameStartedSignal, signal_frame_started);
179  DEFINE_SIGNAL(FrameFinishedSignal, signal_frame_finished);
180 public:
181  Application(const AppConfig& config);
182  virtual ~Application();
183 
184  //Create the window, start do_initialization in a thread, show the loading scene
185  //when thread completes, hide the loading scene and run the main loop
186  int32_t run();
187  int32_t run(int argc, char* argv[]);
188 
189  bool initialized() const { return initialized_; }
190 
193  ProcessID process_id() const;
194 
196  smlt::thread::ThreadID thread_id() const;
197 
201  int64_t ram_usage_in_bytes() const;
202 
206  uint32_t stage_node_pool_capacity() const;
207  uint32_t stage_node_pool_capacity_in_bytes() const;
208 
211  bool run_frame();
212 
215  void run_update(float dt);
216 
218  void run_fixed_updates();
219 
222  void request_frame_time(float ms);
223 
224  /* Coroutines */
225  void start_coroutine(std::function<void ()> func);
226  void update_coroutines();
227  void stop_all_coroutines();
228 
230  void stop_running();
231 
233  bool is_shutting_down() const;
234 
235  void shutdown();
236 
237  /* Loader things */
238  LoaderPtr loader_for(const Path &filename, LoaderHint hint=LOADER_HINT_NONE);
239  LoaderPtr loader_for(const std::string& loader_name, const Path& filename);
240  LoaderTypePtr loader_type(const std::string& loader_name) const;
241 
242  void register_loader(LoaderTypePtr loader_type);
243 
249  bool activate_language(const std::string& language_code);
250 
252  std::string active_language() const {
253  return active_language_;
254  }
255 
262  unicode translated_text(const unicode& source_text) {
263  auto it = active_translations_.find(source_text);
264  if(it == active_translations_.end()) {
265  return source_text;
266  } else {
267  return it->second;
268  }
269  }
270 
271 protected:
272  bool _call_init();
273 
274 private:
275  friend void cr_run_main(std::function<void ()> func);
276  std::function<void ()> cr_synced_function_;
277 
278  void run_coroutines_and_late_update();
279 
280  thread::ThreadID main_thread_id_;
281  bool has_shutdown_ = false;
282 
283  std::shared_ptr<Window> window_;
284  std::shared_ptr<SceneManager> scene_manager_;
285  std::shared_ptr<SharedAssetManager> asset_manager_;
286  std::shared_ptr<TimeKeeper> time_keeper_;
287  std::shared_ptr<StatsRecorder> stats_;
288  std::shared_ptr<VirtualFileSystem> vfs_;
289  std::shared_ptr<SoundDriver> sound_driver_;
290 
291  std::vector<LoaderTypePtr> loaders_;
292 
293  bool initialized_ = false;
294  bool is_running_ = true;
295 
296  float frame_counter_time_ = 0.0f;
297  int32_t frame_counter_frames_ = 0;
298  float frame_time_in_milliseconds_ = 0.0f;
299 
300  void _call_fixed_update(float dt) {
301  fixed_update(dt);
302  }
303 
304  void _call_clean_up() {
305  clean_up();
306  }
307 
308  void _call_update(float dt) {
309  update(dt);
310  }
311 
312  void _call_late_update(float dt) {
313  late_update(dt);
314  }
315 
316  virtual bool init() = 0;
317  virtual void fixed_update(float dt) {
318  _S_UNUSED(dt);
319  }
320 
321  virtual void update(float dt) {
322  _S_UNUSED(dt);
323  }
324 
325  virtual void late_update(float dt) {
326  _S_UNUSED(dt);
327  }
328 
329  virtual void clean_up() {}
330 
331  generic::DataCarrier data_carrier_;
332 
333  AppConfig config_;
334  StageNodePool* node_pool_ = nullptr;
335 
336  void construct_window(const AppConfig& config);
337 
338  ArgParser args_;
339 
340  void await_frame_time();
341  uint64_t last_frame_time_us_ = 0;
342  float requested_frame_time_ms_ = 0;
343 
344  std::list<cort::CoroutineID> coroutines_;
345  void preload_default_font();
346 
347  std::string active_language_ = DEFAULT_LANGUAGE_CODE;
348  std::map<unicode, unicode> active_translations_;
349 public:
350  S_DEFINE_PROPERTY(window, &Application::window_);
351  S_DEFINE_PROPERTY(data, &Application::data_carrier_);
352  S_DEFINE_PROPERTY(scenes, &Application::scene_manager_);
353  S_DEFINE_PROPERTY(args, &Application::args_);
354  S_DEFINE_PROPERTY(config, &Application::config_);
355  S_DEFINE_PROPERTY(stage_node_pool, &Application::node_pool_);
356  S_DEFINE_PROPERTY(shared_assets, &Application::asset_manager_);
357  S_DEFINE_PROPERTY(time_keeper, &Application::time_keeper_);
358  S_DEFINE_PROPERTY(stats, &Application::stats_);
359  S_DEFINE_PROPERTY(vfs, &Application::vfs_);
360  S_DEFINE_PROPERTY(sound_driver, &Application::sound_driver_);
361 private:
362  friend Application* get_app();
363  static Application* global_app;
364 
365  mutable thread::Mutex running_lock_;
366 
367  std::vector<std::string> generate_potential_codes(const std::string& language_code);
368  bool load_arb_file(const smlt::Path& filename);
369 };
370 
371 Application* get_app();
372 
373 }
374 
375 #define _T(text) \
376  smlt::get_app()->translated_text((text))
377 
378 #endif // APPLICATION_H
smlt::Application::run_update
void run_update(float dt)
Definition: application.cpp:404
smlt::AppConfig::Desktop
Definition: application.h:117
smlt::Application::process_id
ProcessID process_id() const
Definition: application.cpp:576
smlt::Application
Definition: application.h:167
smlt::Application::stop_running
void stop_running()
Definition: application.cpp:636
smlt
Definition: animation.cpp:25
smlt::LoaderType
Definition: loader.h:111
smlt::Window
Definition: window.h:65
smlt::Loader
Definition: loader.h:66
smlt::AppConfig::UI
Definition: application.h:94
smlt::BackgroundLoadException
Definition: application.h:55
smlt::Application::active_language
std::string active_language() const
Definition: application.h:252
smlt::Application::translated_text
unicode translated_text(const unicode &source_text)
Definition: application.h:262
smlt::AppConfig::UI::font_family
std::string font_family
Definition: application.h:110
smlt::Application::run_fixed_updates
void run_fixed_updates()
Definition: application.cpp:427
smlt::Application::thread_id
smlt::thread::ThreadID thread_id() const
Definition: application.cpp:586
smlt::Application::stage_node_pool_capacity
uint32_t stage_node_pool_capacity() const
Definition: application.cpp:603
smlt::AppConfig::UI::font_size
uint16_t font_size
Definition: application.h:114
smlt::Path
Definition: path.h:7
smlt::AppConfig
Definition: application.h:61
unicode
Definition: unicode.h:35
smlt::AppConfig::General
Definition: application.h:90
smlt::Application::ram_usage_in_bytes
int64_t ram_usage_in_bytes() const
Definition: application.cpp:590
smlt::Application::request_frame_time
void request_frame_time(float ms)
Definition: application.cpp:387
smlt::Application::run_frame
bool run_frame()
Definition: application.cpp:442
smlt::AppConfig::UI::font_directories
std::vector< Path > font_directories
Definition: application.h:97
smlt::sig::signal
Definition: signal.h:319
smlt::Application::is_shutting_down
bool is_shutting_down() const
Definition: application.cpp:641
smlt::Application::activate_language
bool activate_language(const std::string &language_code)
Definition: application.cpp:782
smlt::AppConfig::Development
Definition: application.h:125