From 9275c15258b660e2a9c45a1d0b3a0e14cc9980ae Mon Sep 17 00:00:00 2001 From: Martin Dahl Date: Mon, 6 Apr 2020 14:46:57 +0200 Subject: [PATCH] Add support for service messages --- build.rs | 23 ++++++++++++++++++----- common/src/lib.rs | 8 ++++++++ msg_gen/build.rs | 14 +++++++++++--- msg_gen/src/lib.rs | 14 +++++++++++++- src/lib.rs | 19 +++++++++++++++++++ 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/build.rs b/build.rs index ee2402b..152e800 100644 --- a/build.rs +++ b/build.rs @@ -27,17 +27,30 @@ fn main() { println!("cargo:rustc-link-lib=dylib={}__rosidl_generator_c", module); modules.push_str(&format!(r#"pub mod {module}{{include!(concat!(env!("OUT_DIR"), "/{module}.rs"));}}{lf}"#, module=module, lf="\n")); - //modules.push_str(&format!("pub mod {};\n", module)); let mut codegen = String::new(); for (prefix, msgs) in prefixes { codegen.push_str(&format!(" pub mod {} {{\n", prefix)); - codegen.push_str(" use super::super::*;\n"); for msg in msgs { - codegen.push_str(&generate_rust_msg(module, prefix, msg)); - - println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg); + if prefix == &"srv" { + codegen.push_str("#[allow(non_snake_case)]\n"); + codegen.push_str(&format!(" pub mod {} {{\n", msg)); + for s in &["Request", "Response"] { + let msgname = format!("{}_{}", msg, s); + codegen.push_str("#[allow(unused_imports)]\n"); + codegen.push_str(" use super::super::super::*;\n"); + codegen.push_str(&generate_rust_msg(module, prefix, &msgname)); + println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg); + } + codegen.push_str(" }\n"); + } else { + // the need to allow unused seems to be a compiler bug... + codegen.push_str("#[allow(unused_imports)]\n"); + codegen.push_str(" use super::super::*;\n"); + codegen.push_str(&generate_rust_msg(module, prefix, msg)); + println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg); + } } codegen.push_str(" }\n"); diff --git a/common/src/lib.rs b/common/src/lib.rs index 743a217..cb0a1c0 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -50,6 +50,14 @@ pub fn get_all_ros_msgs() -> Vec { msgs.push(msg_name); } } + if l.starts_with("srv/") && (l.ends_with(".idl") || l.ends_with(".srv")) { + if let Some(file_name_str) = file_name.to_str() { + let substr = &l[4..l.len()-4]; + let srv_name = format!("{}/srv/{}", file_name_str, substr); + println!("srv_name: {}", srv_name); + msgs.push(srv_name); + } + } }); } } diff --git a/msg_gen/build.rs b/msg_gen/build.rs index 7e04b47..3cbb247 100644 --- a/msg_gen/build.rs +++ b/msg_gen/build.rs @@ -48,9 +48,17 @@ fn main() { &msg.module, &msg.prefix, &include_filename )); - let key = &format!("{}__{}__{}", &msg.module, &msg.prefix, &msg.name); - let val = &format!("unsafe {{ rosidl_typesupport_introspection_c__get_message_type_support_handle__{}__{}__{}() }} as *const i32 as usize", &msg.module, &msg.prefix, &msg.name); - introspecion_map.push_str(&format!("m.insert(\"{}\", {});\n", key, val)); + if msg.prefix == "srv" { + for s in &["Request", "Response"] { + let key = &format!("{}__{}__{}_{}", &msg.module, &msg.prefix, &msg.name, s); + let val = &format!("unsafe {{ rosidl_typesupport_introspection_c__get_message_type_support_handle__{}__{}__{}_{}() }} as *const i32 as usize", &msg.module, &msg.prefix, &msg.name, s); + introspecion_map.push_str(&format!("m.insert(\"{}\", {});\n", key, val)); + } + } else { + let key = &format!("{}__{}__{}", &msg.module, &msg.prefix, &msg.name); + let val = &format!("unsafe {{ rosidl_typesupport_introspection_c__get_message_type_support_handle__{}__{}__{}() }} as *const i32 as usize", &msg.module, &msg.prefix, &msg.name); + introspecion_map.push_str(&format!("m.insert(\"{}\", {});\n", key, val)); + } } introspecion_map.push_str("m \n }; }\n\n"); diff --git a/msg_gen/src/lib.rs b/msg_gen/src/lib.rs index c47a3d4..4c3140f 100644 --- a/msg_gen/src/lib.rs +++ b/msg_gen/src/lib.rs @@ -110,11 +110,20 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String { .expect(&format!("code generation error: {}", name_)); let ptr = *ptr as *const i32 as *const rosidl_message_type_support_t; unsafe { - let (module, prefix, name, c_struct, members) = introspection(ptr); + let (module, prefix, mut name, c_struct, members) = introspection(ptr); assert_eq!(module, module_); assert_eq!(prefix, prefix_); assert_eq!(name, name_); + if prefix == "srv" { + // for srv, the message name is both the service name and _Request or _Respone + // we only want to keep the last part. + let mut nn = name.splitn(2, "_"); + let _mod_name = nn.next().expect(&format!("malformed service name {}", name)); + let msg_name = nn.next().expect(&format!("malformed service name {}", name)); + name = msg_name.to_owned(); + } + let mut fields = String::new(); for member in members { @@ -353,6 +362,9 @@ impl WrappedNativeMsgUntyped { let mut lines = String::new(); for msg in msgs { + // for now don't generate untyped services + if msg.prefix == "srv" { continue; } + let typename = format!("{}/{}/{}", msg.module, msg.prefix, msg.name); let rustname = format!("{}::{}::{}", msg.module, msg.prefix, msg.name); diff --git a/src/lib.rs b/src/lib.rs index f8aae0e..0dee56b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -911,4 +911,23 @@ mod tests { assert_eq!(msg.wstring_value, msg2.wstring_value); } + #[cfg(r2r__example_interfaces__srv__AddTwoInts)] + #[test] + fn test_service_msgs() { + use example_interfaces::srv::AddTwoInts; + let mut req = AddTwoInts::Request::default(); + req.a = 5; + let rn = WrappedNativeMsg::<_>::from(&req); + let req2 = AddTwoInts::Request::from_native(&rn); + println!("req2 {:?}", req2); + assert_eq!(req, req2); + + let mut resp = AddTwoInts::Response::default(); + resp.sum = 5; + let rn = WrappedNativeMsg::<_>::from(&resp); + let resp2 = AddTwoInts::Response::from_native(&rn); + println!("resp {:?}", resp2); + assert_eq!(resp, resp2); + } + }