diff --git a/cu29_derive/attr.copper_runtime.html b/cu29_derive/attr.copper_runtime.html index 0ba007c7f..4ba40824a 100644 --- a/cu29_derive/attr.copper_runtime.html +++ b/cu29_derive/attr.copper_runtime.html @@ -1,4 +1,4 @@ -copper_runtime in cu29_derive - Rust
cu29_derive

Attribute Macro copper_runtime

Source
#[copper_runtime]
Expand description

Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. +copper_runtime in cu29_derive - Rust

cu29_derive

Attribute Macro copper_runtime

Source
#[copper_runtime]
Expand description

Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. if sim_mode is ommited, it is set to false. This will add a “runtime” field to your struct and implement the “new” and “run” methods.

\ No newline at end of file diff --git a/cu29_derive/index.html b/cu29_derive/index.html index 6fb7574a1..14deebc20 100644 --- a/cu29_derive/index.html +++ b/cu29_derive/index.html @@ -1,4 +1,4 @@ -cu29_derive - Rust

Crate cu29_derive

Source

Macros§

  • Generates the CopperList content type from a config. +cu29_derive - Rust

    Crate cu29_derive

    Source

    Macros§

    • Generates the CopperList content type from a config. gen_cumsgs!(“path/to/config.toml”) It will create a new type called CuMsgs you can pass to the log reader for decoding:

    Attribute Macros§

    • Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. if sim_mode is ommited, it is set to false. diff --git a/cu29_derive/macro.gen_cumsgs.html b/cu29_derive/macro.gen_cumsgs.html index 0ea292cf7..5ac9e4c1f 100644 --- a/cu29_derive/macro.gen_cumsgs.html +++ b/cu29_derive/macro.gen_cumsgs.html @@ -1,4 +1,4 @@ -gen_cumsgs in cu29_derive - Rust
      cu29_derive

      Macro gen_cumsgs

      Source
      gen_cumsgs!() { /* proc-macro */ }
      Expand description

      Generates the CopperList content type from a config. +gen_cumsgs in cu29_derive - Rust

      cu29_derive

      Macro gen_cumsgs

      Source
      gen_cumsgs!() { /* proc-macro */ }
      Expand description

      Generates the CopperList content type from a config. gen_cumsgs!(“path/to/config.toml”) It will create a new type called CuMsgs you can pass to the log reader for decoding:

      \ No newline at end of file diff --git a/src/cu29_derive/lib.rs.html b/src/cu29_derive/lib.rs.html index 26285e190..832207569 100644 --- a/src/cu29_derive/lib.rs.html +++ b/src/cu29_derive/lib.rs.html @@ -1211,10 +1211,58 @@ 1210 1211 1212 -1213
      extern crate proc_macro;
      +1213
      +1214
      +1215
      +1216
      +1217
      +1218
      +1219
      +1220
      +1221
      +1222
      +1223
      +1224
      +1225
      +1226
      +1227
      +1228
      +1229
      +1230
      +1231
      +1232
      +1233
      +1234
      +1235
      +1236
      +1237
      +1238
      +1239
      +1240
      +1241
      +1242
      +1243
      +1244
      +1245
      +1246
      +1247
      +1248
      +1249
      +1250
      +1251
      +1252
      +1253
      +1254
      +1255
      +1256
      +1257
      +1258
      +1259
      +1260
      +1261
      extern crate proc_macro;
       
       use proc_macro::TokenStream;
      -use quote::quote;
      +use quote::{format_ident, quote};
       use std::fs::read_to_string;
       use syn::meta::parser;
       use syn::Fields::{Named, Unnamed};
      @@ -1255,6 +1303,13 @@
           let runtime_plan: CuExecutionLoop =
               compute_runtime_plan(&cuconfig).expect("Could not compute runtime plan");
       
      +    // Give a name compatible with a struct to match the task ids to their output in the CuMsgs tuple.
      +    let all_tasks_member_ids: Vec<String> = cuconfig
      +        .get_all_nodes()
      +        .iter()
      +        .map(|(_, node)| utils::config_id_to_struct_member(node.get_id().as_str()))
      +        .collect();
      +
           // All accesses are linear on the culist but the id of the tasks is random (determined by the Ron declaration order).
           // This records the task ids in call order.
           let taskid_order: Vec<usize> = runtime_plan
      @@ -1266,7 +1321,16 @@
               })
               .collect();
       
      -    let support = gen_culist_support(&runtime_plan, &taskid_order);
      +    #[cfg(feature = "macro_debug")]
      +    eprintln!(
      +        "[The CuMsgs matching tasks ids are {:?}]",
      +        taskid_order
      +            .iter()
      +            .map(|i| all_tasks_member_ids[*i].clone())
      +            .collect::<Vec<_>>()
      +    );
      +
      +    let support = gen_culist_support(&runtime_plan, &taskid_order, &all_tasks_member_ids);
       
           let with_uses = quote! {
               mod cumsgs {
      @@ -1290,6 +1354,7 @@
       fn gen_culist_support(
           runtime_plan: &CuExecutionLoop,
           taskid_call_order: &[usize],
      +    all_tasks_as_struct_member_name: &Vec<String>,
       ) -> proc_macro2::TokenStream {
           #[cfg(feature = "macro_debug")]
           eprintln!("[Extract msgs types]");
      @@ -1320,6 +1385,19 @@
               }
           };
       
      +    let methods = itertools::multizip((all_tasks_as_struct_member_name, taskid_call_order)).map(
      +        |(name, output_position)| {
      +            let fn_name = format_ident!("get_{}_output", name);
      +            let payload_type = all_msgs_types_in_culist_order[*output_position].clone();
      +            let index = syn::Index::from(*output_position);
      +            quote! {
      +                pub fn #fn_name(&self) -> &_CuMsg<#payload_type> {
      +                    &self.0.#index
      +                }
      +            }
      +        },
      +    );
      +
           // This generates a way to get the metadata of every single message of a culist at low cost
           quote! {
               #collect_metadata_function
      @@ -1327,6 +1405,18 @@
               pub struct CuMsgs(#msgs_types_tuple);
               pub type CuList = _CopperList<CuMsgs>;
       
      +        impl CuMsgs {
      +            #(#methods)*
      +
      +            fn get_tuple(&self) -> &#msgs_types_tuple {
      +                &self.0
      +            }
      +
      +            fn get_tuple_mut(&mut self) -> &mut #msgs_types_tuple {
      +                &mut self.0
      +            }
      +        }
      +
               // Adds the bincode support for the copper list tuple
               #msgs_types_tuple_encode
               #msgs_types_tuple_decode
      @@ -1999,10 +2089,16 @@
           #[cfg(feature = "macro_debug")]
           eprintln!("[Culist access order:  {:?}]", taskid_call_order);
       
      +    // Give a name compatible with a struct to match the task ids to their output in the CuMsgs tuple.
      +    let all_tasks_member_ids: Vec<String> = all_tasks_ids
      +        .iter()
      +        .map(|name| utils::config_id_to_struct_member(name.as_str()))
      +        .collect();
      +
           #[cfg(feature = "macro_debug")]
           eprintln!("[build the copperlist support]");
           let culist_support: proc_macro2::TokenStream =
      -        gen_culist_support(&runtime_plan, &taskid_call_order);
      +        gen_culist_support(&runtime_plan, &taskid_call_order, &all_tasks_member_ids);
       
           #[cfg(feature = "macro_debug")]
           eprintln!("[build the sim support]");
      diff --git a/src/cu29_derive/utils.rs.html b/src/cu29_derive/utils.rs.html
      index e99837115..b069b8dac 100644
      --- a/src/cu29_derive/utils.rs.html
      +++ b/src/cu29_derive/utils.rs.html
      @@ -107,7 +107,44 @@
       106
       107
       108
      -109
      use convert_case::{Case, Casing};
      +109
      +110
      +111
      +112
      +113
      +114
      +115
      +116
      +117
      +118
      +119
      +120
      +121
      +122
      +123
      +124
      +125
      +126
      +127
      +128
      +129
      +130
      +131
      +132
      +133
      +134
      +135
      +136
      +137
      +138
      +139
      +140
      +141
      +142
      +143
      +144
      +145
      +146
    use convert_case::{Case, Casing};
     use std::path::PathBuf;
     use walkdir::WalkDir;
     
    @@ -131,6 +168,26 @@
         candidate
     }
     
    +/// Same as config_id_to_enum but for a struct member name
    +pub(crate) fn config_id_to_struct_member(id: &str) -> String {
    +    let mut candidate = id
    +        .chars()
    +        .map(|c| if c.is_alphanumeric() { c } else { '_' })
    +        .collect::<String>();
    +
    +    candidate = candidate.to_case(Case::Snake);
    +
    +    if candidate
    +        .chars()
    +        .next()
    +        .map_or(false, |c| c.is_ascii_digit())
    +    {
    +        candidate.insert(0, '_');
    +    }
    +
    +    candidate
    +}
    +
     // Lifted this HORROR but it works.
     pub fn caller_crate_root() -> PathBuf {
         let crate_name =
    @@ -215,5 +272,22 @@
                 );
             })
         }
    +
    +    #[test]
    +    fn test_identifier_to_struct_member() {
    +        assert_eq!(crate::utils::config_id_to_struct_member("toto"), "toto");
    +        assert_eq!(crate::utils::config_id_to_struct_member("#id"), "id");
    +        assert_eq!(
    +            crate::utils::config_id_to_struct_member("!!something"),
    +            "something"
    +        );
    +        assert_eq!(crate::utils::config_id_to_struct_member("hey?"), "hey");
    +        assert_eq!(crate::utils::config_id_to_struct_member("é"), "é");
    +        assert_eq!(crate::utils::config_id_to_struct_member("T"), "t");
    +        assert_eq!(
    +            crate::utils::config_id_to_struct_member("Test_Dunder"),
    +            "test_dunder"
    +        );
    +    }
     }
     
\ No newline at end of file