diff --git a/CHANGELOG.md b/CHANGELOG.md index b1bf90c4..3fa51fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,6 @@ ### Breaking Changes -- `ViewRef` (as returned by `Cursive::find_name`) no longer implements `DerefMut`. - You will need to call `.run(|v| foo(v))` to get mutable access. - This is caused by the switch from `owning_ref` to `ouroboros`, which currently does not support this. - The `View` now requires `Send + Sync`, to allow accessing or moving views between threads. This prevents using `Rc`/`RefCell`, and may require using `Arc`/`Mutex` instead. This should eventually open the way for more multi-threaded processing of the view tree. diff --git a/cursive-core/Cargo.toml b/cursive-core/Cargo.toml index 5df38dc7..d80079e0 100644 --- a/cursive-core/Cargo.toml +++ b/cursive-core/Cargo.toml @@ -34,7 +34,7 @@ lazy_static = "1" ahash = "0.8" serde_json = "1.0.85" serde_yaml = "0.9.11" -ouroboros = "0.18.0" +parking_lot = { version = "0.12.1", features = ["arc_lock"] } [dependencies.cursive-macros] path = "../cursive-macros" diff --git a/cursive-core/src/cursive_root.rs b/cursive-core/src/cursive_root.rs index 0d882220..b6d5d85a 100644 --- a/cursive-core/src/cursive_root.rs +++ b/cursive-core/src/cursive_root.rs @@ -567,7 +567,7 @@ impl Cursive { /// /// // Could be called in a callback /// let mut view: ViewRef = siv.find_name("id").unwrap(); - /// view.run(|v| v.set_content("bar")); + /// view.set_content("bar"); /// ``` /// /// Note that you must specify the exact type for the view you're after; for example, using the diff --git a/cursive-core/src/views/named_view.rs b/cursive-core/src/views/named_view.rs index e251988a..ab3eb507 100644 --- a/cursive-core/src/views/named_view.rs +++ b/cursive-core/src/views/named_view.rs @@ -2,8 +2,8 @@ use crate::{ event::{AnyCb, EventResult}, view::{Selector, View, ViewNotFound, ViewWrapper}, }; -use ouroboros::self_referencing; -use std::sync::{Arc, Mutex, MutexGuard}; +use parking_lot::Mutex; +use std::sync::Arc; /// Wrapper around a view to make it identifiable. /// @@ -20,30 +20,20 @@ pub struct NamedView { /// This behaves like a [`MutexGuard`], but without being tied to a lifetime. /// /// [`MutexGuard`]: std::sync::MutexGuard -//pub type ViewRef = OwningHandle>, MutexGuard<'static, V>>; -#[self_referencing] pub struct ViewRef { - owner: Arc>, - - #[borrows(owner)] - #[covariant] - guard: MutexGuard<'this, V>, + guard: parking_lot::lock_api::ArcMutexGuard, } impl std::ops::Deref for ViewRef { type Target = V; fn deref(&self) -> &Self::Target { - self.borrow_guard() + self.guard.deref() } } -impl ViewRef { - /// Run the given closure on the targetted view. - pub fn run(&mut self, f: F) -> R - where - F: FnOnce(&mut V) -> R, - { - self.with_guard_mut(|guard| f(guard)) +impl std::ops::DerefMut for ViewRef { + fn deref_mut(&mut self) -> &mut Self::Target { + self.guard.deref_mut() } } @@ -58,20 +48,15 @@ impl NamedView { /// Gets mutable access to the inner view. /// - /// This returns a `ViewRef`, which implement `Deref` for read-only accesses, - /// and [`ViewRef::run()`] for mutable access. + /// This returns a `ViewRef`, which implement `DerefMut`. /// /// # Panics /// /// Panics if another reference for this view already exists. pub fn get_mut(&mut self) -> ViewRef { - let owner = Arc::clone(&self.view); + let guard = self.view.lock_arc(); - ViewRefBuilder { - owner, - guard_builder: |owner| owner.lock().unwrap(), - } - .build() + ViewRef { guard } } /// Returns the name attached to this view. @@ -92,14 +77,14 @@ impl ViewWrapper for NamedView { where F: FnOnce(&Self::V) -> R, { - self.view.try_lock().ok().map(|v| f(&*v)) + self.view.try_lock().map(|v| f(&*v)) } fn with_view_mut(&mut self, f: F) -> Option where F: FnOnce(&mut Self::V) -> R, { - self.view.try_lock().ok().map(|mut v| f(&mut *v)) + self.view.try_lock().map(|mut v| f(&mut *v)) } fn into_inner(mut self) -> Result @@ -112,7 +97,7 @@ impl ViewWrapper for NamedView { self.view = rc; Err(self) } - Ok(cell) => Ok(cell.into_inner().unwrap()), + Ok(cell) => Ok(cell.into_inner()), } } @@ -131,7 +116,7 @@ impl ViewWrapper for NamedView { s => self .view .try_lock() - .map_err(|_| ViewNotFound) + .ok_or(ViewNotFound) .and_then(|mut v| v.focus_view(s)), } }