|
1 |
| -#[cfg(feature = "async-tokio")] |
2 |
| -extern crate futures; |
3 |
| -#[cfg(feature = "async-tokio")] |
4 |
| -extern crate sysfs_gpio; |
5 |
| -#[cfg(feature = "async-tokio")] |
6 |
| -extern crate tokio; |
| 1 | +// Copyright (c) 2020. The sysfs-gpio Authors. |
7 | 2 |
|
8 |
| -#[cfg(feature = "async-tokio")] |
| 3 | +use futures::future::join_all; |
| 4 | +use futures::StreamExt; |
9 | 5 | use std::env;
|
10 |
| - |
11 |
| -#[cfg(feature = "async-tokio")] |
12 |
| -use futures::{lazy, Future, Stream}; |
13 |
| - |
14 |
| -#[cfg(feature = "async-tokio")] |
15 | 6 | use sysfs_gpio::{Direction, Edge, Pin};
|
16 | 7 |
|
17 |
| -#[cfg(feature = "async-tokio")] |
18 |
| -fn stream(pin_nums: Vec<u64>) -> sysfs_gpio::Result<()> { |
| 8 | +async fn monitor_pin(pin: Pin) -> Result<(), sysfs_gpio::Error> { |
| 9 | + pin.export()?; |
| 10 | + pin.set_direction(Direction::In)?; |
| 11 | + pin.set_edge(Edge::BothEdges)?; |
| 12 | + let mut gpio_events = pin.get_value_stream()?; |
| 13 | + while let Some(evt) = gpio_events.next().await { |
| 14 | + let val = evt.unwrap(); |
| 15 | + println!("Pin {} changed value to {}", pin.get_pin_num(), val); |
| 16 | + } |
| 17 | + Ok(()) |
| 18 | +} |
| 19 | + |
| 20 | +async fn stream(pin_nums: Vec<u64>) { |
19 | 21 | // NOTE: this currently runs forever and as such if
|
20 | 22 | // the app is stopped (Ctrl-C), no cleanup will happen
|
21 | 23 | // and the GPIO will be left exported. Not much
|
22 | 24 | // can be done about this as Rust signal handling isn't
|
23 | 25 | // really present at the moment. Revisit later.
|
24 |
| - let pins: Vec<_> = pin_nums.iter().map(|&p| (p, Pin::new(p))).collect(); |
25 |
| - let task = lazy(move || { |
26 |
| - for &(i, ref pin) in pins.iter() { |
27 |
| - pin.export().unwrap(); |
28 |
| - pin.set_direction(Direction::In).unwrap(); |
29 |
| - pin.set_edge(Edge::BothEdges).unwrap(); |
30 |
| - tokio::spawn( |
31 |
| - pin.get_value_stream() |
32 |
| - .unwrap() |
33 |
| - .for_each(move |val| { |
34 |
| - println!("Pin {} changed value to {}", i, val); |
35 |
| - Ok(()) |
36 |
| - }) |
37 |
| - .map_err(|_| ()), |
38 |
| - ); |
39 |
| - } |
40 |
| - Ok(()) |
41 |
| - }); |
42 |
| - tokio::run(task); |
43 |
| - |
44 |
| - Ok(()) |
| 26 | + join_all(pin_nums.into_iter().map(|p| { |
| 27 | + let pin = Pin::new(p); |
| 28 | + tokio::task::spawn(monitor_pin(pin)) |
| 29 | + })) |
| 30 | + .await; |
45 | 31 | }
|
46 | 32 |
|
47 |
| -#[cfg(feature = "async-tokio")] |
48 |
| -fn main() { |
| 33 | +#[tokio::main] |
| 34 | +async fn main() { |
49 | 35 | let pins: Vec<u64> = env::args()
|
50 | 36 | .skip(1)
|
51 | 37 | .map(|a| a.parse().expect("Pins must be specified as integers"))
|
52 | 38 | .collect();
|
53 | 39 | if pins.is_empty() {
|
54 | 40 | println!("Usage: ./tokio <pin> [pin ...]");
|
55 | 41 | } else {
|
56 |
| - stream(pins).unwrap(); |
| 42 | + stream(pins).await; |
57 | 43 | }
|
58 | 44 | }
|
59 |
| - |
60 |
| -#[cfg(not(feature = "async-tokio"))] |
61 |
| -fn main() { |
62 |
| - println!("This example requires the `tokio` feature to be enabled."); |
63 |
| -} |
0 commit comments