generation of action message types
This commit is contained in:
parent
c84bb67914
commit
ebe9287d76
21
build.rs
21
build.rs
|
|
@ -32,7 +32,22 @@ fn main() {
|
||||||
for (prefix, msgs) in prefixes {
|
for (prefix, msgs) in prefixes {
|
||||||
codegen.push_str(&format!(" pub mod {} {{\n", prefix));
|
codegen.push_str(&format!(" pub mod {} {{\n", prefix));
|
||||||
|
|
||||||
if prefix == &"srv" {
|
if prefix == &"action" {
|
||||||
|
for msg in msgs {
|
||||||
|
codegen.push_str("#[allow(non_snake_case)]\n");
|
||||||
|
codegen.push_str(&format!(" pub mod {} {{\n", msg));
|
||||||
|
codegen.push_str(" use super::super::super::*;\n");
|
||||||
|
|
||||||
|
codegen.push_str(&msg_gen::generate_rust_action(module, prefix, msg));
|
||||||
|
|
||||||
|
for s in &["Goal", "Result", "Feedback"] {
|
||||||
|
let msgname = format!("{}_{}", msg, s);
|
||||||
|
codegen.push_str(&msg_gen::generate_rust_msg(module, prefix, &msgname));
|
||||||
|
println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg);
|
||||||
|
}
|
||||||
|
codegen.push_str(" }\n");
|
||||||
|
}
|
||||||
|
} else if prefix == &"srv" {
|
||||||
for msg in msgs {
|
for msg in msgs {
|
||||||
codegen.push_str("#[allow(non_snake_case)]\n");
|
codegen.push_str("#[allow(non_snake_case)]\n");
|
||||||
codegen.push_str(&format!(" pub mod {} {{\n", msg));
|
codegen.push_str(&format!(" pub mod {} {{\n", msg));
|
||||||
|
|
@ -47,12 +62,14 @@ fn main() {
|
||||||
}
|
}
|
||||||
codegen.push_str(" }\n");
|
codegen.push_str(" }\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else if prefix == &"msg" {
|
||||||
codegen.push_str(" use super::super::*;\n");
|
codegen.push_str(" use super::super::*;\n");
|
||||||
for msg in msgs {
|
for msg in msgs {
|
||||||
codegen.push_str(&msg_gen::generate_rust_msg(module, prefix, msg));
|
codegen.push_str(&msg_gen::generate_rust_msg(module, prefix, msg));
|
||||||
println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg);
|
println!("cargo:rustc-cfg=r2r__{}__{}__{}", module, prefix, msg);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
panic!("unknown prefix type: {}", prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
codegen.push_str(" }\n");
|
codegen.push_str(" }\n");
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,18 @@ fn get_msgs_from_package(package: &Path) -> Vec<String> {
|
||||||
msgs.push(srv_name);
|
msgs.push(srv_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if l.starts_with("action/") && (l.ends_with(".idl") || l.ends_with(".action")) {
|
||||||
|
if let Some(file_name_str) = file_name.to_str() {
|
||||||
|
let substr = if l.ends_with(".action") {
|
||||||
|
&l[7..l.len()-7]
|
||||||
|
} else {
|
||||||
|
&l[7..l.len()-4] // .idl
|
||||||
|
};
|
||||||
|
let action_name = format!("{}/action/{}", file_name_str, substr);
|
||||||
|
println!("found action: {}", action_name);
|
||||||
|
msgs.push(action_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,19 +92,6 @@ pub fn get_ros_msgs(paths: &[&Path]) -> Vec<String> {
|
||||||
msgs
|
msgs
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_msg_list() {
|
|
||||||
|
|
||||||
let msgs = get_all_ros_msgs();
|
|
||||||
for m in &msgs {
|
|
||||||
println!("{}", m);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(msgs.contains(&"std_msgs/msg/String".to_string()));
|
|
||||||
assert!(msgs.contains(&"builtin_interfaces/msg/Time".to_string()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_msgs(msgs: &Vec<String>) -> Vec<RosMsg> {
|
pub fn parse_msgs(msgs: &Vec<String>) -> Vec<RosMsg> {
|
||||||
let v: Vec<Vec<&str>> = msgs.iter().map(|l| l.split("/").into_iter().take(3).collect()).collect();
|
let v: Vec<Vec<&str>> = msgs.iter().map(|l| l.split("/").into_iter().take(3).collect()).collect();
|
||||||
let v: Vec<_> = v.iter().filter(|v|v.len() == 3).
|
let v: Vec<_> = v.iter().filter(|v|v.len() == 3).
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,14 @@ fn main() {
|
||||||
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);
|
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));
|
introspecion_map.push_str(&format!("m.insert(\"{}\", {});\n", key, val));
|
||||||
}
|
}
|
||||||
} else {
|
} else if msg.prefix == "action" {
|
||||||
|
for s in &["Goal", "Result", "Feedback"] {
|
||||||
|
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 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);
|
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(&format!("m.insert(\"{}\", {});\n", key, val));
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,24 @@ pub fn generate_rust_service(module_: &str, prefix_: &str, name_: &str) -> Strin
|
||||||
", module_, prefix_, name_)
|
", module_, prefix_, name_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_rust_action(module_: &str, prefix_: &str, name_: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"
|
||||||
|
pub struct Action();
|
||||||
|
impl WrappedActionTypeSupport for Action {{
|
||||||
|
type Goal = Goal;
|
||||||
|
type Result = Result;
|
||||||
|
type Feedback = Feedback;
|
||||||
|
fn get_ts() -> &'static rosidl_action_type_support_t {{
|
||||||
|
unsafe {{
|
||||||
|
&*rosidl_typesupport_c__get_action_type_support_handle__{}__{}__{}()
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
", module_, prefix_, name_)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: this is a terrible hack :)
|
// TODO: this is a terrible hack :)
|
||||||
pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
||||||
|
|
@ -133,9 +151,11 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
||||||
assert_eq!(prefix, prefix_);
|
assert_eq!(prefix, prefix_);
|
||||||
assert_eq!(name, name_);
|
assert_eq!(name, name_);
|
||||||
|
|
||||||
if prefix == "srv" {
|
if prefix == "srv" || prefix == "action" {
|
||||||
// for srv, the message name is both the service name and _Request or _Respone
|
// for srv, the message name is both the service name and _Request or _Respone
|
||||||
// we only want to keep the last part.
|
// we only want to keep the last part.
|
||||||
|
// same for actions with _Goal, _Result, _Feedback
|
||||||
|
// TODO: refactor...
|
||||||
let mut nn = name.splitn(2, "_");
|
let mut nn = name.splitn(2, "_");
|
||||||
let _mod_name = nn.next().expect(&format!("malformed service name {}", name));
|
let _mod_name = nn.next().expect(&format!("malformed service name {}", name));
|
||||||
let msg_name = nn.next().expect(&format!("malformed service name {}", name));
|
let msg_name = nn.next().expect(&format!("malformed service name {}", name));
|
||||||
|
|
@ -380,8 +400,8 @@ impl WrappedNativeMsgUntyped {
|
||||||
|
|
||||||
let mut lines = String::new();
|
let mut lines = String::new();
|
||||||
for msg in msgs {
|
for msg in msgs {
|
||||||
// for now don't generate untyped services
|
// for now don't generate untyped services or actions
|
||||||
if msg.prefix == "srv" { continue; }
|
if msg.prefix == "srv" || msg.prefix == "action" { continue; }
|
||||||
|
|
||||||
let typename = format!("{}/{}/{}", msg.module, msg.prefix, msg.name);
|
let typename = format!("{}/{}/{}", msg.module, msg.prefix, msg.name);
|
||||||
let rustname = format!("{}::{}::{}", msg.module, msg.prefix, msg.name);
|
let rustname = format!("{}::{}::{}", msg.module, msg.prefix, msg.name);
|
||||||
|
|
|
||||||
34
src/lib.rs
34
src/lib.rs
|
|
@ -38,6 +38,14 @@ pub trait WrappedServiceTypeSupport {
|
||||||
fn get_ts() -> &'static rosidl_service_type_support_t;
|
fn get_ts() -> &'static rosidl_service_type_support_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait WrappedActionTypeSupport {
|
||||||
|
type Goal: WrappedTypesupport;
|
||||||
|
type Result: WrappedTypesupport;
|
||||||
|
type Feedback: WrappedTypesupport;
|
||||||
|
|
||||||
|
fn get_ts() -> &'static rosidl_action_type_support_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WrappedNativeMsg<T>
|
pub struct WrappedNativeMsg<T>
|
||||||
|
|
@ -1638,4 +1646,30 @@ mod tests {
|
||||||
println!("resp {:?}", resp2);
|
println!("resp {:?}", resp2);
|
||||||
assert_eq!(resp, resp2);
|
assert_eq!(resp, resp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(r2r__example_interfaces__action__Fibonacci)]
|
||||||
|
#[test]
|
||||||
|
fn test_action_msgs() {
|
||||||
|
use example_interfaces::action::Fibonacci;
|
||||||
|
let mut goal = Fibonacci::Goal::default();
|
||||||
|
goal.order = 5;
|
||||||
|
let gn = WrappedNativeMsg::<_>::from(&goal);
|
||||||
|
let goal2 = Fibonacci::Goal::from_native(&gn);
|
||||||
|
println!("goal2 {:?}", goal2);
|
||||||
|
assert_eq!(goal, goal2);
|
||||||
|
|
||||||
|
let mut res = Fibonacci::Result::default();
|
||||||
|
res.sequence = vec![1,2,3];
|
||||||
|
let rn = WrappedNativeMsg::<_>::from(&res);
|
||||||
|
let res2 = Fibonacci::Result::from_native(&rn);
|
||||||
|
println!("res2 {:?}", res2);
|
||||||
|
assert_eq!(res, res2);
|
||||||
|
|
||||||
|
let mut fb = Fibonacci::Feedback::default();
|
||||||
|
fb.sequence = vec![4,3,6];
|
||||||
|
let fbn = WrappedNativeMsg::<_>::from(&fb);
|
||||||
|
let fb2 = Fibonacci::Feedback::from_native(&fbn);
|
||||||
|
println!("feedback2 {:?}", fb2);
|
||||||
|
assert_eq!(fb, fb2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue