Skip to content

Commit

Permalink
Replace ouroboros with parking_lot
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Jan 2, 2024
1 parent 68bbcc9 commit 53846dd
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 34 deletions.
3 changes: 0 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion cursive-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion cursive-core/src/cursive_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ impl Cursive {
///
/// // Could be called in a callback
/// let mut view: ViewRef<TextView> = 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
Expand Down
43 changes: 14 additions & 29 deletions cursive-core/src/views/named_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand All @@ -20,30 +20,20 @@ pub struct NamedView<V> {
/// This behaves like a [`MutexGuard`], but without being tied to a lifetime.
///
/// [`MutexGuard`]: std::sync::MutexGuard
//pub type ViewRef<V> = OwningHandle<ArcRef<Mutex<V>>, MutexGuard<'static, V>>;
#[self_referencing]
pub struct ViewRef<V: 'static> {
owner: Arc<Mutex<V>>,

#[borrows(owner)]
#[covariant]
guard: MutexGuard<'this, V>,
guard: parking_lot::lock_api::ArcMutexGuard<parking_lot::RawMutex, V>,
}

impl<V> std::ops::Deref for ViewRef<V> {
type Target = V;
fn deref(&self) -> &Self::Target {
self.borrow_guard()
self.guard.deref()
}
}

impl<V> ViewRef<V> {
/// Run the given closure on the targetted view.
pub fn run<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut V) -> R,
{
self.with_guard_mut(|guard| f(guard))
impl<V> std::ops::DerefMut for ViewRef<V> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.guard.deref_mut()
}
}

Expand All @@ -58,20 +48,15 @@ impl<V> NamedView<V> {

/// Gets mutable access to the inner view.
///
/// This returns a `ViewRef<V>`, which implement `Deref<Target = V>` for read-only accesses,
/// and [`ViewRef::run()`] for mutable access.
/// This returns a `ViewRef<V>`, which implement `DerefMut<Target = V>`.
///
/// # Panics
///
/// Panics if another reference for this view already exists.
pub fn get_mut(&mut self) -> ViewRef<V> {
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.
Expand All @@ -92,14 +77,14 @@ impl<T: View + 'static> ViewWrapper for NamedView<T> {
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<F, R>(&mut self, f: F) -> Option<R>
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<Self::V, Self>
Expand All @@ -112,7 +97,7 @@ impl<T: View + 'static> ViewWrapper for NamedView<T> {
self.view = rc;
Err(self)
}
Ok(cell) => Ok(cell.into_inner().unwrap()),
Ok(cell) => Ok(cell.into_inner()),
}
}

Expand All @@ -131,7 +116,7 @@ impl<T: View + 'static> ViewWrapper for NamedView<T> {
s => self
.view
.try_lock()
.map_err(|_| ViewNotFound)
.ok_or(ViewNotFound)
.and_then(|mut v| v.focus_view(s)),
}
}
Expand Down

0 comments on commit 53846dd

Please sign in to comment.