mod app;
mod app_blueprint;
mod app_state;
mod background_tasks;
pub mod env_vars;
#[cfg(not(target_arch = "wasm32"))]
mod loading;
mod saving;
mod screenshotter;
mod store_hub;
mod ui;
mod viewer_analytics;
pub mod blueprint;
pub(crate) use {
app_state::AppState,
ui::{memory_panel, selection_panel},
};
pub use app::{App, StartupOptions};
pub use store_hub::StoreBundle;
pub mod external {
pub use re_data_ui;
pub use {eframe, egui};
pub use {
re_data_store, re_data_store::external::*, re_entity_db, re_log, re_log_types, re_memory,
re_renderer, re_types, re_ui, re_viewer_context, re_viewer_context::external::*,
re_viewport, re_viewport::external::*,
};
}
#[cfg(not(target_arch = "wasm32"))]
pub mod native;
#[cfg(not(target_arch = "wasm32"))]
pub use native::{run_native_app, run_native_viewer_with_messages};
#[cfg(target_arch = "wasm32")]
mod web;
#[cfg(target_arch = "wasm32")]
mod web_tools;
pub fn build_info() -> re_build_info::BuildInfo {
re_build_info::build_info!()
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AppEnvironment {
CSdk,
PythonSdk(re_log_types::PythonVersion),
RustSdk {
rustc_version: String,
llvm_version: String,
},
RerunCli {
rustc_version: String,
llvm_version: String,
},
Web,
Custom(String),
}
impl AppEnvironment {
pub fn from_store_source(source: &re_log_types::StoreSource) -> Self {
use re_log_types::StoreSource;
match source {
StoreSource::CSdk => Self::CSdk,
StoreSource::PythonSdk(python_version) => Self::PythonSdk(python_version.clone()),
StoreSource::RustSdk {
rustc_version,
llvm_version,
} => Self::RustSdk {
rustc_version: rustc_version.clone(),
llvm_version: llvm_version.clone(),
},
StoreSource::File { .. }
| StoreSource::Unknown
| StoreSource::Viewer
| StoreSource::Other(_) => {
#[cfg(debug_assertions)]
re_log::warn_once!("Asked to create an AppEnvironment from {source:?}");
Self::RustSdk {
rustc_version: "unknown".into(),
llvm_version: "unknown".into(),
}
}
}
}
}
fn supported_graphics_backends(force_wgpu_backend: Option<String>) -> wgpu::Backends {
if let Some(force_wgpu_backend) = force_wgpu_backend {
if let Some(backend) = re_renderer::config::parse_graphics_backend(&force_wgpu_backend) {
if let Err(err) = re_renderer::config::validate_graphics_backend_applicability(backend)
{
re_log::error!("Failed to force rendering backend parsed from {force_wgpu_backend:?}: {err}\nUsing default backend instead.");
re_renderer::config::supported_backends()
} else {
re_log::info!("Forcing graphics backend to {backend:?}.");
backend.into()
}
} else {
re_log::error!("Failed to parse rendering backend string {force_wgpu_backend:?}. Using default backend instead.");
re_renderer::config::supported_backends()
}
} else {
re_renderer::config::supported_backends()
}
}
pub(crate) fn wgpu_options(force_wgpu_backend: Option<String>) -> egui_wgpu::WgpuConfiguration {
re_tracing::profile_function!();
egui_wgpu::WgpuConfiguration {
#[cfg(all(not(target_arch = "wasm32"), debug_assertions))] on_surface_error: std::sync::Arc::new(|err| {
if err == wgpu::SurfaceError::Outdated && !cfg!(target_os = "windows"){
egui_wgpu::SurfaceErrorAction::RecreateSurface
} else {
egui_wgpu::SurfaceErrorAction::SkipFrame
}
}),
supported_backends: supported_graphics_backends(force_wgpu_backend),
device_descriptor: std::sync::Arc::new(|adapter| re_renderer::config::DeviceCaps::from_adapter(adapter).device_descriptor()),
..Default::default()
}
}
#[must_use]
pub fn customize_eframe(cc: &eframe::CreationContext<'_>) -> re_ui::ReUi {
re_tracing::profile_function!();
if let Some(render_state) = &cc.wgpu_render_state {
use re_renderer::{config::RenderContextConfig, RenderContext};
let paint_callback_resources = &mut render_state.renderer.write().callback_resources;
paint_callback_resources.insert(RenderContext::new(
&render_state.adapter,
render_state.device.clone(),
render_state.queue.clone(),
RenderContextConfig {
output_format_color: render_state.target_format,
device_caps: re_renderer::config::DeviceCaps::from_adapter(&render_state.adapter),
},
));
}
re_ui::ReUi::load_and_apply(&cc.egui_ctx)
}
#[cfg(not(feature = "web_viewer"))]
#[cfg(not(target_arch = "wasm32"))]
pub fn wake_up_ui_thread_on_each_msg<T: Send + 'static>(
rx: re_smart_channel::Receiver<T>,
ctx: egui::Context,
) -> re_smart_channel::Receiver<T> {
let (tx, new_rx) = rx.chained_channel();
std::thread::Builder::new()
.name("ui_waker".to_owned())
.spawn(move || {
while let Ok(msg) = rx.recv_with_send_time() {
if tx.send_at(msg.time, msg.source, msg.payload).is_ok() {
ctx.request_repaint();
} else {
break;
}
}
re_log::debug!("Shutting down ui_waker thread");
})
.unwrap();
new_rx
}