1#[allow(ambiguous_glob_reexports)]
2pub use rscad_core::*;
3#[cfg(feature = "export")]
4pub use rscad_openscad::export::ExportObject;
5#[cfg(feature = "import")]
6pub use rscad_openscad::import::import;
7
8use bevy::prelude::*;
9use rscad_engine::platform::{Platform, PlatformInit, PlatformWatcher, PlatformWindow};
10use tracing_subscriber::{Layer, layer::SubscriberExt, util::SubscriberInitExt};
11
12#[cfg(all(feature = "leptos", target_arch = "wasm32"))]
15pub mod web_html;
16
17#[cfg(not(target_arch = "wasm32"))]
20fn fmt_layer<S>() -> impl Layer<S>
21where
22 S: tracing::Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
23{
24 tracing_subscriber::fmt::layer().with_filter({
25 let default_directive = "info".parse().expect("BUG: invalid default directive");
26 let builder = tracing_subscriber::filter::EnvFilter::builder()
27 .with_default_directive(default_directive);
28
29 if std::env::var("RSCAD_LOG").is_ok() {
31 builder
32 .with_env_var("RSCAD_LOG")
33 .from_env()
34 .unwrap_or_default()
35 } else {
36 builder
37 .with_env_var("RUST_LOG")
38 .from_env()
39 .unwrap_or_default()
40 }
41 })
42}
43
44#[cfg(target_arch = "wasm32")]
49fn wasm_log_filter() -> tracing_subscriber::EnvFilter {
50 tracing_subscriber::EnvFilter::new("info,wgpu=warn,wgpu_core=warn,wgpu_hal=warn,naga=warn")
51}
52
53#[cfg(target_arch = "wasm32")]
59#[wasm_bindgen::prelude::wasm_bindgen(start)]
60fn wasm_main() {
61 #[cfg(feature = "leptos")]
62 web_html::main();
63 #[cfg(all(feature = "gui", not(feature = "leptos")))]
64 main();
65}
66
67#[bevy_main]
68pub fn main() {
69 #[cfg(target_arch = "wasm32")]
72 console_error_panic_hook::set_once();
73
74 #[cfg(feature = "gui")]
78 let log_rx = {
79 let (log_tx, log_rx) = flume::unbounded();
80 let panel = rscad_gui::UiLogLayer { tx: log_tx };
81
82 #[cfg(not(target_arch = "wasm32"))]
84 tracing_subscriber::registry()
85 .with(panel.with_filter(tracing_subscriber::filter::LevelFilter::INFO))
86 .with(fmt_layer())
87 .init();
88 #[cfg(target_arch = "wasm32")]
91 tracing_subscriber::registry()
92 .with(panel.with_filter(wasm_log_filter()))
93 .with(tracing_wasm::WASMLayer::new(Default::default()).with_filter(wasm_log_filter()))
94 .init();
95
96 log_rx
97 };
98 #[cfg(all(not(feature = "gui"), not(target_arch = "wasm32")))]
99 tracing_subscriber::registry().with(fmt_layer()).init();
100 #[cfg(all(not(feature = "gui"), target_arch = "wasm32"))]
101 tracing_subscriber::registry()
102 .with(tracing_wasm::WASMLayer::new(Default::default()).with_filter(wasm_log_filter()))
103 .init();
104
105 let platform = rscad_engine::platform::current_platform();
106 tracing::info!("Platform: {}", platform.name());
107
108 let cli_open = std::env::args().nth(1).is_some();
112 let initial = platform.load_initial_model();
113 let watcher = cli_open
114 .then(|| platform.create_watcher(&initial.model_state.source))
115 .flatten();
116
117 let mut app = App::new();
119 if let Some(watcher) = watcher {
120 app.insert_resource(watcher);
121 }
122 app.insert_resource(platform.winit_settings())
123 .add_plugins(
124 DefaultPlugins
125 .build()
126 .disable::<bevy::log::LogPlugin>()
127 .set(platform.window_plugin()),
128 )
129 .insert_resource(rscad_engine::platform::PlatformRes(platform))
132 .add_plugins(rscad_engine::EnginePlugins {
133 init: rscad_engine::ModelInit {
134 source: initial.model_state.source,
135 scene: initial.model_state.scene,
136 pre_built_mesh: initial.pre_built_mesh,
137 },
138 spawn_camera: cfg!(not(feature = "gui")),
141 });
142
143 #[cfg(feature = "gui")]
145 {
146 app.insert_resource(rscad_gui::ProjectsOpen(!cli_open));
148 app.add_plugins(rscad_gui::GuiPlugin);
149 app.insert_resource(rscad_gui::Logs {
150 rx: log_rx,
151 entries: Vec::new(),
152 rendered_count: 0,
153 });
154 }
155
156 app.run();
157}