WIP: Start on WrapMap

This commit is contained in:
Antonio Scandurra
2021-07-14 18:43:48 +02:00
parent 4313e99a00
commit a5edc14e3a
3 changed files with 154 additions and 3 deletions
+1
View File
@@ -1,4 +1,5 @@
mod fold_map;
mod wrap_map;
use crate::settings::StyleId;
+2 -3
View File
@@ -27,15 +27,14 @@ pub struct FoldMap {
impl FoldMap {
pub fn new(buffer_handle: ModelHandle<Buffer>, cx: &AppContext) -> Self {
let buffer = buffer_handle.read(cx);
let text_summary = buffer.text_summary();
Self {
buffer: buffer_handle,
folds: Default::default(),
transforms: Mutex::new(SumTree::from_item(
Transform {
summary: TransformSummary {
buffer: text_summary.clone(),
display: text_summary,
buffer: buffer.text_summary(),
display: buffer.text_summary(),
},
display_text: None,
},
+151
View File
@@ -0,0 +1,151 @@
use crate::{
editor::{display_map::FoldMap, Buffer, TextSummary},
sum_tree::{self, SumTree},
time,
};
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
use parking_lot::Mutex;
use postage::{
mpsc,
prelude::{Sink, Stream},
watch,
};
#[derive(Clone)]
struct Snapshot {
transforms: SumTree<Transform>,
version: time::Global,
}
struct State {
snapshot: Snapshot,
interpolated_version: time::Global,
}
struct WrapMap {
buffer: ModelHandle<Buffer>,
fold_map: FoldMap,
state: Mutex<State>,
background_snapshots: watch::Receiver<Snapshot>,
_background_task: Task<()>,
}
impl Entity for WrapMap {
type Event = ();
}
impl WrapMap {
fn new(buffer_handle: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self {
let buffer = buffer_handle.read(cx).clone();
let version = buffer.version();
let snapshot = Snapshot {
transforms: SumTree::from_item(
Transform {
summary: TransformSummary {
buffer: buffer.text_summary(),
display: buffer.text_summary(),
},
display_text: None,
},
&(),
),
version: version.clone(),
};
let (background_snapshots_tx, background_snapshots_rx) =
watch::channel_with(snapshot.clone());
let (buffers_tx, buffers_rx) = mpsc::channel(32);
cx.observe(&buffer_handle, move |_, buffer, cx| {
let mut buffers_tx = buffers_tx.clone();
let buffer = buffer.read(cx).clone();
cx.spawn_weak(|_, _| async move {
let _ = buffers_tx.send(buffer).await;
})
.detach();
});
let background_task = cx.background().spawn(async move {
let mut wrapper = BackgroundWrapper::new(buffers_rx, background_snapshots_tx);
wrapper.run(buffer).await;
});
Self {
buffer: buffer_handle.clone(),
fold_map: FoldMap::new(buffer_handle, cx.as_ref()),
state: Mutex::new(State {
snapshot,
interpolated_version: version,
}),
background_snapshots: background_snapshots_rx,
_background_task: background_task,
}
}
}
struct BackgroundWrapper {
buffers_rx: mpsc::Receiver<Buffer>,
snapshots_tx: watch::Sender<Snapshot>,
snapshot: Snapshot,
}
impl BackgroundWrapper {
fn new(buffers_rx: mpsc::Receiver<Buffer>, snapshots_tx: watch::Sender<Snapshot>) -> Self {
Self {
buffers_rx,
snapshots_tx,
snapshot: Snapshot {
transforms: Default::default(),
version: Default::default(),
},
}
}
async fn run(&mut self, buffer: Buffer) {
if !self.sync(buffer).await {
return;
}
while let Some(buffer) = self.buffers_rx.recv().await {
if !self.sync(buffer).await {
break;
}
}
}
async fn sync(&mut self, buffer: Buffer) -> bool {
self.snapshots_tx.send(self.snapshot.clone()).await.is_ok()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Transform {
summary: TransformSummary,
display_text: Option<&'static str>,
}
impl sum_tree::Item for Transform {
type Summary = TransformSummary;
fn summary(&self) -> Self::Summary {
self.summary.clone()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct TransformSummary {
display: TextSummary,
buffer: TextSummary,
}
impl sum_tree::Summary for TransformSummary {
type Context = ();
fn add_summary(&mut self, other: &Self, _: &()) {
self.buffer += &other.buffer;
self.display += &other.display;
}
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for TransformSummary {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
sum_tree::Summary::add_summary(self, summary, &());
}
}