mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-04 12:58:23 +00:00
progress
This commit is contained in:
@@ -31,7 +31,7 @@ impl TrackpointChunk {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct WaypointChunkId(Uuid);
|
||||
|
||||
impl Default for WaypointChunkId {
|
||||
|
||||
@@ -13,12 +13,22 @@ impl Default for FileId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct FileWaypointsRevisionId(pub Uuid);
|
||||
|
||||
impl Default for FileWaypointsRevisionId {
|
||||
fn default() -> Self {
|
||||
Self(Uuid::new_v4())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct File {
|
||||
pub id: FileId,
|
||||
pub info: FileInfo,
|
||||
pub trk: Vec<Track>,
|
||||
pub wpt: Vec<Rc<WaypointChunk>>,
|
||||
pub wpt_rev_id: FileWaypointsRevisionId,
|
||||
// TODO routes
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,9 @@ mod tests {
|
||||
file_id: id,
|
||||
wpt_ids: HashSet::from([ids[1]]),
|
||||
};
|
||||
let rev = fx.files[&id].wpt_rev_id;
|
||||
Delete.apply(&mut fx.state()).unwrap();
|
||||
assert_ne!(fx.files[&id].wpt_rev_id, rev);
|
||||
let left: Vec<_> = fx.files[&id]
|
||||
.wpt
|
||||
.iter()
|
||||
|
||||
@@ -161,6 +161,7 @@ fn duplicate_waypoints(
|
||||
chunks
|
||||
};
|
||||
file.wpt.splice(last_chunk..=last_chunk, replacement);
|
||||
file.wpt_rev_id = Default::default();
|
||||
files.insert(file_id, Rc::new(file));
|
||||
Ok(Selection::Waypoint {
|
||||
file_id,
|
||||
@@ -304,7 +305,9 @@ mod tests {
|
||||
file_id: id,
|
||||
wpt_ids: HashSet::from([ids[0]]),
|
||||
};
|
||||
let rev = fx.files[&id].wpt_rev_id;
|
||||
Duplicate.apply(&mut fx.state()).unwrap();
|
||||
assert_ne!(fx.files[&id].wpt_rev_id, rev);
|
||||
let all: Vec<_> = fx.files[&id]
|
||||
.wpt
|
||||
.iter()
|
||||
|
||||
@@ -33,5 +33,8 @@ pub fn edit_waypoint_chunks(
|
||||
}
|
||||
}
|
||||
file.wpt = chunks;
|
||||
if changed {
|
||||
file.wpt_rev_id = Default::default();
|
||||
}
|
||||
changed
|
||||
}
|
||||
|
||||
@@ -305,7 +305,9 @@ mod tests {
|
||||
file_id: id,
|
||||
wpt_ids: HashSet::from([ids[1]]),
|
||||
};
|
||||
let rev = fx.files[&id].wpt_rev_id;
|
||||
update_selected(&mut fx.state(), &mut Name);
|
||||
assert_ne!(fx.files[&id].wpt_rev_id, rev);
|
||||
let chunk = &fx.files[&id].wpt[0];
|
||||
assert_ne!(chunk.id, chunk_id);
|
||||
let named: Vec<_> = chunk.wpt.iter().map(|w| w.name.is_some()).collect();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use crate::{
|
||||
FileId, StackEntry as Files, TrackSegmentId, TrackSegmentRevisionId, waypoints_revision,
|
||||
FileId, FileWaypointsRevisionId, StackEntry as Files, TrackSegmentId, TrackSegmentRevisionId,
|
||||
};
|
||||
|
||||
/// Coordinates buffers, as flat `[lng, lat, lng, lat, ...]` arrays so that they can be handed
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CoordinatesCache {
|
||||
segments: HashMap<TrackSegmentId, (TrackSegmentRevisionId, Vec<f64>)>,
|
||||
waypoints: HashMap<FileId, (u64, Vec<f64>)>,
|
||||
waypoints: HashMap<FileId, (FileWaypointsRevisionId, Vec<f64>)>,
|
||||
}
|
||||
|
||||
impl CoordinatesCache {
|
||||
@@ -20,15 +20,19 @@ impl CoordinatesCache {
|
||||
let mut waypoints = HashSet::new();
|
||||
for file in files.into_iter().flat_map(|files| files.values()) {
|
||||
waypoints.insert(file.id);
|
||||
let rev = waypoints_revision(file);
|
||||
if self.waypoints.get(&file.id).is_none_or(|(r, _)| *r != rev) {
|
||||
if self
|
||||
.waypoints
|
||||
.get(&file.id)
|
||||
.is_none_or(|(r, _)| *r != file.wpt_rev_id)
|
||||
{
|
||||
let coordinates = file
|
||||
.wpt
|
||||
.iter()
|
||||
.flat_map(|chunk| &chunk.wpt)
|
||||
.flat_map(|wpt| [wpt.coordinates.lng, wpt.coordinates.lat])
|
||||
.collect();
|
||||
self.waypoints.insert(file.id, (rev, coordinates));
|
||||
self.waypoints
|
||||
.insert(file.id, (file.wpt_rev_id, coordinates));
|
||||
}
|
||||
for seg in file.trk.iter().flat_map(|trk| &trk.trkseg) {
|
||||
segments.insert(seg.id);
|
||||
@@ -131,6 +135,7 @@ mod tests {
|
||||
..Default::default()
|
||||
};
|
||||
let mut file = (*fx.files[&id]).clone();
|
||||
file.wpt_rev_id = Default::default();
|
||||
file.wpt = vec![
|
||||
Rc::new(WaypointChunk {
|
||||
wpt: vec![wpt(1.0, 2.0)],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::{File, FileId, TrackId, TrackSegmentId, TrackSegmentRevisionId, WaypointId};
|
||||
use crate::{
|
||||
File, FileId, FileWaypointsRevisionId, TrackId, TrackSegmentId, TrackSegmentRevisionId,
|
||||
WaypointId,
|
||||
};
|
||||
|
||||
/// What the UI needs to display a file: its name and the structure of its tracks and waypoints,
|
||||
/// with the ids that reference every element. Coordinates are not part of it, they are read
|
||||
@@ -14,7 +15,7 @@ pub struct FileStructure {
|
||||
pub tracks: Vec<TrackNode>,
|
||||
pub waypoints: Vec<WaypointNode>,
|
||||
/// Changes whenever the waypoints of the file (hence their buffer) change.
|
||||
pub waypoints_rev: u64,
|
||||
pub wpt_rev_id: FileWaypointsRevisionId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@@ -69,20 +70,11 @@ impl FileStructure {
|
||||
name: wpt.name.clone(),
|
||||
})
|
||||
.collect(),
|
||||
waypoints_rev: waypoints_revision(file),
|
||||
wpt_rev_id: file.wpt_rev_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifies the current waypoints of a file: chunks are immutable, so their ids are enough.
|
||||
pub fn waypoints_revision(file: &File) -> u64 {
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
for chunk in &file.wpt {
|
||||
chunk.id.hash(&mut hasher);
|
||||
}
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rc::Rc;
|
||||
@@ -116,7 +108,8 @@ mod tests {
|
||||
name: Some(n.to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
let before = waypoints_revision(&file);
|
||||
let before = file.wpt_rev_id;
|
||||
file.wpt_rev_id = Default::default();
|
||||
file.wpt = vec![
|
||||
Rc::new(WaypointChunk {
|
||||
wpt: vec![wpt("a"), wpt("b")],
|
||||
@@ -134,7 +127,7 @@ mod tests {
|
||||
.map(|w| w.name.clone().unwrap())
|
||||
.collect();
|
||||
assert_eq!(names, ["a", "b", "c"]);
|
||||
assert_ne!(node.waypoints_rev, before);
|
||||
assert_eq!(node.waypoints_rev, waypoints_revision(&file));
|
||||
assert_ne!(node.wpt_rev_id, before);
|
||||
assert_eq!(node.wpt_rev_id, file.wpt_rev_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ fn structure_object(file: &engine::FileStructure) -> Object {
|
||||
named_node(wpt.id.0, wpt.name.as_deref()).into()
|
||||
}),
|
||||
);
|
||||
set(&node, "waypointsRev", format!("{:x}", file.waypoints_rev));
|
||||
set(&node, "waypointsRev", file.wpt_rev_id.0.to_string());
|
||||
node
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user