SharedContext

Struct SharedContext 

Source
pub struct SharedContext<S>
where S: UiBindable + Send + Sync + 'static,
{ /* private fields */ }
Expand description

Thread-safe shared state container.

SharedContext wraps user-defined shared state in an Arc<RwLock<S>>, enabling safe concurrent access from multiple views. Each view receives a cloned reference to the same underlying state.

§Type Parameters

  • S - The shared state type. Must implement:
    • UiBindable for XML binding access (e.g., {shared.field})
    • Send + Sync for thread safety
    • 'static for Arc storage

§Example

use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default, Clone)]
struct SharedState {
    theme: String,
    user_name: Option<String>,
}

impl UiBindable for SharedState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["theme"] => Some(BindingValue::String(self.theme.clone())),
            ["user_name"] => match &self.user_name {
                Some(name) => Some(BindingValue::String(name.clone())),
                None => Some(BindingValue::None),
            },
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> {
        vec!["theme".to_string(), "user_name".to_string()]
    }
}

let ctx = SharedContext::new(SharedState::default());
let ctx2 = ctx.clone(); // Same underlying state

ctx.write().theme = "dark".to_string();
assert_eq!(ctx2.read().theme, "dark");

§Lock Poisoning

If a thread panics while holding a write lock, the lock becomes “poisoned”. The read() and write() methods will panic in this case. Use try_read() and try_write() for fallible access.

Implementations§

Source§

impl<S> SharedContext<S>
where S: UiBindable + Send + Sync + 'static,

Source

pub fn new(initial: S) -> Self

Create a new SharedContext with initial state.

§Arguments
  • initial - The initial shared state value
§Example
use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default)]
struct MyState { counter: i32 }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["counter"] => Some(BindingValue::Integer(self.counter as i64)),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["counter".to_string()] }
}

let ctx = SharedContext::new(MyState { counter: 42 });
assert_eq!(ctx.read().counter, 42);
Source

pub fn read(&self) -> RwLockReadGuard<'_, S>

Acquire read access to shared state.

Returns a guard that provides immutable access to the shared state. Multiple readers can hold guards simultaneously.

§Panics

Panics if the lock is poisoned (a thread panicked while holding write lock). Use try_read for fallible access.

§Example
use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default)]
struct MyState { value: String }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["value"] => Some(BindingValue::String(self.value.clone())),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["value".to_string()] }
}

let ctx = SharedContext::new(MyState { value: "hello".to_string() });
let guard = ctx.read();
assert_eq!(guard.value, "hello");
Source

pub fn write(&self) -> RwLockWriteGuard<'_, S>

Acquire write access to shared state.

Returns a guard that provides mutable access to the shared state. Only one writer can hold the guard at a time, and no readers can access the state while a write guard is held.

§Panics

Panics if the lock is poisoned. Use try_write for fallible access.

§Example
use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default)]
struct MyState { counter: i32 }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["counter"] => Some(BindingValue::Integer(self.counter as i64)),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["counter".to_string()] }
}

let ctx = SharedContext::new(MyState { counter: 0 });
ctx.write().counter += 1;
assert_eq!(ctx.read().counter, 1);
Source

pub fn try_read(&self) -> Option<RwLockReadGuard<'_, S>>

Try to acquire read access without blocking.

Returns None if the lock is currently held for writing or is poisoned. This is useful when you want to avoid blocking on a potentially long-held write lock.

§Example
use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default)]
struct MyState { value: i32 }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["value"] => Some(BindingValue::Integer(self.value as i64)),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["value".to_string()] }
}

let ctx = SharedContext::new(MyState { value: 42 });
if let Some(guard) = ctx.try_read() {
    assert_eq!(guard.value, 42);
}
Source

pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, S>>

Try to acquire write access without blocking.

Returns None if the lock is currently held (for reading or writing) or is poisoned.

§Example
use dampen_core::SharedContext;
use dampen_core::{UiBindable, BindingValue};

#[derive(Default)]
struct MyState { value: i32 }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["value"] => Some(BindingValue::Integer(self.value as i64)),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["value".to_string()] }
}

let ctx = SharedContext::new(MyState { value: 0 });
if let Some(mut guard) = ctx.try_write() {
    guard.value = 100;
}
Source§

impl SharedContext<()>

Special implementation for unit type when shared state is not used.

This allows applications that don’t use shared state to still compile without requiring a real shared state type.

Source

pub fn empty() -> Self

Create an empty shared context (no-op).

Used internally when an application doesn’t configure shared state. The resulting context holds unit type () and is essentially a no-op.

§Example
use dampen_core::SharedContext;

let ctx = SharedContext::<()>::empty();
// Can still call read/write, but they just return ()
let _guard = ctx.read();

Trait Implementations§

Source§

impl<S> Clone for SharedContext<S>
where S: UiBindable + Send + Sync + 'static,

Source§

fn clone(&self) -> Self

Clone the SharedContext.

This creates a new SharedContext that references the same underlying state. Modifications through one clone are visible to all others.

1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S> Debug for SharedContext<S>
where S: UiBindable + Send + Sync + 'static + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S> UiBindable for SharedContext<S>
where S: UiBindable + Send + Sync + 'static,

Implement UiBindable for SharedContext by delegating to the inner state.

This allows SharedContext to be used directly in widget builders and bindings without needing to extract the inner state first.

§Example

use dampen_core::{SharedContext, UiBindable, BindingValue};

#[derive(Default)]
struct MyState { value: i32 }

impl UiBindable for MyState {
    fn get_field(&self, path: &[&str]) -> Option<BindingValue> {
        match path {
            ["value"] => Some(BindingValue::Integer(self.value as i64)),
            _ => None,
        }
    }
    fn available_fields() -> Vec<String> { vec!["value".to_string()] }
}

let ctx = SharedContext::new(MyState { value: 42 });
// Can use ctx directly as &dyn UiBindable
assert_eq!(ctx.get_field(&["value"]), Some(BindingValue::Integer(42)));
Source§

fn get_field(&self, path: &[&str]) -> Option<BindingValue>

Get a field value by path Read more
Source§

fn available_fields() -> Vec<String>

List available field paths for error suggestions Read more

Auto Trait Implementations§

§

impl<S> Freeze for SharedContext<S>

§

impl<S> RefUnwindSafe for SharedContext<S>

§

impl<S> Send for SharedContext<S>

§

impl<S> Sync for SharedContext<S>

§

impl<S> Unpin for SharedContext<S>

§

impl<S> UnwindSafe for SharedContext<S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.