1use clap::Parser;
2use utils::args::Args;
3
4#[cfg(target_os = "android")]
6const TAG: &str = "CatgirlEngine";
7
8pub(super) fn process_args() {
10 #[cfg(feature = "client")]
12 client::game::store_resources_path(get_args().resources);
13
14 #[cfg(all(feature = "client", target_os = "linux"))]
16 if get_args().uninstall_desktop_files {
17 trace!("Uninstalling desktop files...");
18 let _ = client::uninstall_desktop_files();
19 }
20
21 #[cfg(all(feature = "client", target_os = "linux"))]
23 if get_args().install_desktop_files {
24 trace!("Installing desktop files...");
25 let _ = client::install_desktop_files();
26 }
27
28 #[cfg(not(target_family = "wasm"))]
29 if get_args().print_environment_variables {
30 trace!("Printing environment variables...");
31 utils::environment::print_environment_vars();
32 }
33
34 #[cfg(feature = "client")]
35 trace!("Resources Path: {:?}", client::game::get_resources_path());
36}
37
38#[must_use]
44pub(super) fn get_args() -> Args {
45 if utils::args::get_args().is_some() {
46 utils::args::get_args().unwrap()
47 } else {
48 Args::parse()
49 }
50}
51
52#[cfg(feature = "logging-subscriber")]
54pub(super) fn setup_logger() {
55 if cfg!(target_os = "android") {
56 #[cfg(target_os = "android")]
60 android_logger::init_once(
61 android_logger::Config::default()
62 .with_max_level(tracing::log::LevelFilter::Trace)
63 .with_tag(TAG)
64 .with_filter(
65 android_logger::FilterBuilder::new()
66 .parse("main=trace,catgirl_engine=trace")
67 .build(),
68 ),
69 );
70 } else if cfg!(target_family = "wasm") {
71 #[cfg(target_family = "wasm")]
73 if let Err(_error) = fern::Dispatch::new()
74 .level(tracing::log::LevelFilter::Off)
75 .level_for("main", tracing::log::LevelFilter::Trace)
76 .level_for("catgirl_engine", tracing::log::LevelFilter::Trace)
77 .level_for("catgirl_engine_client", tracing::log::LevelFilter::Trace)
78 .level_for("catgirl_engine_server", tracing::log::LevelFilter::Trace)
79 .level_for("catgirl_engine_utils", tracing::log::LevelFilter::Trace)
80 .chain(fern::Output::call(console_log::log))
81 .apply()
82 {
83 warn!("Failed to initialize console logger...")
84 }
85 } else {
86 let mut builder = pretty_env_logger::formatted_builder();
88 if let Ok(s) = std::env::var("RUST_LOG") {
89 builder.parse_filters(&s);
91 } else {
92 builder
94 .default_format()
95 .filter(Some("main"), tracing::log::LevelFilter::Info)
96 .filter(Some("catgirl_engine"), tracing::log::LevelFilter::Info)
97 .filter(
98 Some("catgirl_engine_client"),
99 tracing::log::LevelFilter::Info,
100 )
101 .filter(
102 Some("catgirl_engine_server"),
103 tracing::log::LevelFilter::Info,
104 )
105 .filter(
106 Some("catgirl_engine_utils"),
107 tracing::log::LevelFilter::Info,
108 );
109 }
110
111 builder.try_init().unwrap();
112 }
113}
114
115fn set_panic_hook() {
117 std::panic::set_hook(Box::new(|info| {
118 let location_string = if let Some(location) = info.location() {
119 format!(
120 " in file {} at line:column {}:{}",
121 location.file(),
122 location.line(),
123 location.column()
124 )
125 } else {
126 String::new()
127 };
128
129 if let Some(string) = info.payload().downcast_ref::<String>() {
130 error!("Caught panic{location_string}: {string}");
131 } else {
132 error!("Caught panic{location_string}");
133 }
134
135 utils::exit::set_exit();
136 }));
137}
138
139pub(super) fn start() -> Result<(), String> {
161 info!("Starting Game...");
162
163 debug!("Setting panic hook...");
164 set_panic_hook();
165
166 #[cfg(any(target_family = "unix", target_family = "windows"))]
168 {
169 debug!("Setting SIGINT hook...");
170 ctrlc::set_handler(move || {
171 debug!("SIGINT (Ctrl+C) Was Called! Stopping...");
172 utils::exit::set_exit();
173
174 #[cfg(feature = "client")]
175 if !get_args().server {
176 #[cfg(not(target_family = "wasm"))]
177 let _ = client::game::advance_event_loop();
178 }
179 })
180 .expect("Could not create Interrupt Handler (e.g. Ctrl+C)...");
181 }
182
183 debug!("Starting main loop...");
184
185 #[cfg(feature = "server")]
186 if cfg!(not(feature = "client")) || get_args().server {
187 return server::game::game_loop();
189 }
190
191 #[cfg(feature = "client")]
193 return client::game::game_loop();
194
195 #[cfg(not(feature = "client"))]
197 Err("Neither the client nor server features were configured at build time...".to_string())
198}