Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/v1/cu29-runtime.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1790,10 +1790,16 @@ pub fn cu29_runtime::resource::ResourceManager::borrow_shared_arc<T: 'static + c
pub fn cu29_runtime::resource::ResourceManager::new(bundle_sizes: &[usize]) -> Self
pub fn cu29_runtime::resource::ResourceManager::take<T: 'static + core::marker::Send + core::marker::Sync>(&mut self, key: cu29_runtime::resource::ResourceKey<T>) -> cu29_traits::CuResult<cu29_runtime::resource::Owned<T>>
pub struct cu29_runtime::resource::ThreadPoolBundle
impl cu29_runtime::resource::NamedResourceBundleDecl for cu29_runtime::resource::ThreadPoolBundle
pub const cu29_runtime::resource::ThreadPoolBundle::NAMES: &'static [&'static str]
impl cu29_runtime::resource::ResourceBundle for cu29_runtime::resource::ThreadPoolBundle
pub fn cu29_runtime::resource::ThreadPoolBundle::build(bundle: cu29_runtime::resource::BundleContext<Self>, config: core::option::Option<&cu29_runtime::config::ComponentConfig>, manager: &mut cu29_runtime::resource::ResourceManager) -> cu29_traits::CuResult<()>
impl cu29_runtime::resource::ResourceBundleDecl for cu29_runtime::resource::ThreadPoolBundle
pub type cu29_runtime::resource::ThreadPoolBundle::Id = cu29_runtime::resource::ThreadPoolId
pub trait cu29_runtime::resource::NamedResourceBundleDecl: cu29_runtime::resource::ResourceBundleDecl
pub const cu29_runtime::resource::NamedResourceBundleDecl::NAMES: &'static [&'static str]
impl cu29_runtime::resource::NamedResourceBundleDecl for cu29_runtime::resource::ThreadPoolBundle
pub const cu29_runtime::resource::ThreadPoolBundle::NAMES: &'static [&'static str]
pub trait cu29_runtime::resource::ResourceBindings<'r>: core::marker::Sized
pub type cu29_runtime::resource::ResourceBindings::Binding: core::marker::Copy + core::cmp::Eq + 'static
pub fn cu29_runtime::resource::ResourceBindings::from_bindings(manager: &'r mut cu29_runtime::resource::ResourceManager, mapping: core::option::Option<&cu29_runtime::resource::ResourceBindingMap<Self::Binding>>) -> cu29_traits::CuResult<Self>
Expand Down
41 changes: 26 additions & 15 deletions components/res/cu_linux_resources/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,21 +313,21 @@ pub struct LinuxResources;

bundle_resources!(
LinuxResources:
Serial0,
Serial1,
Serial2,
Serial3,
Serial4,
Serial5,
I2c0,
I2c1,
I2c2,
Gpio0,
Gpio1,
Gpio2,
Gpio3,
Gpio4,
Gpio5
Serial0 = "serial0",
Serial1 = "serial1",
Serial2 = "serial2",
Serial3 = "serial3",
Serial4 = "serial4",
Serial5 = "serial5",
I2c0 = "i2c0",
I2c1 = "i2c1",
I2c2 = "i2c2",
Gpio0 = "gpio0",
Gpio1 = "gpio1",
Gpio2 = "gpio2",
Gpio3 = "gpio3",
Gpio4 = "gpio4",
Gpio5 = "gpio5"
);

const LINUX_RESOURCE_SLOT_NAMES: &[&str] = &[
Expand Down Expand Up @@ -862,6 +862,17 @@ fn get_u64(config: Option<&ComponentConfig>, key: &str) -> CuResult<Option<u64>>
#[cfg(test)]
mod tests {
use super::*;
use cu29::resource::{NamedResourceBundleDecl, resource_index_by_name};

#[test]
fn named_resource_bundle_decl_matches_public_linux_slot_names() {
let declared = <LinuxResources as NamedResourceBundleDecl>::NAMES;
assert_eq!(declared, LINUX_RESOURCE_SLOT_NAMES);

for (idx, name) in declared.iter().enumerate() {
assert_eq!(resource_index_by_name::<LinuxResources>(name), idx);
}
}

#[test]
fn parse_serial_parity_value_accepts_expected_inputs() {
Expand Down
26 changes: 13 additions & 13 deletions components/res/cu_micoairh743/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,19 +373,19 @@ pub struct MicoAirH743;

bundle_resources!(
MicoAirH743:
Uart6,
Uart3,
Uart2,
Uart4,
GreenLed,
Logger,
Bmi088Spi,
Bmi088AccCs,
Bmi088GyrCs,
Bmi088Delay,
I2C2Dps310,
I2C2Ist8310,
BatteryAdc
Uart6 = "uart6",
Uart3 = "uart3",
Uart2 = "uart2",
Uart4 = "uart4",
GreenLed = "green_led",
Logger = "logger",
Bmi088Spi = "bmi088_spi",
Bmi088AccCs = "bmi088_acc_cs",
Bmi088GyrCs = "bmi088_gyr_cs",
Bmi088Delay = "bmi088_delay",
I2C2Dps310 = "i2c2_dps310",
I2C2Ist8310 = "i2c2_ist8310",
BatteryAdc = "battery_adc"
);

impl ResourceBundle for MicoAirH743 {
Expand Down
37 changes: 31 additions & 6 deletions core/cu29_derive/src/bundle_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ pub fn bundle_resources(input: TokenStream) -> TokenStream {
.unwrap_or_else(|| Ident::new("Bundle", proc_macro2::Span::call_site()));
let enum_ident = format_ident!("{}Id", bundle_ident);
let count = ids.len();
let variants = ids.iter();
let names = ids.iter().map(|ident| {
let name = ident.to_string().to_case(Case::Snake);
syn::LitStr::new(&name, ident.span())
let variants = ids.iter().map(|entry| &entry.ident);
let names = ids.iter().map(|entry| {
entry.name.clone().unwrap_or_else(|| {
let name = entry.ident.to_string().to_case(Case::Snake);
syn::LitStr::new(&name, entry.ident.span())
})
});
let names_ident_str = format!("{}_NAMES", enum_ident.to_string().to_case(Case::UpperSnake));
let names_ident = format_ident!("{}", names_ident_str);
Expand All @@ -51,6 +53,10 @@ pub fn bundle_resources(input: TokenStream) -> TokenStream {
type Id = #enum_ident;
}

impl ::cu29::resource::NamedResourceBundleDecl for #bundle {
const NAMES: &'static [&'static str] = #names_ident;
}

#[allow(dead_code)]
pub const #names_ident: &[&str] = &[#(#names),*];
};
Expand All @@ -60,17 +66,36 @@ pub fn bundle_resources(input: TokenStream) -> TokenStream {

struct BundleResourcesMacro {
bundle: Path,
ids: Vec<Ident>,
ids: Vec<BundleResourceEntry>,
}

struct BundleResourceEntry {
ident: Ident,
name: Option<syn::LitStr>,
}

impl Parse for BundleResourcesMacro {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let bundle: Path = input.parse()?;
input.parse::<Token![:]>()?;
let ids: Punctuated<Ident, Token![,]> = input.parse_terminated(Ident::parse, Token![,])?;
let ids: Punctuated<BundleResourceEntry, Token![,]> =
input.parse_terminated(BundleResourceEntry::parse, Token![,])?;
Ok(BundleResourcesMacro {
bundle,
ids: ids.into_iter().collect(),
})
}
}

impl Parse for BundleResourceEntry {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let ident: Ident = input.parse()?;
let name = if input.peek(Token![=]) {
input.parse::<Token![=]>()?;
Some(input.parse()?)
} else {
None
};
Ok(Self { ident, name })
}
}
22 changes: 12 additions & 10 deletions core/cu29_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7111,16 +7111,17 @@ fn build_task_resource_mappings(
<<#binding_task_type as #binding_trait>::Resources<'_> as ResourceBindings>::Binding
};
let entry_tokens = entries.iter().map(|spec| {
let binding_ident =
Ident::new(&config_id_to_enum(spec.binding_name.as_str()), Span::call_site());
let resource_ident =
Ident::new(&config_id_to_enum(spec.resource_name.as_str()), Span::call_site());
let binding_ident = Ident::new(
&config_id_to_enum(spec.binding_name.as_str()),
Span::call_site(),
);
let resource_name = LitStr::new(spec.resource_name.as_str(), Span::call_site());
let bundle_index = spec.bundle_index;
let provider_path = &spec.provider_path;
quote! {
(#binding_type::#binding_ident, cu29::resource::ResourceKey::new(
cu29::resource::BundleIndex::new(#bundle_index),
<#provider_path as cu29::resource::ResourceBundleDecl>::Id::#resource_ident as usize,
cu29::resource::resource_index_by_name::<#provider_path>(#resource_name),
))
}
});
Expand Down Expand Up @@ -7172,16 +7173,17 @@ fn build_bridge_resource_mappings(
let entries_ident = format_ident!("BRIDGE{}_RES_ENTRIES", idx);
let map_ident = format_ident!("BRIDGE{}_RES_MAPPING", idx);
let entry_tokens = entries.iter().map(|spec| {
let binding_ident =
Ident::new(&config_id_to_enum(spec.binding_name.as_str()), Span::call_site());
let resource_ident =
Ident::new(&config_id_to_enum(spec.resource_name.as_str()), Span::call_site());
let binding_ident = Ident::new(
&config_id_to_enum(spec.binding_name.as_str()),
Span::call_site(),
);
let resource_name = LitStr::new(spec.resource_name.as_str(), Span::call_site());
let bundle_index = spec.bundle_index;
let provider_path = &spec.provider_path;
quote! {
(#binding_type::#binding_ident, cu29::resource::ResourceKey::new(
cu29::resource::BundleIndex::new(#bundle_index),
<#provider_path as cu29::resource::ResourceBundleDecl>::Id::#resource_ident as usize,
cu29::resource::resource_index_by_name::<#provider_path>(#resource_name),
))
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use cu29::prelude::*;
use cu29::resource::{BundleContext, ResourceBundle, ResourceManager};
use cu29::{bundle_resources, resources};
use cu29_derive::copper_runtime;

use std::string::String;

pub struct TestBundle;

bundle_resources!(
TestBundle:
Serial3 = "serial3",
Gpio0 = "gpio0",
I2c1 = "i2c1"
);

impl ResourceBundle for TestBundle {
fn build(
bundle: BundleContext<Self>,
_config: Option<&ComponentConfig>,
manager: &mut ResourceManager,
) -> CuResult<()> {
manager.add_owned(bundle.key(TestBundleId::Serial3), String::from("serial"))?;
manager.add_owned(bundle.key(TestBundleId::Gpio0), String::from("pin"))?;
manager.add_owned(bundle.key(TestBundleId::I2c1), String::from("bus"))?;
Ok(())
}
}

#[derive(Reflect)]
struct NoopSource;

impl Freezable for NoopSource {}

impl CuSrcTask for NoopSource {
type Resources<'r> = ();
type Output<'m> = output_msg!(u32);

fn new(_config: Option<&ComponentConfig>, _resources: Self::Resources<'_>) -> CuResult<Self> {
Ok(Self)
}

fn process(&mut self, _ctx: &CuContext, output: &mut Self::Output<'_>) -> CuResult<()> {
output.set_payload(1);
Ok(())
}
}

mod sink_resources {
use super::*;

resources!({
serial => Owned<String>,
pin => Owned<String>,
bus => Owned<String>,
});
}

type SinkResources = sink_resources::Resources;

#[derive(Reflect)]
struct UsesNamedResourcesSink;

impl Freezable for UsesNamedResourcesSink {}

impl CuSinkTask for UsesNamedResourcesSink {
type Resources<'r> = SinkResources;
type Input<'m> = input_msg!(u32);

fn new(_config: Option<&ComponentConfig>, resources: Self::Resources<'_>) -> CuResult<Self> {
let _serial = resources.serial.0;
let _pin = resources.pin.0;
let _bus = resources.bus.0;
Ok(Self)
}

fn process(&mut self, _ctx: &CuContext, _input: &Self::Input<'_>) -> CuResult<()> {
Ok(())
}
}

#[copper_runtime(config = "config/resource_bundle_slot_name_case_valid.ron")]
struct App {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
(
resources: [
(
id: "linux",
provider: "TestBundle",
),
],
tasks: [
(id: "src", type: "NoopSource"),
(
id: "sink",
type: "UsesNamedResourcesSink",
resources: {
"serial": "linux.serial3",
"pin": "linux.gpio0",
"bus": "linux.i2c1",
},
),
],
cnx: [
(
src: "src",
dst: "sink",
msg: "u32",
),
],
)
Loading
Loading