mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-04 18:15:21 +00:00
Implement Snapshot::interpolate
This commit is contained in:
parent
b66de06d0e
commit
3d8c59af31
2 changed files with 93 additions and 31 deletions
|
@ -261,6 +261,12 @@ impl OutputPoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<super::Point> for OutputPoint {
|
||||
fn from(point: super::Point) -> Self {
|
||||
Self(point)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Self> for OutputPoint {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
self.0 += &rhs.0;
|
||||
|
|
|
@ -62,7 +62,6 @@ impl Sub<Self> for OutputPoint {
|
|||
pub struct Snapshot {
|
||||
transforms: SumTree<Transform>,
|
||||
input: InputSnapshot,
|
||||
version: usize,
|
||||
}
|
||||
|
||||
impl Snapshot {
|
||||
|
@ -78,11 +77,67 @@ impl Snapshot {
|
|||
},
|
||||
&(),
|
||||
),
|
||||
version: input.version(),
|
||||
input,
|
||||
}
|
||||
}
|
||||
|
||||
fn interpolate(&mut self, new_snapshot: InputSnapshot, edits: &[InputEdit]) {
|
||||
if edits.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut new_transforms;
|
||||
{
|
||||
let mut old_cursor = self.transforms.cursor::<InputPoint, ()>();
|
||||
let mut edits = edits.into_iter().peekable();
|
||||
new_transforms =
|
||||
old_cursor.slice(&edits.peek().unwrap().old_lines.start, Bias::Right, &());
|
||||
|
||||
while let Some(edit) = edits.next() {
|
||||
if edit.new_lines.start > InputPoint::from(new_transforms.summary().input.lines) {
|
||||
let summary = new_snapshot.text_summary_for_range(
|
||||
InputPoint::from(new_transforms.summary().input.lines)
|
||||
..edit.new_lines.start,
|
||||
);
|
||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||
}
|
||||
|
||||
new_transforms.push_or_extend(Transform::isomorphic(
|
||||
new_snapshot.text_summary_for_range(edit.new_lines.clone()),
|
||||
));
|
||||
|
||||
old_cursor.seek_forward(&edit.old_lines.end, Bias::Right, &());
|
||||
if let Some(next_edit) = edits.peek() {
|
||||
if next_edit.old_lines.start > old_cursor.seek_end(&()) {
|
||||
if old_cursor.seek_end(&()) > edit.old_lines.end {
|
||||
let summary = self.input.text_summary_for_range(
|
||||
edit.old_lines.end..old_cursor.seek_end(&()),
|
||||
);
|
||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||
}
|
||||
old_cursor.next(&());
|
||||
new_transforms.push_tree(
|
||||
old_cursor.slice(&next_edit.old_lines.start, Bias::Right, &()),
|
||||
&(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if old_cursor.seek_end(&()) > edit.old_lines.end {
|
||||
let summary = self
|
||||
.input
|
||||
.text_summary_for_range(edit.old_lines.end..old_cursor.seek_end(&()));
|
||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||
}
|
||||
old_cursor.next(&());
|
||||
new_transforms.push_tree(old_cursor.suffix(&()), &());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.transforms = new_transforms;
|
||||
self.input = new_snapshot;
|
||||
}
|
||||
|
||||
pub fn chunks_at(&self, point: OutputPoint) -> Chunks {
|
||||
let mut transforms = self.transforms.cursor();
|
||||
transforms.seek(&point, Bias::Right, &());
|
||||
|
@ -145,7 +200,6 @@ impl<'a> Iterator for Chunks<'a> {
|
|||
|
||||
struct State {
|
||||
snapshot: Snapshot,
|
||||
interpolated_version: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -179,10 +233,7 @@ impl WrapMap {
|
|||
};
|
||||
|
||||
Self {
|
||||
state: Mutex::new(State {
|
||||
interpolated_version: snapshot.version,
|
||||
snapshot,
|
||||
}),
|
||||
state: Mutex::new(State { snapshot }),
|
||||
edits_tx,
|
||||
background_snapshots: background_snapshots_rx,
|
||||
_background_task: background_task,
|
||||
|
@ -190,7 +241,10 @@ impl WrapMap {
|
|||
}
|
||||
|
||||
pub fn sync(&self, input: InputSnapshot, edits: Vec<InputEdit>) -> Snapshot {
|
||||
// TODO: interpolate
|
||||
self.state
|
||||
.lock()
|
||||
.snapshot
|
||||
.interpolate(input.clone(), &edits);
|
||||
self.edits_tx.try_send((input, edits)).unwrap();
|
||||
self.state.lock().snapshot.clone()
|
||||
}
|
||||
|
@ -378,30 +432,8 @@ impl BackgroundWrapper {
|
|||
|
||||
self.snapshot = Snapshot {
|
||||
transforms: new_transforms,
|
||||
version: new_snapshot.version(),
|
||||
input: new_snapshot,
|
||||
};
|
||||
self.check_invariants();
|
||||
}
|
||||
|
||||
fn check_invariants(&self) {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let summary = self.snapshot.transforms.summary();
|
||||
assert_eq!(
|
||||
InputPoint::new(summary.input.lines.row, summary.input.lines.column),
|
||||
self.snapshot.input.max_point()
|
||||
);
|
||||
|
||||
let mut transforms = self.snapshot.transforms.cursor::<(), ()>().peekable();
|
||||
while let Some(transform) = transforms.next() {
|
||||
let next_transform = transforms.peek();
|
||||
assert!(
|
||||
!transform.is_isomorphic()
|
||||
|| next_transform.map_or(true, |t| !t.is_isomorphic())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,10 +645,14 @@ mod tests {
|
|||
unwrapped_text
|
||||
);
|
||||
|
||||
let mut interpolated_snapshot = wrapper.snapshot.clone();
|
||||
for _i in 0..operations {
|
||||
buffer.update(cx, |buffer, cx| buffer.randomly_mutate(&mut rng, cx));
|
||||
let (snapshot, edits) = fold_map.read(cx.as_ref());
|
||||
let (snapshot, edits) = tab_map.sync(snapshot, edits);
|
||||
interpolated_snapshot.interpolate(snapshot.clone(), &edits);
|
||||
interpolated_snapshot.check_invariants();
|
||||
|
||||
let unwrapped_text = snapshot.text();
|
||||
let expected_text = wrap_text(
|
||||
&unwrapped_text,
|
||||
|
@ -625,7 +661,7 @@ mod tests {
|
|||
font_system.as_ref(),
|
||||
);
|
||||
wrapper.sync(snapshot, edits);
|
||||
|
||||
wrapper.snapshot.check_invariants();
|
||||
let actual_text = wrapper
|
||||
.snapshot
|
||||
.chunks_at(OutputPoint::zero())
|
||||
|
@ -635,6 +671,8 @@ mod tests {
|
|||
"unwrapped text is: {:?}",
|
||||
unwrapped_text
|
||||
);
|
||||
|
||||
interpolated_snapshot = wrapper.snapshot.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -661,4 +699,22 @@ mod tests {
|
|||
}
|
||||
wrapped_text
|
||||
}
|
||||
|
||||
impl Snapshot {
|
||||
fn check_invariants(&self) {
|
||||
assert_eq!(
|
||||
InputPoint::from(self.transforms.summary().input.lines),
|
||||
self.input.max_point()
|
||||
);
|
||||
|
||||
let mut transforms = self.transforms.cursor::<(), ()>().peekable();
|
||||
while let Some(transform) = transforms.next() {
|
||||
let next_transform = transforms.peek();
|
||||
assert!(
|
||||
!transform.is_isomorphic()
|
||||
|| next_transform.map_or(true, |t| !t.is_isomorphic())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue