Pass

Struct Pass 

Source
pub struct Pass(/* private fields */);
Expand description

A key for reading/writing to RwData

This key is necessary in order to prevent breakage of the number one rule of Rust: any number of shared references, or one exclusive reference.

When you call RwData::read, any call to RwData::write may end up breaking this rule, and vice-versa, which is why this struct is necessary.

One downside of this approach is that it is even more restrictive than Rust’s rule of thumb, since that one is enforced on individual instances, while this one is enforced on all RwDatas. This (as far as i know) cannot be circumvented, as a more advanced compile time checker (that distinguishes RwData<T>s of different Ts, for example) does not seem feasible without the use of unfinished features, which I am not willing to use.

Implementations§

Source§

impl Pass

Source

pub fn write_many<'p, Tup: WriteableTuple<'p, impl Any>>( &'p mut self, tup: Tup, ) -> Tup::Return

Writes to many RwData-like structs at once

This function accepts tuples (or a single element) of references to types that implement the [WriteableData] trait, which is one of the following:

Here’s an example, which writes to two RwDatas at the same time as a Handle:

use duat::{data::RwData, prelude::*};
setup_duat!(setup);

fn setup() {
    let (num1, num2) = (RwData::new(0), RwData::new(0));
    hook::add::<BufferOpened>(move |pa, handle: &Handle| {
        let (num1, num2, buf) = pa.write_many((&num1, &num2, handle));
        // Rest of the function writes to all of them at the same time.
    });
}

This allows for much more flexibility when writing to global state, which should hopefully lead to more streamlined functions

§Panics

This function will panic if any of the elements of the tuple point to the same data as any other element, for example, with the earlier code snippet:

use duat::{data::RwData, prelude::*};
setup_duat!(setup);

fn setup() {
    let num1 = RwData::new(0);
    // num2 is now a clone of num1
    let num2 = num1.clone();
    hook::add::<BufferOpened>(move |pa, handle: &Handle| {
        let (num1, num2, buf) = pa.write_many((&num1, &num2, handle));
        // Rest of the function writes to all of them at the same time.
    });
}

Since num1 and num2 point to the same data, you’d be getting two &mut i32 for the same variable, which violates rust’s “mutability xor aliasing” rule. This is why this will panic. If you want a non-panicking version of this function, check out Pass::try_write_many, which returns a Result instead.

Source

pub fn try_write_many<'p, Tup: WriteableTuple<'p, impl Any>>( &'p mut self, tup: Tup, ) -> Result<Tup::Return, Text>

Tries writing to many RwData-like structs at once

This function accepts tuples (or a single element) of references to types that implement the [WriteableData] trait, which is one of the following:

This function works exactly like Pass::write_many, however, instead of panicking, this function returns a Result, returning an Err if any of the tuple’s elements point to the same data as any of the other elements.

Auto Trait Implementations§

§

impl Freeze for Pass

§

impl RefUnwindSafe for Pass

§

impl Send for Pass

§

impl Sync for Pass

§

impl Unpin for Pass

§

impl UnwindSafe for Pass

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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
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, 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.