Add support for service messages

This commit is contained in:
Martin Dahl 2020-04-06 14:46:57 +02:00
parent f83541a24c
commit 9275c15258
5 changed files with 69 additions and 9 deletions

View File

@ -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");

View File

@ -50,6 +50,14 @@ pub fn get_all_ros_msgs() -> Vec<String> {
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);
}
}
});
}
}

View File

@ -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");

View File

@ -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);

View File

@ -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);
}
}