WIP: pass synchronize channel buffers integration test

This commit is contained in:
Mikayla 2023-08-21 17:53:37 -07:00
parent a7a4e2e369
commit 364ed1f840
No known key found for this signature in database
15 changed files with 411 additions and 135 deletions

View file

@ -1,9 +1,10 @@
use crate::ChannelId;
use anyhow::Result;
use client::Client;
use gpui::{Entity, ModelContext, ModelHandle, Task};
use rpc::proto::GetChannelBuffer;
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task};
use rpc::{proto, TypedEnvelope};
use std::sync::Arc;
use util::ResultExt;
// Open the channel document
// ChannelDocumentView { ChannelDocument, Editor } -> On clone, clones internal ChannelDocument handle, instantiates new editor
@ -14,9 +15,12 @@ use std::sync::Arc;
// ChannleBuffers: HashMap<bufferId, ModelHandle<language::Buffer>>
// }
type BufferId = u64;
pub struct ChannelBuffer {
channel_id: ChannelId,
buffer: Option<ModelHandle<language::Buffer>>,
buffer_id: BufferId,
buffer: ModelHandle<language::Buffer>,
client: Arc<Client>,
}
@ -28,53 +32,76 @@ impl ChannelBuffer {
pub fn for_channel(
channel_id: ChannelId,
client: Arc<Client>,
cx: &mut ModelContext<Self>,
) -> Self {
Self {
channel_id,
client,
buffer: None,
}
cx: &mut AppContext,
) -> Task<Result<ModelHandle<Self>>> {
cx.spawn(|mut cx| async move {
let response = client
.request(proto::OpenChannelBuffer { channel_id })
.await?;
let base_text = response.base_text;
let operations = response
.operations
.into_iter()
.map(language::proto::deserialize_operation)
.collect::<Result<Vec<_>, _>>()?;
let buffer_id = response.buffer_id;
let buffer = cx.add_model(|cx| language::Buffer::new(0, base_text, cx));
buffer.update(&mut cx, |buffer, cx| buffer.apply_ops(operations, cx))?;
anyhow::Ok(cx.add_model(|cx| {
cx.subscribe(&buffer, Self::on_buffer_update).detach();
client.add_model_message_handler(Self::handle_update_channel_buffer);
Self {
buffer_id,
buffer,
client,
channel_id,
}
}))
})
}
async fn handle_update_channel_buffer(
this: ModelHandle<Self>,
update_channel_buffer: TypedEnvelope<proto::UpdateChannelBuffer>,
_: Arc<Client>,
mut cx: AsyncAppContext,
) -> Result<()> {
let ops = update_channel_buffer
.payload
.operations
.into_iter()
.map(language::proto::deserialize_operation)
.collect::<Result<Vec<_>, _>>()?;
this.update(&mut cx, |this, cx| {
this.buffer
.update(cx, |buffer, cx| buffer.apply_ops(ops, cx))
})?;
Ok(())
}
fn on_buffer_update(
&mut self,
buffer: ModelHandle<language::Buffer>,
_: ModelHandle<language::Buffer>,
event: &language::Event,
cx: &mut ModelContext<Self>,
_: &mut ModelContext<Self>,
) {
//
}
pub fn buffer(
&mut self,
cx: &mut ModelContext<Self>,
) -> Task<Result<ModelHandle<language::Buffer>>> {
if let Some(buffer) = &self.buffer {
Task::ready(Ok(buffer.clone()))
} else {
let channel_id = self.channel_id;
let client = self.client.clone();
cx.spawn(|this, mut cx| async move {
let response = client.request(GetChannelBuffer { channel_id }).await?;
let base_text = response.base_text;
let operations = response
.operations
.into_iter()
.map(language::proto::deserialize_operation)
.collect::<Result<Vec<_>, _>>()?;
this.update(&mut cx, |this, cx| {
let buffer = cx.add_model(|cx| language::Buffer::new(0, base_text, cx));
buffer.update(cx, |buffer, cx| buffer.apply_ops(operations, cx))?;
cx.subscribe(&buffer, Self::on_buffer_update).detach();
this.buffer = Some(buffer.clone());
anyhow::Ok(buffer)
if let language::Event::Operation(operation) = event {
let operation = language::proto::serialize_operation(operation);
self.client
.send(proto::UpdateChannelBuffer {
buffer_id: self.buffer_id,
operations: vec![operation],
})
})
.log_err();
}
}
pub fn buffer(&self) -> ModelHandle<language::Buffer> {
self.buffer.clone()
}
}