Skip to content

Commit 1f4c61a

Browse files
committed
implement consistent open/import/log_file behavior for all cases
1 parent 3886323 commit 1f4c61a

File tree

13 files changed

+159
-48
lines changed

13 files changed

+159
-48
lines changed

Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -5376,6 +5376,7 @@ dependencies = [
53765376
"re_types",
53775377
"tempfile",
53785378
"thiserror",
5379+
"uuid",
53795380
"walkdir",
53805381
]
53815382

@@ -6415,6 +6416,7 @@ dependencies = [
64156416
"strum",
64166417
"strum_macros",
64176418
"thiserror",
6419+
"uuid",
64186420
"wasm-bindgen",
64196421
"wasm-bindgen-futures",
64206422
"web-sys",

crates/store/re_data_loader/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ once_cell.workspace = true
4343
parking_lot.workspace = true
4444
rayon.workspace = true
4545
thiserror.workspace = true
46+
uuid.workspace = true
4647
walkdir.workspace = true
4748

4849
[target.'cfg(not(any(target_arch = "wasm32")))'.dependencies]

crates/store/re_data_loader/src/lib.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ pub struct DataLoaderSettings {
6464
/// The [`re_log_types::StoreId`] that is currently opened in the viewer, if any.
6565
pub opened_store_id: Option<re_log_types::StoreId>,
6666

67+
/// Whether `SetStoreInfo`s should be sent, regardless of the surrounding context.
68+
///
69+
/// Only useful when creating a recording just-in-time directly in the viewer (which is what
70+
/// happens when importing things into the welcome screen).
71+
pub force_store_info: bool,
72+
6773
/// What should the logged entity paths be prefixed with?
6874
pub entity_path_prefix: Option<EntityPath>,
6975

@@ -79,6 +85,7 @@ impl DataLoaderSettings {
7985
opened_application_id: Default::default(),
8086
store_id: store_id.into(),
8187
opened_store_id: Default::default(),
88+
force_store_info: false,
8289
entity_path_prefix: Default::default(),
8390
timepoint: Default::default(),
8491
}
@@ -91,6 +98,7 @@ impl DataLoaderSettings {
9198
opened_application_id,
9299
store_id,
93100
opened_store_id,
101+
force_store_info: _,
94102
entity_path_prefix,
95103
timepoint,
96104
} = self;
@@ -150,6 +158,8 @@ impl DataLoaderSettings {
150158
}
151159
}
152160

161+
pub type DataLoaderName = String;
162+
153163
/// A [`DataLoader`] loads data from a file path and/or a file's contents.
154164
///
155165
/// Files can be loaded in 3 different ways:
@@ -205,8 +215,8 @@ impl DataLoaderSettings {
205215
pub trait DataLoader: Send + Sync {
206216
/// Name of the [`DataLoader`].
207217
///
208-
/// Doesn't need to be unique.
209-
fn name(&self) -> String;
218+
/// Should be globally unique.
219+
fn name(&self) -> DataLoaderName;
210220

211221
/// Loads data from a file on the local filesystem and sends it to `tx`.
212222
///
@@ -314,20 +324,31 @@ impl DataLoaderError {
314324
/// most convenient for them, whether it is raw components, arrow chunks or even
315325
/// full-on [`LogMsg`]s.
316326
pub enum LoadedData {
317-
Chunk(re_log_types::StoreId, Chunk),
318-
ArrowMsg(re_log_types::StoreId, ArrowMsg),
319-
LogMsg(LogMsg),
327+
Chunk(DataLoaderName, re_log_types::StoreId, Chunk),
328+
ArrowMsg(DataLoaderName, re_log_types::StoreId, ArrowMsg),
329+
LogMsg(DataLoaderName, LogMsg),
320330
}
321331

322332
impl LoadedData {
333+
/// Returns the name of the [`DataLoader`] that generated this data.
334+
#[inline]
335+
pub fn data_loader_name(&self) -> &DataLoaderName {
336+
match self {
337+
Self::Chunk(name, ..) | Self::ArrowMsg(name, ..) | Self::LogMsg(name, ..) => name,
338+
}
339+
}
340+
323341
/// Pack the data into a [`LogMsg`].
342+
#[inline]
324343
pub fn into_log_msg(self) -> ChunkResult<LogMsg> {
325344
match self {
326-
Self::Chunk(store_id, chunk) => Ok(LogMsg::ArrowMsg(store_id, chunk.to_arrow_msg()?)),
345+
Self::Chunk(_name, store_id, chunk) => {
346+
Ok(LogMsg::ArrowMsg(store_id, chunk.to_arrow_msg()?))
347+
}
327348

328-
Self::ArrowMsg(store_id, msg) => Ok(LogMsg::ArrowMsg(store_id, msg)),
349+
Self::ArrowMsg(_name, store_id, msg) => Ok(LogMsg::ArrowMsg(store_id, msg)),
329350

330-
Self::LogMsg(msg) => Ok(msg),
351+
Self::LogMsg(_name, msg) => Ok(msg),
331352
}
332353
}
333354
}

crates/store/re_data_loader/src/load_file.rs

+33-16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use ahash::{HashMap, HashMapExt};
44
use re_log_types::{FileSource, LogMsg};
55
use re_smart_channel::Sender;
66

7-
use crate::{DataLoaderError, LoadedData};
7+
use crate::{DataLoader, DataLoaderError, LoadedData, RrdLoader};
88

99
// ---
1010

@@ -37,7 +37,7 @@ pub fn load_from_path(
3737

3838
let rx = load(settings, path, None)?;
3939

40-
send(settings.clone(), file_source, path.to_owned(), rx, tx);
40+
send(settings.clone(), file_source, rx, tx);
4141

4242
Ok(())
4343
}
@@ -64,7 +64,7 @@ pub fn load_from_file_contents(
6464

6565
let data = load(settings, filepath, Some(contents))?;
6666

67-
send(settings.clone(), file_source, filepath.to_owned(), data, tx);
67+
send(settings.clone(), file_source, data, tx);
6868

6969
Ok(())
7070
}
@@ -73,21 +73,20 @@ pub fn load_from_file_contents(
7373

7474
/// Prepares an adequate [`re_log_types::StoreInfo`] [`LogMsg`] given the input.
7575
pub(crate) fn prepare_store_info(
76+
application_id: re_log_types::ApplicationId,
7677
store_id: &re_log_types::StoreId,
7778
file_source: FileSource,
78-
path: &std::path::Path,
7979
) -> LogMsg {
80-
re_tracing::profile_function!(path.display().to_string());
80+
re_tracing::profile_function!();
8181

8282
use re_log_types::SetStoreInfo;
8383

84-
let app_id = re_log_types::ApplicationId(path.display().to_string());
8584
let store_source = re_log_types::StoreSource::File { file_source };
8685

8786
LogMsg::SetStoreInfo(SetStoreInfo {
8887
row_id: *re_chunk::RowId::new(),
8988
info: re_log_types::StoreInfo {
90-
application_id: app_id.clone(),
89+
application_id,
9190
store_id: store_id.clone(),
9291
cloned_from: None,
9392
is_official_example: false,
@@ -263,14 +262,19 @@ pub(crate) fn load(
263262
pub(crate) fn send(
264263
settings: crate::DataLoaderSettings,
265264
file_source: FileSource,
266-
path: std::path::PathBuf,
267265
rx_loader: std::sync::mpsc::Receiver<LoadedData>,
268266
tx: &Sender<LogMsg>,
269267
) {
270268
spawn({
271269
re_tracing::profile_function!();
272270

273-
let mut store_info_tracker: HashMap<re_log_types::StoreId, bool> = HashMap::new();
271+
#[derive(Default, Debug)]
272+
struct Tracked {
273+
is_rrd_or_rbl: bool,
274+
already_has_store_info: bool,
275+
}
276+
277+
let mut store_info_tracker: HashMap<re_log_types::StoreId, Tracked> = HashMap::new();
274278

275279
let tx = tx.clone();
276280
move || {
@@ -280,6 +284,7 @@ pub(crate) fn send(
280284
// poll the channel in any case so as to make sure that the data producer
281285
// doesn't get stuck.
282286
for data in rx_loader {
287+
let data_loader_name = data.data_loader_name().clone();
283288
let msg = match data.into_log_msg() {
284289
Ok(msg) => {
285290
let store_info = match &msg {
@@ -293,7 +298,10 @@ pub(crate) fn send(
293298
};
294299

295300
if let Some((store_id, store_info_created)) = store_info {
296-
*store_info_tracker.entry(store_id).or_default() |= store_info_created;
301+
let tracked = store_info_tracker.entry(store_id).or_default();
302+
tracked.is_rrd_or_rbl =
303+
*data_loader_name == RrdLoader::name(&RrdLoader);
304+
tracked.already_has_store_info |= store_info_created;
297305
}
298306

299307
msg
@@ -306,16 +314,25 @@ pub(crate) fn send(
306314
tx.send(msg).ok();
307315
}
308316

309-
for (store_id, store_info_already_created) in store_info_tracker {
317+
for (store_id, tracked) in store_info_tracker {
310318
let is_a_preexisting_recording =
311319
Some(&store_id) == settings.opened_store_id.as_ref();
312320

313-
if store_info_already_created || is_a_preexisting_recording {
314-
continue;
315-
}
321+
// Never try to send custom store info for RRDs and RBLs, they always have their own, and
322+
// it's always right.
323+
let should_force_store_info = !tracked.is_rrd_or_rbl && settings.force_store_info;
324+
325+
let should_send_new_store_info = should_force_store_info
326+
|| (!tracked.already_has_store_info && !is_a_preexisting_recording);
316327

317-
let store_info = prepare_store_info(&store_id, file_source.clone(), &path);
318-
tx.send(store_info).ok();
328+
if should_send_new_store_info {
329+
let app_id = settings
330+
.opened_application_id
331+
.clone()
332+
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string().into());
333+
let store_info = prepare_store_info(app_id, &store_id, file_source.clone());
334+
tx.send(store_info).ok();
335+
}
319336
}
320337

321338
tx.quit(None).ok();

crates/store/re_data_loader/src/loader_archetype.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl DataLoader for ArchetypeLoader {
138138
.clone()
139139
.unwrap_or_else(|| settings.store_id.clone());
140140
for row in rows {
141-
let data = LoadedData::Chunk(store_id.clone(), row);
141+
let data = LoadedData::Chunk(Self::name(&Self), store_id.clone(), row);
142142
if tx.send(data).is_err() {
143143
break; // The other end has decided to hang up, not our problem.
144144
}

crates/store/re_data_loader/src/loader_external.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66
use ahash::HashMap;
77
use once_cell::sync::Lazy;
88

9-
use crate::LoadedData;
9+
use crate::{DataLoader, LoadedData};
1010

1111
// ---
1212

@@ -321,7 +321,7 @@ fn decode_and_stream<R: std::io::Read>(
321321
}
322322
};
323323

324-
let data = LoadedData::LogMsg(msg);
324+
let data = LoadedData::LogMsg(ExternalLoader::name(&ExternalLoader), msg);
325325
if tx.send(data).is_err() {
326326
break; // The other end has decided to hang up, not our problem.
327327
}

crates/store/re_data_loader/src/loader_rrd.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use re_log_encoding::decoder::Decoder;
44
use crossbeam::channel::Receiver;
55
use re_log_types::{ApplicationId, StoreId};
66

7-
use crate::LoadedData;
7+
use crate::{DataLoader as _, LoadedData};
88

99
// ---
1010

@@ -192,7 +192,7 @@ fn decode_and_stream<R: std::io::Read>(
192192
msg
193193
};
194194

195-
let data = LoadedData::LogMsg(msg);
195+
let data = LoadedData::LogMsg(RrdLoader::name(&RrdLoader), msg);
196196
if tx.send(data).is_err() {
197197
break; // The other end has decided to hang up, not our problem.
198198
}

crates/store/re_data_source/src/data_source.rs

+3
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ impl DataSource {
178178
let settings = re_data_loader::DataLoaderSettings {
179179
opened_application_id: file_source.recommended_application_id().cloned(),
180180
opened_store_id: file_source.recommended_recording_id().cloned(),
181+
force_store_info: file_source.force_store_info(),
181182
..re_data_loader::DataLoaderSettings::recommended(shared_store_id)
182183
};
183184
re_data_loader::load_from_path(&settings, file_source, &path, &tx)
@@ -206,6 +207,7 @@ impl DataSource {
206207
let settings = re_data_loader::DataLoaderSettings {
207208
opened_application_id: file_source.recommended_application_id().cloned(),
208209
opened_store_id: file_source.recommended_recording_id().cloned(),
210+
force_store_info: file_source.force_store_info(),
209211
..re_data_loader::DataLoaderSettings::recommended(shared_store_id)
210212
};
211213
re_data_loader::load_from_file_contents(
@@ -275,6 +277,7 @@ fn test_data_source_from_uri() {
275277
let file_source = FileSource::DragAndDrop {
276278
recommended_application_id: None,
277279
recommended_recording_id: None,
280+
force_store_info: false,
278281
};
279282

280283
for uri in file {

crates/store/re_log_types/src/lib.rs

+31
Original file line numberDiff line numberDiff line change
@@ -413,21 +413,39 @@ pub enum FileSource {
413413
DragAndDrop {
414414
/// The [`ApplicationId`] that the viewer heuristically recommends should be used when loading
415415
/// this data source, based on the surrounding context.
416+
#[cfg_attr(feature = "serde", serde(skip))]
416417
recommended_application_id: Option<ApplicationId>,
417418

418419
/// The [`StoreId`] that the viewer heuristically recommends should be used when loading
419420
/// this data source, based on the surrounding context.
421+
#[cfg_attr(feature = "serde", serde(skip))]
420422
recommended_recording_id: Option<StoreId>,
423+
424+
/// Whether `SetStoreInfo`s should be sent, regardless of the surrounding context.
425+
///
426+
/// Only useful when creating a recording just-in-time directly in the viewer (which is what
427+
/// happens when importing things into the welcome screen).
428+
#[cfg_attr(feature = "serde", serde(skip))]
429+
force_store_info: bool,
421430
},
422431

423432
FileDialog {
424433
/// The [`ApplicationId`] that the viewer heuristically recommends should be used when loading
425434
/// this data source, based on the surrounding context.
435+
#[cfg_attr(feature = "serde", serde(skip))]
426436
recommended_application_id: Option<ApplicationId>,
427437

428438
/// The [`StoreId`] that the viewer heuristically recommends should be used when loading
429439
/// this data source, based on the surrounding context.
440+
#[cfg_attr(feature = "serde", serde(skip))]
430441
recommended_recording_id: Option<StoreId>,
442+
443+
/// Whether `SetStoreInfo`s should be sent, regardless of the surrounding context.
444+
///
445+
/// Only useful when creating a recording just-in-time directly in the viewer (which is what
446+
/// happens when importing things into the welcome screen).
447+
#[cfg_attr(feature = "serde", serde(skip))]
448+
force_store_info: bool,
431449
},
432450

433451
Sdk,
@@ -463,6 +481,19 @@ impl FileSource {
463481
Self::Cli | Self::Sdk => None,
464482
}
465483
}
484+
485+
#[inline]
486+
pub fn force_store_info(&self) -> bool {
487+
match self {
488+
Self::FileDialog {
489+
force_store_info, ..
490+
}
491+
| Self::DragAndDrop {
492+
force_store_info, ..
493+
} => *force_store_info,
494+
Self::Cli | Self::Sdk => false,
495+
}
496+
}
466497
}
467498

468499
/// The source of a recording or blueprint.

crates/top/re_sdk/src/recording_stream.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,7 @@ impl RecordingStream {
12591259
opened_application_id: None,
12601260
store_id: store_info.store_id.clone(),
12611261
opened_store_id: None,
1262+
force_store_info: false,
12621263
entity_path_prefix,
12631264
timepoint: (!static_).then(|| {
12641265
self.with(|inner| {

crates/viewer/re_viewer/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ serde = { workspace = true, features = ["derive"] }
120120
serde_json.workspace = true
121121
serde-wasm-bindgen.workspace = true
122122
thiserror.workspace = true
123+
uuid.workspace = true
123124
web-time.workspace = true
124125
wgpu.workspace = true
125126

0 commit comments

Comments
 (0)