mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 19:08:00 +03:00
Checkpoint
This commit is contained in:
parent
13ba450c4c
commit
5ab1034698
@ -1,9 +1,9 @@
|
||||
mod async_context;
|
||||
mod entities;
|
||||
mod entity_map;
|
||||
mod model_context;
|
||||
|
||||
pub use async_context::*;
|
||||
pub use entities::*;
|
||||
pub use entity_map::*;
|
||||
pub use model_context::*;
|
||||
|
||||
use crate::{
|
||||
|
@ -1,9 +1,16 @@
|
||||
use crate::Context;
|
||||
use anyhow::{anyhow, Result};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use parking_lot::Mutex;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use slotmap::{SecondaryMap, SlotMap};
|
||||
use std::{any::Any, marker::PhantomData, sync::Arc};
|
||||
use std::{
|
||||
any::Any,
|
||||
marker::PhantomData,
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
Arc, Weak,
|
||||
},
|
||||
};
|
||||
|
||||
slotmap::new_key_type! { pub struct EntityId; }
|
||||
|
||||
@ -16,24 +23,21 @@ pub struct Lease<T> {
|
||||
}
|
||||
|
||||
pub(crate) struct EntityMap {
|
||||
ref_counts: Arc<Mutex<SlotMap<EntityId, usize>>>,
|
||||
ref_counts: Arc<RwLock<RefCounts>>,
|
||||
entities: Arc<Mutex<SecondaryMap<EntityId, Box<dyn Any + Send + Sync>>>>,
|
||||
}
|
||||
|
||||
impl EntityMap {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ref_counts: Arc::new(Mutex::new(SlotMap::with_key())),
|
||||
ref_counts: Arc::new(RwLock::new(SlotMap::with_key())),
|
||||
entities: Arc::new(Mutex::new(SecondaryMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reserve<T>(&self) -> Slot<T> {
|
||||
let id = self.ref_counts.lock().insert(1);
|
||||
Slot(Handle {
|
||||
id,
|
||||
entity_type: PhantomData,
|
||||
})
|
||||
pub fn reserve<T: 'static + Send + Sync>(&self) -> Slot<T> {
|
||||
let id = self.ref_counts.write().insert(1.into());
|
||||
Slot(Handle::new(id, Arc::downgrade(&self.ref_counts)))
|
||||
}
|
||||
|
||||
pub fn redeem<T: 'static + Any + Send + Sync>(&self, slot: Slot<T>, entity: T) -> Handle<T> {
|
||||
@ -42,7 +46,7 @@ impl EntityMap {
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn lease<T: 'static>(&self, handle: &Handle<T>) -> Lease<T> {
|
||||
pub fn lease<T: 'static + Send + Sync>(&self, handle: &Handle<T>) -> Lease<T> {
|
||||
let id = handle.id;
|
||||
let entity = self
|
||||
.entities
|
||||
@ -57,21 +61,33 @@ impl EntityMap {
|
||||
pub fn end_lease<T: 'static + Send + Sync>(&mut self, lease: Lease<T>) {
|
||||
self.entities.lock().insert(lease.id, lease.entity);
|
||||
}
|
||||
|
||||
pub fn weak_handle<T: 'static + Send + Sync>(&self, id: EntityId) -> WeakHandle<T> {
|
||||
WeakHandle {
|
||||
id,
|
||||
entity_type: PhantomData,
|
||||
ref_counts: Arc::downgrade(&self.ref_counts),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deref, DerefMut)]
|
||||
pub struct Slot<T>(Handle<T>);
|
||||
pub struct Slot<T: Send + Sync + 'static>(Handle<T>);
|
||||
|
||||
pub struct Handle<T> {
|
||||
pub struct Handle<T: Send + Sync> {
|
||||
pub(crate) id: EntityId,
|
||||
pub(crate) entity_type: PhantomData<T>,
|
||||
entity_type: PhantomData<T>,
|
||||
ref_counts: Weak<RwLock<RefCounts>>,
|
||||
}
|
||||
|
||||
impl<T: Send + Sync + 'static> Handle<T> {
|
||||
pub fn new(id: EntityId) -> Self {
|
||||
type RefCounts = SlotMap<EntityId, AtomicUsize>;
|
||||
|
||||
impl<T: 'static + Send + Sync> Handle<T> {
|
||||
pub fn new(id: EntityId, ref_counts: Weak<RwLock<RefCounts>>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
entity_type: PhantomData,
|
||||
ref_counts,
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +95,7 @@ impl<T: Send + Sync + 'static> Handle<T> {
|
||||
WeakHandle {
|
||||
id: self.id,
|
||||
entity_type: self.entity_type,
|
||||
ref_counts: self.ref_counts.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,11 +113,23 @@ impl<T: Send + Sync + 'static> Handle<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for Handle<T> {
|
||||
impl<T: Send + Sync> Clone for Handle<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
id: self.id,
|
||||
entity_type: PhantomData,
|
||||
ref_counts: self.ref_counts.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send + Sync> Drop for Handle<T> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref_counts) = self.ref_counts.upgrade() {
|
||||
if let Some(count) = ref_counts.read().get(self.id) {
|
||||
let prev_count = count.fetch_sub(1, SeqCst);
|
||||
assert_ne!(prev_count, 0, "Detected over-release of a handle.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,14 +137,17 @@ impl<T> Clone for Handle<T> {
|
||||
pub struct WeakHandle<T> {
|
||||
pub(crate) id: EntityId,
|
||||
pub(crate) entity_type: PhantomData<T>,
|
||||
pub(crate) ref_counts: Weak<RwLock<RefCounts>>,
|
||||
}
|
||||
|
||||
impl<T: Send + Sync + 'static> WeakHandle<T> {
|
||||
pub fn upgrade(&self, _: &impl Context) -> Option<Handle<T>> {
|
||||
// todo!("Actually upgrade")
|
||||
let ref_counts = self.ref_counts.upgrade()?;
|
||||
ref_counts.read().get(self.id).unwrap().fetch_add(1, SeqCst);
|
||||
Some(Handle {
|
||||
id: self.id,
|
||||
entity_type: self.entity_type,
|
||||
ref_counts: self.ref_counts.clone(),
|
||||
})
|
||||
}
|
||||
|
@ -35,10 +35,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
|
||||
// }
|
||||
|
||||
pub fn handle(&self) -> WeakHandle<T> {
|
||||
WeakHandle {
|
||||
id: self.entity_id,
|
||||
entity_type: PhantomData,
|
||||
}
|
||||
self.app.entities.weak_handle(self.entity_id)
|
||||
}
|
||||
|
||||
pub fn observe<E: Send + Sync + 'static>(
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
};
|
||||
use std::{any::Any, marker::PhantomData, sync::Arc};
|
||||
|
||||
pub struct View<S, P> {
|
||||
pub struct View<S: Send + Sync, P> {
|
||||
state: Handle<S>,
|
||||
render: Arc<dyn Fn(&mut S, &mut ViewContext<S>) -> AnyElement<S> + Send + Sync + 'static>,
|
||||
parent_state_type: PhantomData<P>,
|
||||
@ -21,7 +21,7 @@ impl<S: 'static + Send + Sync, P: 'static + Send> View<S, P> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P> Clone for View<S, P> {
|
||||
impl<S: Send + Sync, P> Clone for View<S, P> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
state: self.state.clone(),
|
||||
@ -33,10 +33,15 @@ impl<S, P> Clone for View<S, P> {
|
||||
|
||||
pub type RootView<S> = View<S, ()>;
|
||||
|
||||
pub fn view<S: 'static, P: 'static, E: Element<State = S>>(
|
||||
pub fn view<S, P, E>(
|
||||
state: Handle<S>,
|
||||
render: impl Fn(&mut S, &mut ViewContext<S>) -> E + Send + Sync + 'static,
|
||||
) -> View<S, P> {
|
||||
) -> View<S, P>
|
||||
where
|
||||
S: 'static + Send + Sync,
|
||||
P: 'static,
|
||||
E: Element<State = S>,
|
||||
{
|
||||
View {
|
||||
state,
|
||||
render: Arc::new(move |state, cx| render(state, cx).into_any()),
|
||||
|
@ -275,10 +275,7 @@ impl<'a, 'w, T: Send + Sync + 'static> ViewContext<'a, 'w, T> {
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> WeakHandle<T> {
|
||||
WeakHandle {
|
||||
id: self.entity_id,
|
||||
entity_type: PhantomData,
|
||||
}
|
||||
self.entities.weak_handle(self.entity_id)
|
||||
}
|
||||
|
||||
pub fn observe<E: Send + Sync + 'static>(
|
||||
|
Loading…
Reference in New Issue
Block a user