diff --git a/oxydsp-flowgraph/src/tag.rs b/oxydsp-flowgraph/src/tag.rs index a334b7e..cb261aa 100644 --- a/oxydsp-flowgraph/src/tag.rs +++ b/oxydsp-flowgraph/src/tag.rs @@ -1,10 +1,74 @@ +/// A tag is an amount of data you can "attach" to a particular sample in stream. +/// Indeed you might need to mark sample, or bring information along with them sparsely : +/// Tags are often a rare occurence. +/// +/// Example : +/// +/// Timing error detection : A sample is the center of a symbol +/// There might be a Tag : +/// +/// ted_symbol_center: 0.011 (Here the number might represent a error value) +/// +/// But really, any kind of data could be referenced by a tag : +/// A float, A string like a json structure, or even a binary blob. +/// +/// A tag is formed that way : +/// +/// The TagKey : +/// | A unique key allocated at the begining, +/// | Which is tied to a human readable label configured +/// | ahead of runtime. +/// | +/// | And a type, which is used to constrain the type that the tag +/// | contains, to keep downcasting safe and less error prone. +/// +/// The TagData : +/// | Then, when it is time to tag sa sample, a block uses that tag key +/// | to add a tag on a sample bundling the tag key, and the sepcific data. +/// +/// +/// Another block downstream could then check if a sample has been tagged with something +/// of interest with the tag key. +/// If so, the block can then retrieve the data on the tag. +/// +/// Each sample can have multiple tags attached to it. +/// +/// TagKey using a usize backed identifier is used instead of the more +/// classic way of using String-Value pairs to allow easier and faster +/// Comparisons, as well as much tighter and cleaner managment of tags +/// throughout the graph. +/// +/// +/// use std::any::Any; use std::collections::HashMap; +use std::marker::PhantomData; use std::ops::Deref; use std::ops::DerefMut; use std::sync::Arc; use std::sync::Mutex; +pub struct Tags +{ + // Counter to uniquely identify allocated tags + counter: usize, + + // Keeps readable tag type and label(s) for the tags + tag_data: HashMap, +} + +pub struct TagKey +{ + key: usize, + _phantom: PhantomData, +} + +// Label for a tag like : "symbol", "packet_start", "error" +pub struct TagLabel +{ + label: String, +} + // Tags a particular sample within a specific stream #[derive(Clone)] pub struct Tag @@ -20,6 +84,35 @@ pub struct Tag pub data: Arc>>>, } +impl Tags +{ + pub fn new() -> Self + { + Self { + counter: 0, + tag_data: HashMap::new(), + } + } + + pub fn allocate_tag(&mut self) -> TagKey + { + let new_tag = TagKey { + key: self.counter, + _phantom: Default::default(), + }; + self.counter += 1; + new_tag + } +} + +impl Default for Tags +{ + fn default() -> Self + { + Self::new() + } +} + impl Tag { pub fn new() -> Self