-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AsyncChannelSource and AsyncChannelSink (#12)
feat(blocks): AsyncChannel Source and sink
- Loading branch information
1 parent
7c688e2
commit 0d86666
Showing
24 changed files
with
298 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
.idea | ||
.vscode | ||
config.toml | ||
/target | ||
/Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use async_channel::Sender; | ||
|
||
use futuresdr::anyhow::Result; | ||
use futuresdr::log::info; | ||
use futuresdr::runtime::Block; | ||
use futuresdr::runtime::BlockMeta; | ||
use futuresdr::runtime::BlockMetaBuilder; | ||
use futuresdr::runtime::Kernel; | ||
use futuresdr::runtime::MessageIo; | ||
use futuresdr::runtime::MessageIoBuilder; | ||
use futuresdr::runtime::StreamIo; | ||
use futuresdr::runtime::StreamIoBuilder; | ||
use futuresdr::runtime::WorkIo; | ||
|
||
/// Get samples out of a Flowgraph into a channel. | ||
/// | ||
/// # Inputs | ||
/// | ||
/// `in`: Samples retrieved from teh flowgraph | ||
/// | ||
/// # Usage | ||
/// ``` | ||
/// use async_channel; | ||
/// use futuresdr::blocks::VectorSource; | ||
/// use fsdr-blocks::blocks::AsyncChannelSink | ||
/// use futuresdr::runtime::Flowgraph; | ||
/// | ||
/// let mut fg = Flowgraph::new(); | ||
/// let (tx, rx) = async_channel::unbounded::<Box<[u32]>>(); | ||
/// let vec = vec![0, 1, 2]; | ||
/// let src = fg.add_block(VectorSource::<u32>::new(vec)); | ||
/// let cs = fg.add_block(AsyncChannelSink::<u32>::new(tx)); | ||
/// // start flowgraph | ||
/// ``` | ||
pub struct AsyncChannelSink<T: Send + 'static> { | ||
sender: Sender<Box<[T]>>, | ||
} | ||
|
||
impl<T: Send + Clone + 'static> AsyncChannelSink<T> { | ||
#[allow(clippy::new_ret_no_self)] | ||
pub fn new(sender: Sender<Box<[T]>>) -> Block { | ||
Block::new( | ||
BlockMetaBuilder::new("AsyncChannelSink").build(), | ||
StreamIoBuilder::new().add_input::<T>("in").build(), | ||
MessageIoBuilder::new().build(), | ||
AsyncChannelSink::<T> { sender }, | ||
) | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
#[async_trait] | ||
impl<T: Send + Clone + 'static> Kernel for AsyncChannelSink<T> { | ||
async fn work( | ||
&mut self, | ||
io: &mut WorkIo, | ||
sio: &mut StreamIo, | ||
_mio: &mut MessageIo<Self>, | ||
_meta: &mut BlockMeta, | ||
) -> Result<()> { | ||
let i = sio.input(0).slice::<T>(); | ||
|
||
if !i.is_empty() { | ||
match self.sender.try_send(i.into()) { | ||
Ok(_) => { | ||
info!("sent data..."); | ||
} | ||
Err(err) => { | ||
info!("{}", err.to_string()); | ||
} | ||
} | ||
sio.input(0).consume(i.len()); | ||
} | ||
|
||
if sio.input(0).finished() { | ||
io.finished = true; | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use async_channel::Receiver; | ||
use futuresdr::futures::StreamExt; | ||
|
||
use futuresdr::anyhow::Result; | ||
use futuresdr::log::info; | ||
use futuresdr::runtime::Block; | ||
use futuresdr::runtime::BlockMeta; | ||
use futuresdr::runtime::BlockMetaBuilder; | ||
use futuresdr::runtime::Kernel; | ||
use futuresdr::runtime::MessageIo; | ||
use futuresdr::runtime::MessageIoBuilder; | ||
use futuresdr::runtime::StreamIo; | ||
use futuresdr::runtime::StreamIoBuilder; | ||
use futuresdr::runtime::WorkIo; | ||
|
||
/// Push samples through a channel into a stream connection. | ||
/// | ||
/// # Outputs | ||
/// | ||
/// `out`: Samples pushed into the channel | ||
/// | ||
/// # Usage | ||
/// ``` | ||
/// use async_channel; | ||
/// use fsdr-blocks::blocks::AsyncChannelSource; | ||
/// use futuresdr::runtime::Flowgraph; | ||
/// | ||
/// let mut fg = Flowgraph::new(); | ||
/// let (tx, rx) = async_channel::unbounded::<Box<[u32]>>(); | ||
/// | ||
/// let async_channel_src = fg.add_block(AsyncChannelSource::<u32>::new(rx)); | ||
/// | ||
/// tx.send(orig.clone().into_boxed_slice()).await.unwrap(); | ||
/// ``` | ||
pub struct AsyncChannelSource<T: Send + 'static> { | ||
receiver: Receiver<Box<[T]>>, | ||
current: Option<(Box<[T]>, usize)>, | ||
} | ||
|
||
impl<T: Send + 'static> AsyncChannelSource<T> { | ||
#[allow(clippy::new_ret_no_self)] | ||
pub fn new(receiver: Receiver<Box<[T]>>) -> Block { | ||
Block::new( | ||
BlockMetaBuilder::new("AsyncChannelSource").build(), | ||
StreamIoBuilder::new().add_output::<T>("out").build(), | ||
MessageIoBuilder::new().build(), | ||
AsyncChannelSource::<T> { | ||
receiver, | ||
current: None, | ||
}, | ||
) | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
#[async_trait] | ||
impl<T: Send + 'static> Kernel for AsyncChannelSource<T> { | ||
async fn work( | ||
&mut self, | ||
io: &mut WorkIo, | ||
sio: &mut StreamIo, | ||
_mio: &mut MessageIo<Self>, | ||
_meta: &mut BlockMeta, | ||
) -> Result<()> { | ||
let out = sio.output(0).slice::<T>(); | ||
if out.is_empty() { | ||
return Ok(()); | ||
} | ||
|
||
if self.current.is_none() { | ||
match self.receiver.by_ref().recv().await { | ||
//.by_ref().next().await | ||
Ok(data) => { | ||
info!("received data chunk on channel"); | ||
self.current = Some((data, 0)); | ||
} | ||
Err(_err) => { | ||
info!("sender-end of channel was closed"); | ||
io.finished = true; | ||
return Ok(()); | ||
} | ||
} | ||
} | ||
|
||
if let Some((data, index)) = &mut self.current { | ||
let n = std::cmp::min(data.len() - *index, out.len()); | ||
unsafe { | ||
std::ptr::copy_nonoverlapping(data.as_ptr().add(*index), out.as_mut_ptr(), n); | ||
}; | ||
sio.output(0).produce(n); | ||
*index += n; | ||
if *index == data.len() { | ||
self.current = None; | ||
} | ||
} | ||
|
||
if self.current.is_none() { | ||
io.call_again = true; | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
//! ## Blocks related to channels | ||
mod async_channel_sink; | ||
mod async_channel_source; | ||
|
||
pub use async_channel_sink::AsyncChannelSink; | ||
pub use async_channel_source::AsyncChannelSource; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
use std; | ||
use std::fmt::{self, Display}; | ||
|
||
use serde::{de, ser}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.