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