Improve the ergonomics of creating local buffers (#10347)
This PR renames `language::Buffer::new` to `language::Buffer::local` and
simplifies its interface. Instead of taking a replica id (which should
always be 0 for the local case) and a `BufferId`, which was awkward and
verbose to construct, it simply takes text and a `cx`.
It uses the `cx` to derive a `BufferId` from the `EntityId` associated
with the `cx`, which should always be positive based on the following
analysis...
We convert the entity id to a u64 using this method on `EntityId`, which
is defined by macros in the `slotmap` crate:
```rust
pub fn as_ffi(self) -> u64 {
(u64::from(self.version.get()) << 32) | u64::from(self.idx)
}
```
If you look at the type of `version` in `KeyData`, it is non-zero:
```rust
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct KeyData {
idx: u32,
version: NonZeroU32,
}
```
This commit also adds `Context::reserve_model` and
`Context::insert_model` to determine a model's entity ID before it is
created, which we need in order to assign a `BufferId` in the background
when loading a buffer asynchronously.
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This commit is contained in:
co-authored by
Piotr Osiewicz
parent
664efef76b
commit
7abb63cfda
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, BorrowAppContext, Context,
|
||||
DismissEvent, FocusableView, ForegroundExecutor, Global, Model, ModelContext, Render, Result,
|
||||
Task, View, ViewContext, VisualContext, WindowContext, WindowHandle,
|
||||
DismissEvent, FocusableView, ForegroundExecutor, Global, Model, ModelContext, Render,
|
||||
Reservation, Result, Task, View, ViewContext, VisualContext, WindowContext, WindowHandle,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@@ -35,6 +35,28 @@ impl Context for AsyncAppContext {
|
||||
Ok(app.new_model(build_model))
|
||||
}
|
||||
|
||||
fn reserve_model<T: 'static>(&mut self) -> Result<Reservation<T>> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.reserve_model())
|
||||
}
|
||||
|
||||
fn insert_model<T: 'static>(
|
||||
&mut self,
|
||||
reservation: Reservation<T>,
|
||||
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
|
||||
) -> Result<Model<T>> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.insert_model(reservation, build_model))
|
||||
}
|
||||
|
||||
fn update_model<T: 'static, R>(
|
||||
&mut self,
|
||||
handle: &Model<T>,
|
||||
@@ -278,6 +300,19 @@ impl Context for AsyncWindowContext {
|
||||
self.window.update(self, |_, cx| cx.new_model(build_model))
|
||||
}
|
||||
|
||||
fn reserve_model<T: 'static>(&mut self) -> Result<Reservation<T>> {
|
||||
self.window.update(self, |_, cx| cx.reserve_model())
|
||||
}
|
||||
|
||||
fn insert_model<T: 'static>(
|
||||
&mut self,
|
||||
reservation: Reservation<T>,
|
||||
build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
|
||||
) -> Self::Result<Model<T>> {
|
||||
self.window
|
||||
.update(self, |_, cx| cx.insert_model(reservation, build_model))
|
||||
}
|
||||
|
||||
fn update_model<T: 'static, R>(
|
||||
&mut self,
|
||||
handle: &Model<T>,
|
||||
@@ -287,13 +322,6 @@ impl Context for AsyncWindowContext {
|
||||
.update(self, |_, cx| cx.update_model(handle, update))
|
||||
}
|
||||
|
||||
fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
|
||||
where
|
||||
F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
|
||||
{
|
||||
self.app.update_window(window, update)
|
||||
}
|
||||
|
||||
fn read_model<T, R>(
|
||||
&self,
|
||||
handle: &Model<T>,
|
||||
@@ -305,6 +333,13 @@ impl Context for AsyncWindowContext {
|
||||
self.app.read_model(handle, read)
|
||||
}
|
||||
|
||||
fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
|
||||
where
|
||||
F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
|
||||
{
|
||||
self.app.update_window(window, update)
|
||||
}
|
||||
|
||||
fn read_window<T, R>(
|
||||
&self,
|
||||
window: &WindowHandle<T>,
|
||||
|
||||
Reference in New Issue
Block a user