Error type which is simply copy paste:d from the generated bindings
This commit is contained in:
parent
8ec9d1bedb
commit
321068aa1b
|
|
@ -10,6 +10,8 @@ edition = "2018"
|
|||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
failure = "0.1.5"
|
||||
failure_derive = "0.1.5"
|
||||
common = { path = "common", version = "0.0.1" }
|
||||
rcl = { path = "rcl", version = "0.0.1" }
|
||||
msg_gen = { path = "msg_gen", version = "0.0.1" }
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use r2r::*;
|
|||
use builtin_interfaces::msg::Duration;
|
||||
use trajectory_msgs::msg::*;
|
||||
use std_msgs::msg::Int32;
|
||||
use failure::Error;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
fn main() -> Result<(), Error> {
|
||||
let ctx = Context::create()?;
|
||||
let mut node = Node::create(ctx, "testnode", "")?;
|
||||
let publisher = node.create_publisher::<JointTrajectoryPoint>("/hej")?;
|
||||
|
|
@ -30,7 +31,7 @@ fn main() -> Result<(), ()> {
|
|||
let cb2 = move |x:JointTrajectoryPoint| {
|
||||
let serialized = serde_json::to_string(&x).unwrap();
|
||||
println!("JTP serialized as: {}", serialized);
|
||||
};
|
||||
};
|
||||
|
||||
let cb3 = move |raw_c:&WrappedNativeMsg<JointTrajectoryPoint>| {
|
||||
println!("Raw c data: {:?}", raw_c.positions);
|
||||
|
|
@ -45,7 +46,8 @@ fn main() -> Result<(), ()> {
|
|||
|
||||
// run for 10 seconds
|
||||
let mut count = 0;
|
||||
while count < 100 {
|
||||
// while count < 100 {
|
||||
loop {
|
||||
node.spin_once(std::time::Duration::from_millis(100));
|
||||
count += 1;
|
||||
}
|
||||
|
|
@ -54,4 +56,3 @@ fn main() -> Result<(), ()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use r2r::*;
|
|||
use std::thread;
|
||||
use std::env;
|
||||
use std::collections::HashMap;
|
||||
use failure::Error;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
fn main() -> Result<(), Error> {
|
||||
let ctx = Context::create()?;
|
||||
let mut node = Node::create(ctx, "echo", "")?;
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ fn main() -> Result<(), ()> {
|
|||
Some(tn) => tn,
|
||||
None => {
|
||||
eprintln!("Could not determine the type for the passed topic");
|
||||
return Err(());
|
||||
return Ok(());
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use r2r;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use failure::Error;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
fn main() -> Result<(), Error> {
|
||||
let ctx = r2r::Context::create()?;
|
||||
let node = r2r::Node::create(ctx, "testnode", "")?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use r2r::*;
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use failure::Error;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
fn main() -> Result<(), Error> {
|
||||
let ctx = Context::create()?;
|
||||
|
||||
let th = {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use failure::Error;
|
||||
|
||||
use r2r::*;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
fn main() -> Result<(), Error> {
|
||||
let ctx = Context::create()?;
|
||||
let mut node = Node::create(ctx, "testnode", "")?;
|
||||
|
||||
|
|
|
|||
|
|
@ -192,37 +192,36 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
|
|||
|
||||
// this is even worse, it was added as an afterthought when I wanted to implement rostopic echo
|
||||
pub fn generate_untyped_helpers(msgs: &Vec<common::RosMsg>) -> String {
|
||||
let mut ts_helper = format!("fn untyped_ts_helper(typename: &str) -> Result<&'static rosidl_message_type_support_t, ()> {{");
|
||||
let mut ts_helper = format!("fn untyped_ts_helper(typename: &str) -> Result<&'static rosidl_message_type_support_t> {{");
|
||||
for msg in msgs {
|
||||
ts_helper.push_str(&generate_untyped_ts_helper(&msg.module, &msg.prefix, &msg.name));
|
||||
}
|
||||
ts_helper.push_str(&format!("return Err(())\n}}"));
|
||||
ts_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
|
||||
|
||||
let mut ds_helper = format!("fn untyped_deserialize_helper(typename: &str) -> Result<fn(native: *const std::os::raw::c_void) -> serde_json::Value, ()> {{");
|
||||
let mut ds_helper = format!("fn untyped_deserialize_helper(typename: &str) -> Result<fn(native: *const std::os::raw::c_void) -> serde_json::Value> {{");
|
||||
for msg in msgs {
|
||||
ds_helper.push_str(&generate_untyped_deserialize_helper(&msg.module, &msg.prefix, &msg.name));
|
||||
}
|
||||
ds_helper.push_str(&format!("return Err(())\n}}"));
|
||||
ds_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
|
||||
|
||||
let mut se_helper = format!("
|
||||
fn untyped_serialize_helper(typename: &str) -> Result<fn(json: serde_json::Value) -> Result<*mut std::os::raw::c_void, ()>, ()> {{");
|
||||
fn untyped_serialize_helper(typename: &str) -> Result<fn(json: serde_json::Value) -> std::result::Result<*mut std::os::raw::c_void, serde_json::error::Error>> {{");
|
||||
for msg in msgs {
|
||||
se_helper.push_str(&generate_untyped_serialize_helper(&msg.module, &msg.prefix, &msg.name));
|
||||
}
|
||||
se_helper.push_str(&format!("return Err(())\n}}"));
|
||||
se_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
|
||||
|
||||
let mut alloc_helper = format!("fn untyped_alloc_helper(typename: &str) -> Result<*mut std::os::raw::c_void, ()> {{");
|
||||
let mut alloc_helper = format!("fn untyped_alloc_helper(typename: &str) -> Result<*mut std::os::raw::c_void> {{");
|
||||
for msg in msgs {
|
||||
alloc_helper.push_str(&generate_untyped_alloc_helper(&msg.module, &msg.prefix, &msg.name));
|
||||
}
|
||||
alloc_helper.push_str(&format!("return Err(())\n}}"));
|
||||
alloc_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
|
||||
|
||||
|
||||
let mut dealloc_helper = format!("fn untyped_dealloc_helper(typename: &str) -> Result<fn(*mut std::os::raw::c_void), ()> {{");
|
||||
let mut dealloc_helper = format!("fn untyped_dealloc_helper(typename: &str) -> Result<fn(*mut std::os::raw::c_void)> {{");
|
||||
for msg in msgs {
|
||||
dealloc_helper.push_str(&generate_untyped_dealloc_helper(&msg.module, &msg.prefix, &msg.name));
|
||||
}
|
||||
dealloc_helper.push_str(&format!("return Err(())\n}}"));
|
||||
dealloc_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
|
||||
|
||||
format!("{} \n\n {} \n\n {} \n\n {} \n\n {} \n\n", ts_helper, ds_helper, se_helper, alloc_helper, dealloc_helper)
|
||||
}
|
||||
|
|
@ -261,15 +260,10 @@ pub fn generate_untyped_serialize_helper(module_: &str, prefix_: &str, name_: &s
|
|||
format!("
|
||||
if typename == \"{typename}\" {{
|
||||
let x = | json: serde_json::Value | {{
|
||||
let msg: Result<{rustname}, _> = serde_json::from_value(json);
|
||||
match msg {{
|
||||
Ok(msg) => {{
|
||||
serde_json::from_value(json).map(|msg: {rustname}| {{
|
||||
let native = {rustname}::create_msg();
|
||||
unsafe {{ msg.copy_to_native(&mut *native); }}
|
||||
Ok(native as *mut std::os::raw::c_void)
|
||||
}},
|
||||
Err(_) => Err(())
|
||||
}}
|
||||
native as *mut std::os::raw::c_void }})
|
||||
}};
|
||||
return Ok(x);
|
||||
}}", typename = typename, rustname = rustname)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
use rcl::*;
|
||||
|
||||
// TODO
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum Error {
|
||||
// Copied from the generated bindgen
|
||||
#[fail(display = "RCL_RET_OK")]
|
||||
RCL_RET_OK,
|
||||
#[fail(display = "RCL_RET_ERROR")]
|
||||
RCL_RET_ERROR,
|
||||
#[fail(display = "RCL_RET_TIMEOUT")]
|
||||
RCL_RET_TIMEOUT,
|
||||
#[fail(display = "RCL_RET_BAD_ALLOC")]
|
||||
RCL_RET_BAD_ALLOC,
|
||||
#[fail(display = "RCL_RET_INVALID_ARGUMENT")]
|
||||
RCL_RET_INVALID_ARGUMENT,
|
||||
#[fail(display = "RCL_RET_UNSUPPORTED")]
|
||||
RCL_RET_UNSUPPORTED,
|
||||
#[fail(display = "RCL_RET_ALREADY_INIT")]
|
||||
RCL_RET_ALREADY_INIT,
|
||||
#[fail(display = "RCL_RET_NOT_INIT")]
|
||||
RCL_RET_NOT_INIT,
|
||||
#[fail(display = "RCL_RET_MISMATCHED_RMW_ID")]
|
||||
RCL_RET_MISMATCHED_RMW_ID,
|
||||
#[fail(display = "RCL_RET_TOPIC_NAME_INVALID")]
|
||||
RCL_RET_TOPIC_NAME_INVALID,
|
||||
#[fail(display = "RCL_RET_SERVICE_NAME_INVALID")]
|
||||
RCL_RET_SERVICE_NAME_INVALID,
|
||||
#[fail(display = "RCL_RET_UNKNOWN_SUBSTITUTION")]
|
||||
RCL_RET_UNKNOWN_SUBSTITUTION,
|
||||
#[fail(display = "RCL_RET_ALREADY_SHUTDOWN")]
|
||||
RCL_RET_ALREADY_SHUTDOWN,
|
||||
#[fail(display = "RCL_RET_NODE_INVALID")]
|
||||
RCL_RET_NODE_INVALID,
|
||||
#[fail(display = "RCL_RET_NODE_INVALID_NAME")]
|
||||
RCL_RET_NODE_INVALID_NAME,
|
||||
#[fail(display = "RCL_RET_NODE_INVALID_NAMESPACE")]
|
||||
RCL_RET_NODE_INVALID_NAMESPACE,
|
||||
#[fail(display = "RCL_RET_PUBLISHER_INVALID")]
|
||||
RCL_RET_PUBLISHER_INVALID,
|
||||
#[fail(display = "RCL_RET_SUBSCRIPTION_INVALID")]
|
||||
RCL_RET_SUBSCRIPTION_INVALID,
|
||||
#[fail(display = "RCL_RET_SUBSCRIPTION_TAKE_FAILED")]
|
||||
RCL_RET_SUBSCRIPTION_TAKE_FAILED,
|
||||
#[fail(display = "RCL_RET_CLIENT_INVALID")]
|
||||
RCL_RET_CLIENT_INVALID,
|
||||
#[fail(display = "RCL_RET_CLIENT_TAKE_FAILED")]
|
||||
RCL_RET_CLIENT_TAKE_FAILED,
|
||||
#[fail(display = "RCL_RET_SERVICE_INVALID")]
|
||||
RCL_RET_SERVICE_INVALID,
|
||||
#[fail(display = "RCL_RET_SERVICE_TAKE_FAILED")]
|
||||
RCL_RET_SERVICE_TAKE_FAILED,
|
||||
#[fail(display = "RCL_RET_TIMER_INVALID")]
|
||||
RCL_RET_TIMER_INVALID,
|
||||
#[fail(display = "RCL_RET_TIMER_CANCELED")]
|
||||
RCL_RET_TIMER_CANCELED,
|
||||
#[fail(display = "RCL_RET_WAIT_SET_INVALID")]
|
||||
RCL_RET_WAIT_SET_INVALID,
|
||||
#[fail(display = "RCL_RET_WAIT_SET_EMPTY")]
|
||||
RCL_RET_WAIT_SET_EMPTY,
|
||||
#[fail(display = "RCL_RET_WAIT_SET_FULL")]
|
||||
RCL_RET_WAIT_SET_FULL,
|
||||
#[fail(display = "RCL_RET_INVALID_REMAP_RULE")]
|
||||
RCL_RET_INVALID_REMAP_RULE,
|
||||
#[fail(display = "RCL_RET_WRONG_LEXEME")]
|
||||
RCL_RET_WRONG_LEXEME,
|
||||
#[fail(display = "RCL_RET_INVALID_PARAM_RULE")]
|
||||
RCL_RET_INVALID_PARAM_RULE,
|
||||
#[fail(display = "RCL_RET_INVALID_LOG_LEVEL_RULE")]
|
||||
RCL_RET_INVALID_LOG_LEVEL_RULE,
|
||||
#[fail(display = "RCL_RET_EVENT_INVALID")]
|
||||
RCL_RET_EVENT_INVALID,
|
||||
#[fail(display = "RCL_RET_EVENT_TAKE_FAILED")]
|
||||
RCL_RET_EVENT_TAKE_FAILED,
|
||||
|
||||
// Our own errors
|
||||
#[fail(display = "No typesupport build for the message type: {}", msgtype)]
|
||||
InvalidMessageType { msgtype: String },
|
||||
#[fail(display = "Serde error: {}", err)]
|
||||
SerdeError { err: String },
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn from_rcl_error(e: i32) -> Self {
|
||||
let e = e as u32;
|
||||
match e {
|
||||
_ if e == RCL_RET_OK => Error::RCL_RET_OK,
|
||||
_ if e == RCL_RET_ERROR => Error::RCL_RET_ERROR,
|
||||
_ if e == RCL_RET_TIMEOUT => Error::RCL_RET_TIMEOUT,
|
||||
_ if e == RCL_RET_BAD_ALLOC => Error::RCL_RET_BAD_ALLOC,
|
||||
_ if e == RCL_RET_INVALID_ARGUMENT => Error::RCL_RET_INVALID_ARGUMENT,
|
||||
_ if e == RCL_RET_UNSUPPORTED => Error::RCL_RET_UNSUPPORTED,
|
||||
_ if e == RCL_RET_ALREADY_INIT => Error::RCL_RET_ALREADY_INIT,
|
||||
_ if e == RCL_RET_NOT_INIT => Error::RCL_RET_NOT_INIT,
|
||||
_ if e == RCL_RET_MISMATCHED_RMW_ID => Error::RCL_RET_MISMATCHED_RMW_ID,
|
||||
_ if e == RCL_RET_TOPIC_NAME_INVALID => Error::RCL_RET_TOPIC_NAME_INVALID,
|
||||
_ if e == RCL_RET_SERVICE_NAME_INVALID => Error::RCL_RET_SERVICE_NAME_INVALID,
|
||||
_ if e == RCL_RET_UNKNOWN_SUBSTITUTION => Error::RCL_RET_UNKNOWN_SUBSTITUTION,
|
||||
_ if e == RCL_RET_ALREADY_SHUTDOWN => Error::RCL_RET_ALREADY_SHUTDOWN,
|
||||
_ if e == RCL_RET_NODE_INVALID => Error::RCL_RET_NODE_INVALID,
|
||||
_ if e == RCL_RET_NODE_INVALID_NAME => Error::RCL_RET_NODE_INVALID_NAME,
|
||||
_ if e == RCL_RET_NODE_INVALID_NAMESPACE => Error::RCL_RET_NODE_INVALID_NAMESPACE,
|
||||
_ if e == RCL_RET_PUBLISHER_INVALID => Error::RCL_RET_PUBLISHER_INVALID,
|
||||
_ if e == RCL_RET_SUBSCRIPTION_INVALID => Error::RCL_RET_SUBSCRIPTION_INVALID,
|
||||
_ if e == RCL_RET_SUBSCRIPTION_TAKE_FAILED => Error::RCL_RET_SUBSCRIPTION_TAKE_FAILED,
|
||||
_ if e == RCL_RET_CLIENT_INVALID => Error::RCL_RET_CLIENT_INVALID,
|
||||
_ if e == RCL_RET_CLIENT_TAKE_FAILED => Error::RCL_RET_CLIENT_TAKE_FAILED,
|
||||
_ if e == RCL_RET_SERVICE_INVALID => Error::RCL_RET_SERVICE_INVALID,
|
||||
_ if e == RCL_RET_SERVICE_TAKE_FAILED => Error::RCL_RET_SERVICE_TAKE_FAILED,
|
||||
_ if e == RCL_RET_TIMER_INVALID => Error::RCL_RET_TIMER_INVALID,
|
||||
_ if e == RCL_RET_TIMER_CANCELED => Error::RCL_RET_TIMER_CANCELED,
|
||||
_ if e == RCL_RET_WAIT_SET_INVALID => Error::RCL_RET_WAIT_SET_INVALID,
|
||||
_ if e == RCL_RET_WAIT_SET_EMPTY => Error::RCL_RET_WAIT_SET_EMPTY,
|
||||
_ if e == RCL_RET_WAIT_SET_FULL => Error::RCL_RET_WAIT_SET_FULL,
|
||||
_ if e == RCL_RET_INVALID_REMAP_RULE => Error::RCL_RET_INVALID_REMAP_RULE,
|
||||
_ if e == RCL_RET_WRONG_LEXEME => Error::RCL_RET_WRONG_LEXEME,
|
||||
_ if e == RCL_RET_INVALID_PARAM_RULE => Error::RCL_RET_INVALID_PARAM_RULE,
|
||||
_ if e == RCL_RET_INVALID_LOG_LEVEL_RULE => Error::RCL_RET_INVALID_LOG_LEVEL_RULE,
|
||||
_ if e == RCL_RET_EVENT_INVALID => Error::RCL_RET_EVENT_INVALID,
|
||||
_ if e == RCL_RET_EVENT_TAKE_FAILED => Error::RCL_RET_EVENT_TAKE_FAILED,
|
||||
_ => panic!("TODO: add error code {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/lib.rs
69
src/lib.rs
|
|
@ -1,9 +1,7 @@
|
|||
include!(concat!(env!("OUT_DIR"), "/generated_msgs.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/generated_typehacks.rs"));
|
||||
|
||||
use msg_gen::*;
|
||||
use rcl::*;
|
||||
|
||||
#[macro_use] extern crate failure_derive;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ffi::{CString,CStr};
|
||||
use std::marker::PhantomData;
|
||||
|
|
@ -11,6 +9,14 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::time::Duration;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use msg_gen::*;
|
||||
use rcl::*;
|
||||
|
||||
mod error;
|
||||
use error::*;
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub trait WrappedTypesupport {
|
||||
type CStruct;
|
||||
|
||||
|
|
@ -240,7 +246,7 @@ pub struct Context {
|
|||
unsafe impl Send for Context {}
|
||||
|
||||
impl Context {
|
||||
pub fn create() -> Result<Context, ()> {
|
||||
pub fn create() -> Result<Context> {
|
||||
let mut ctx: Box<rcl_context_t> = unsafe { Box::new(rcl_get_zero_initialized_context()) };
|
||||
let is_valid = unsafe {
|
||||
let allocator = rcutils_get_default_allocator();
|
||||
|
|
@ -256,7 +262,7 @@ impl Context {
|
|||
context_handle: Arc::new(Mutex::new(ctx)),
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::RCL_RET_ERROR) // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,7 +292,8 @@ pub struct Node {
|
|||
}
|
||||
|
||||
impl Node {
|
||||
pub fn create(ctx: Context, name: &str, namespace: &str) -> Result<Node, ()> {
|
||||
pub fn create(ctx: Context, name: &str, namespace: &str) -> Result<Node> {
|
||||
// cleanup default options.
|
||||
let (res, node_handle) = {
|
||||
let mut ctx_handle = ctx.context_handle.lock().unwrap();
|
||||
|
||||
|
|
@ -316,13 +323,13 @@ impl Node {
|
|||
})
|
||||
} else {
|
||||
eprintln!("could not create node{}", res);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(res))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_subscription_helper(&mut self, topic: &str, ts: *const rosidl_message_type_support_t) -> Result<rcl_subscription_t, ()> {
|
||||
fn create_subscription_helper(&mut self, topic: &str, ts: *const rosidl_message_type_support_t) -> Result<rcl_subscription_t> {
|
||||
let mut subscription_handle = unsafe { rcl_get_zero_initialized_subscription() };
|
||||
let topic_c_string = CString::new(topic).map_err(|_| ())?;
|
||||
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
|
||||
|
||||
let result = unsafe {
|
||||
let mut subscription_options = rcl_subscription_get_default_options();
|
||||
|
|
@ -338,7 +345,7 @@ impl Node {
|
|||
if result == RCL_RET_OK as i32 {
|
||||
Ok(subscription_handle)
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +353,7 @@ impl Node {
|
|||
&mut self,
|
||||
topic: &str,
|
||||
callback: Box<dyn FnMut(T) -> ()>,
|
||||
) -> Result<&rcl_subscription_t, ()>
|
||||
) -> Result<&rcl_subscription_t>
|
||||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
|
|
@ -364,7 +371,7 @@ impl Node {
|
|||
&mut self,
|
||||
topic: &str,
|
||||
callback: Box<dyn FnMut(&WrappedNativeMsg<T>) -> ()>,
|
||||
) -> Result<&rcl_subscription_t, ()>
|
||||
) -> Result<&rcl_subscription_t>
|
||||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
|
|
@ -384,7 +391,7 @@ impl Node {
|
|||
topic: &str,
|
||||
topic_type: &str,
|
||||
callback: Box<dyn FnMut(serde_json::Value) -> ()>,
|
||||
) -> Result<&rcl_subscription_t, ()> {
|
||||
) -> Result<&rcl_subscription_t> {
|
||||
let ts = untyped_ts_helper(topic_type)?;
|
||||
let de = untyped_deserialize_helper(topic_type)?;
|
||||
let subscription_handle = self.create_subscription_helper(topic, ts)?;
|
||||
|
|
@ -402,12 +409,12 @@ impl Node {
|
|||
}
|
||||
|
||||
|
||||
pub fn create_publisher<T>(&mut self, topic: &str) -> Result<Publisher<T>, ()>
|
||||
pub fn create_publisher<T>(&mut self, topic: &str) -> Result<Publisher<T>>
|
||||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
let mut publisher_handle = unsafe { rcl_get_zero_initialized_publisher() };
|
||||
let topic_c_string = CString::new(topic).unwrap();
|
||||
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
|
||||
|
||||
let result = unsafe {
|
||||
let mut publisher_options = rcl_publisher_get_default_options();
|
||||
|
|
@ -429,14 +436,14 @@ impl Node {
|
|||
Ok(p)
|
||||
} else {
|
||||
eprintln!("could not create publisher {}", result);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_publisher_untyped(&mut self, topic: &str, topic_type: &str) -> Result<PublisherUntyped, ()> {
|
||||
pub fn create_publisher_untyped(&mut self, topic: &str, topic_type: &str) -> Result<PublisherUntyped> {
|
||||
let ts = untyped_ts_helper(topic_type)?;
|
||||
let mut publisher_handle = unsafe { rcl_get_zero_initialized_publisher() };
|
||||
let topic_c_string = CString::new(topic).unwrap();
|
||||
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
|
||||
|
||||
let result = unsafe {
|
||||
let mut publisher_options = rcl_publisher_get_default_options();
|
||||
|
|
@ -458,7 +465,7 @@ impl Node {
|
|||
Ok(p)
|
||||
} else {
|
||||
eprintln!("could not create publisher {}", result);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -524,14 +531,14 @@ impl Node {
|
|||
}
|
||||
|
||||
|
||||
pub fn get_topic_names_and_types(&self) -> Result<HashMap<String, Vec<String>>, ()> {
|
||||
pub fn get_topic_names_and_types(&self) -> Result<HashMap<String, Vec<String>>> {
|
||||
let mut tnat = unsafe { rmw_get_zero_initialized_names_and_types() };
|
||||
let ret = unsafe {
|
||||
rcl_get_topic_names_and_types(self.node_handle.as_ref(), &mut rcutils_get_default_allocator(), false, &mut tnat)
|
||||
};
|
||||
if ret != RCL_RET_OK as i32 {
|
||||
eprintln!("could not get topic names and types {}", ret);
|
||||
return Err(());
|
||||
return Err(Error::from_rcl_error(ret));
|
||||
}
|
||||
|
||||
let names = unsafe { std::slice::from_raw_parts(tnat.names.data, tnat.names.size) };
|
||||
|
|
@ -589,12 +596,12 @@ impl<T> Publisher<T>
|
|||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
pub fn publish(&self, msg: &T) -> Result<(), ()>
|
||||
pub fn publish(&self, msg: &T) -> Result<()>
|
||||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
// upgrade to actual ref. if still alive
|
||||
let publisher = self.handle.upgrade().ok_or(())?;
|
||||
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
|
||||
// copy rust msg to native and publish it
|
||||
let native_msg: WrappedNativeMsg<T> = WrappedNativeMsg::<T>::from(msg);
|
||||
let result = unsafe {
|
||||
|
|
@ -609,16 +616,16 @@ where
|
|||
Ok(())
|
||||
} else {
|
||||
eprintln!("coult not publish {}", result);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn publish_native(&self, msg: &WrappedNativeMsg<T>) -> Result<(), ()>
|
||||
pub fn publish_native(&self, msg: &WrappedNativeMsg<T>) -> Result<()>
|
||||
where
|
||||
T: WrappedTypesupport,
|
||||
{
|
||||
// upgrade to actual ref. if still alive
|
||||
let publisher = self.handle.upgrade().ok_or(())?;
|
||||
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
|
||||
|
||||
let result =
|
||||
unsafe { rcl_publish(publisher.as_ref(), msg.void_ptr(), std::ptr::null_mut()) };
|
||||
|
|
@ -626,22 +633,22 @@ where
|
|||
Ok(())
|
||||
} else {
|
||||
eprintln!("could not publish native {}", result);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PublisherUntyped {
|
||||
pub fn publish(&self, msg: serde_json::Value) -> Result<(), ()> {
|
||||
pub fn publish(&self, msg: serde_json::Value) -> Result<()> {
|
||||
// upgrade to actual ref. if still alive
|
||||
let publisher = self.handle.upgrade().ok_or(())?;
|
||||
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
|
||||
|
||||
// figure out which serializer to use, publish, then destroy
|
||||
let se = untyped_serialize_helper(&self.type_)?;
|
||||
let dealloc = untyped_dealloc_helper(&self.type_)?;
|
||||
|
||||
// copy rust msg to native and publish it
|
||||
let native_ptr = se(msg)?;
|
||||
let native_ptr = se(msg).map_err(|e| Error::SerdeError { err: e.to_string() })?;
|
||||
let result = unsafe {
|
||||
rcl_publish(
|
||||
publisher.as_ref(),
|
||||
|
|
@ -656,7 +663,7 @@ impl PublisherUntyped {
|
|||
Ok(())
|
||||
} else {
|
||||
eprintln!("coult not publish {}", result);
|
||||
Err(())
|
||||
Err(Error::from_rcl_error(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use failure::Error;
|
||||
|
||||
use r2r::*;
|
||||
|
||||
#[test]
|
||||
// Let's create and drop a lot of node and publishers for a while to see that we can cope.
|
||||
fn doesnt_crash() -> Result<(), ()> {
|
||||
fn doesnt_crash() -> Result<(), Error> {
|
||||
// a global shared context.
|
||||
let ctx = Context::create()?;
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ fn doesnt_crash() -> Result<(), ()> {
|
|||
// move publisher to its own thread and publish as fast as we can
|
||||
thread::spawn(move || loop {
|
||||
let res = p.publish(&to_send);
|
||||
thread::sleep(std::time::Duration::from_millis(1));
|
||||
thread::sleep(Duration::from_millis(1));
|
||||
match res {
|
||||
Ok(_) => (),
|
||||
Err(_) => {
|
||||
|
|
@ -42,7 +43,7 @@ fn doesnt_crash() -> Result<(), ()> {
|
|||
|
||||
// spin to simulate some load
|
||||
for _j in 0..100 {
|
||||
node.spin_once(std::time::Duration::from_millis(10));
|
||||
node.spin_once(Duration::from_millis(10));
|
||||
}
|
||||
|
||||
// println!("all done {}-{}", c, i);
|
||||
|
|
|
|||
Loading…
Reference in New Issue