Scope

Struct Scope 

Source
pub struct Scope<'scope, 'env: 'scope> { /* private fields */ }
Expand description

A scope for event handlers with shorter than 'static lifetime.

Scopes are created by calling Queue::dispatch_scope_blocking and Queue::dispatch_scope_async.

Event handlers attached via a scope have the following, additional restriction: they will be dropped and therefore not be invoked after the lifetime of the scope has ended. The proxies can still be used to send requests or as arguments, but no event callbacks will be invoked. Instead, the OwnedProxy::NO_OP_EVENT_HANDLER will be invoked to prevent any memory leaks.

Async scopes created via Queue::dispatch_scope_async have one more restriction: event handlers will only be invoked while the returned future is being polled. Until the future completes, the queue should therefore only be dispatched from inside the future.

§Example

let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"queue name");

let sync = queue.display::<WlDisplay>().sync();
let done = Cell::new(false);
queue.dispatch_scope_blocking(|scope| {
    scope.set_event_handler_local(&sync, WlCallback::on_done(|_, _| done.set(true)));
    queue.dispatch_roundtrip_blocking().unwrap();
});
assert!(done.get());

Implementations§

Source§

impl<'scope> Scope<'scope, '_>

Source

pub fn set_event_handler<P, H>(&'scope self, proxy: &P, handler: H)
where P: OwnedProxy, P::Api: CreateEventHandler<H>, <P::Api as CreateEventHandler<H>>::EventHandler: Send + 'scope,

Sets the event handler of the proxy.

This function is the same as proxy::set_event_handler except that the event handler does not have to implement 'static and that the event handler will not be invoked after 'scope.

The proxy must belong to the queue that was used to create this scope.

§Panic

This function panics whenever proxy::set_event_handler panics and also if the proxy does not belong to the queue that was used to create this scope.

§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let display: WlDisplay = queue.display();
let sync = display.sync();
let done = AtomicBool::new(false);

queue.dispatch_scope_blocking(|scope| {
    // Attach the event handler.
    scope.set_event_handler(&sync, WlCallback::on_done(|_, _| done.store(true, Relaxed)));

    // Wait for the compositor to send the `done` message.
    queue.dispatch_roundtrip_blocking().unwrap();
});

// The event handler sets the value to `true`.
assert!(done.load(Relaxed));
Examples found in repository?
examples/async-roundtrip/../common/singletons.rs (lines 63-68)
56pub fn get_singletons(display: &WlDisplay) -> Singletons {
57    let map = Mutex::new(HashMap::new());
58
59    let queue = proxy::queue(display);
60    let wl_registry = display.get_registry();
61
62    queue.dispatch_scope_blocking(|scope| {
63        scope.set_event_handler(
64            &wl_registry,
65            WlRegistry::on_global(|_, name, interface, version| {
66                map.lock().insert(interface.to_owned(), (name, version));
67            }),
68        );
69        queue.dispatch_roundtrip_blocking().unwrap();
70    });
71
72    Singletons {
73        wl_registry,
74        map: map.into_inner(),
75    }
76}
77
78pub async fn get_singletons_async(display: &WlDisplay) -> Singletons {
79    let map = Mutex::new(HashMap::new());
80
81    let queue = proxy::queue(display);
82    let wl_registry = display.get_registry();
83
84    queue
85        .dispatch_scope_async(async |scope| {
86            scope.set_event_handler(
87                &wl_registry,
88                WlRegistry::on_global(|_, name, interface, version| {
89                    map.lock().insert(interface.to_owned(), (name, version));
90                }),
91            );
92            queue.dispatch_roundtrip_async().await.unwrap();
93        })
94        .await;
95
96    Singletons {
97        wl_registry,
98        map: map.into_inner(),
99    }
100}
More examples
Hide additional examples
examples/get-registry/main.rs (lines 36-48)
27fn get_registry_snapshot(queue: &Queue) -> (WlRegistry, Vec<Global>) {
28    // Create a new registry that will receive the globals and can later be used to
29    // bind them.
30    let registry = queue.display::<WlDisplay>().get_registry();
31    let globals = Mutex::new(vec![]);
32    // Since we don't care about registry events after this function returns, we can
33    // use a dispatch scope. The event handlers in this scope will not be called after
34    // the function returns.
35    queue.dispatch_scope_blocking(|scope| {
36        scope.set_event_handler(
37            &registry,
38            // Since we only want to create a snapshot, we don't care about
39            // global_remove events. This allows us to use the functional event handler
40            // form.
41            WlRegistry::on_global(|_, name, interface, version| {
42                globals.lock().push(Global {
43                    name,
44                    interface: interface.to_string(),
45                    version,
46                });
47            }),
48        );
49        queue.dispatch_roundtrip_blocking().unwrap();
50    });
51    // The event handler will no longer be called after this function returns but
52    // the registry can still be used to bind globals.
53    (registry, globals.into_inner())
54}
Source

pub fn set_event_handler_local<P, H>(&'scope self, proxy: &P, handler: H)
where P: OwnedProxy, P::Api: CreateEventHandler<H>, <P::Api as CreateEventHandler<H>>::EventHandler: 'scope,

Sets the !Send event handler of the proxy.

This function is the same as proxy::set_event_handler_local except that the event handler does not have to implement 'static and that the event handler will not be invoked after 'scope.

The proxy must belong to the queue that was used to create this scope.

§Panic

This function panics whenever proxy::set_event_handler_local panics and also if the proxy does not belong to the queue that was used to create this scope.

§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"queue name");
let display: WlDisplay = queue.display();
let sync = display.sync();
let done = Cell::new(false);

queue.dispatch_scope_blocking(|scope| {
    // Attach the event handler.
    scope.set_event_handler_local(&sync, WlCallback::on_done(|_, _| done.set(true)));

    // Wait for the compositor to send the `done` message.
    queue.dispatch_roundtrip_blocking().unwrap();
});

// The event handler sets the value to `true`.
assert!(done.get());
Examples found in repository?
examples/async-roundtrip/main.rs (lines 19-24)
11async fn main() {
12    let lib = Libwayland::open().unwrap();
13    let con = lib.connect_to_default_display().unwrap();
14    let queue = con.create_local_queue(c"async-roundtrip");
15    let registry = queue.display::<WlDisplay>().get_registry();
16    let num_globals = Cell::new(0);
17    queue
18        .dispatch_scope_async(async |scope| {
19            scope.set_event_handler_local(
20                &registry,
21                WlRegistry::on_global(|_, _, _, _| {
22                    num_globals.set(num_globals.get() + 1);
23                }),
24            );
25            // This function can be used to perform an async roundtrip. It is
26            // compatible with any async runtime. This example also demonstrates
27            // that this works in combination with scoped event handlers.
28            queue.dispatch_roundtrip_async().await.unwrap();
29        })
30        .await;
31    println!("number of globals: {}", num_globals.get());
32}

Auto Trait Implementations§

§

impl<'scope, 'env> Freeze for Scope<'scope, 'env>

§

impl<'scope, 'env> !RefUnwindSafe for Scope<'scope, 'env>

§

impl<'scope, 'env> Send for Scope<'scope, 'env>

§

impl<'scope, 'env> Sync for Scope<'scope, 'env>

§

impl<'scope, 'env> Unpin for Scope<'scope, 'env>

§

impl<'scope, 'env> !UnwindSafe for Scope<'scope, 'env>

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> 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.