Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract type conversions into functions #269

Merged
merged 5 commits into from
Feb 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions rclpy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,39 @@ function(configure_python_c_extension_library _library_name)
)
endfunction()

add_library(rclpy_common
SHARED src/rclpy_common/src/common.c
)
target_link_libraries(rclpy_common
${PythonExtra_LIBRARIES}
)
target_include_directories(rclpy_common
PUBLIC
src/rclpy_common/include
${PythonExtra_INCLUDE_DIRS}
)
ament_target_dependencies(rclpy_common
"rmw"
)

# Causes the visibility macros to use dllexport rather than dllimport,
# which is appropriate when building the dll but not consuming it.
target_compile_definitions(rclpy_common PRIVATE "RCLPY_COMMON_BUILDING_DLL")

install(TARGETS rclpy_common
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)

add_library(
rclpy
SHARED src/rclpy/_rclpy.c
)
target_link_libraries(rclpy
rclpy_common
)

configure_python_c_extension_library(rclpy)
ament_target_dependencies(rclpy
"rcl"
Expand All @@ -87,6 +116,10 @@ add_library(
rclpy_action
SHARED src/rclpy/_rclpy_action.c
)
target_link_libraries(rclpy_action
rclpy_common
)

configure_python_c_extension_library(rclpy_action)
ament_target_dependencies(rclpy_action
"rcl"
Expand Down
176 changes: 20 additions & 156 deletions rclpy/src/rclpy/_rclpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

#include <signal.h>

#include "./impl/common.h"
#include "rclpy_common/common.h"

static rcl_guard_condition_t * g_sigint_gc_handle;

Expand Down Expand Up @@ -1218,36 +1218,9 @@ rclpy_publish(PyObject * Py_UNUSED(self), PyObject * args)
return NULL;
}

PyObject * pymsg_type = PyObject_GetAttrString(pymsg, "__class__");

PyObject * pymetaclass = PyObject_GetAttrString(pymsg_type, "__class__");
Py_DECREF(pymsg_type);

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

convert_from_py_signature * convert_from_py = get_capsule_pointer(
pymetaclass, "_CONVERT_FROM_PY");
assert(convert_from_py != NULL &&
"unable to retrieve convert_from_py function, type_support mustn't have been imported");

Py_DECREF(pymetaclass);

void * raw_ros_message = create_ros_message();
destroy_ros_message_signature * destroy_ros_message = NULL;
void * raw_ros_message = rclpy_convert_from_py(pymsg, &destroy_ros_message);
if (!raw_ros_message) {
return PyErr_NoMemory();
}

if (!convert_from_py(pymsg, raw_ros_message)) {
// the function has set the Python error
destroy_ros_message(raw_ros_message);
return NULL;
}

Expand Down Expand Up @@ -1756,6 +1729,7 @@ rclpy_create_client(PyObject * Py_UNUSED(self), PyObject * args)
PyObject * pymetaclass = PyObject_GetAttrString(pysrv_type, "__class__");

PyObject * pyts = PyObject_GetAttrString(pymetaclass, "_TYPE_SUPPORT");
Py_DECREF(pymetaclass);

rosidl_service_type_support_t * ts =
(rosidl_service_type_support_t *)PyCapsule_GetPointer(pyts, NULL);
Expand Down Expand Up @@ -1820,37 +1794,9 @@ rclpy_send_request(PyObject * Py_UNUSED(self), PyObject * args)
return NULL;
}

PyObject * pyrequest_type = PyObject_GetAttrString(pyrequest, "__class__");
assert(pyrequest_type != NULL);

PyObject * pymetaclass = PyObject_GetAttrString(pyrequest_type, "__class__");
assert(pymetaclass != NULL);

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

convert_from_py_signature * convert_from_py = get_capsule_pointer(
pymetaclass, "_CONVERT_FROM_PY");
assert(convert_from_py != NULL &&
"unable to retrieve convert_from_py function, type_support mustn't have been imported");

Py_DECREF(pymetaclass);

void * raw_ros_request = create_ros_message();
destroy_ros_message_signature * destroy_ros_message = NULL;
void * raw_ros_request = rclpy_convert_from_py(pyrequest, &destroy_ros_message);
if (!raw_ros_request) {
return PyErr_NoMemory();
}

if (!convert_from_py(pyrequest, raw_ros_request)) {
// the function has set the Python error
destroy_ros_message(raw_ros_request);
return NULL;
}

Expand Down Expand Up @@ -1984,39 +1930,10 @@ rclpy_send_response(PyObject * Py_UNUSED(self), PyObject * args)
if (!header) {
return NULL;
}
PyObject * pyresponse_type = PyObject_GetAttrString(pyresponse, "__class__");
assert(pyresponse_type != NULL);

PyObject * pymetaclass = PyObject_GetAttrString(pyresponse_type, "__class__");
assert(pymetaclass != NULL);

Py_DECREF(pyresponse_type);

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

convert_from_py_signature * convert_from_py = get_capsule_pointer(
pymetaclass, "_CONVERT_FROM_PY");
assert(convert_from_py != NULL &&
"unable to retrieve convert_from_py function, type_support mustn't have been imported");

Py_DECREF(pymetaclass);

void * raw_ros_response = create_ros_message();
destroy_ros_message_signature * destroy_ros_message = NULL;
void * raw_ros_response = rclpy_convert_from_py(pyresponse, &destroy_ros_message);
if (!raw_ros_response) {
return PyErr_NoMemory();
}

if (!convert_from_py(pyresponse, raw_ros_response)) {
// the function has set the Python error
destroy_ros_message(raw_ros_response);
return NULL;
}

Expand Down Expand Up @@ -2669,22 +2586,10 @@ rclpy_take(PyObject * Py_UNUSED(self), PyObject * args)
return rclpy_take_raw(subscription);
}

PyObject * pymetaclass = PyObject_GetAttrString(pymsg_type, "__class__");

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

void * taken_msg = create_ros_message();
destroy_ros_message_signature * destroy_ros_message = NULL;
void * taken_msg = rclpy_create_from_py(pymsg_type, &destroy_ros_message);
if (!taken_msg) {
Py_DECREF(pymetaclass);
return PyErr_NoMemory();
return NULL;
}

rcl_ret_t ret = rcl_take(subscription, taken_msg, NULL);
Expand All @@ -2694,15 +2599,11 @@ rclpy_take(PyObject * Py_UNUSED(self), PyObject * args)
"Failed to take from a subscription: %s", rcl_get_error_string().str);
rcl_reset_error();
destroy_ros_message(taken_msg);
Py_DECREF(pymetaclass);
return NULL;
}

if (ret != RCL_RET_SUBSCRIPTION_TAKE_FAILED) {
convert_to_py_signature * convert_to_py = get_capsule_pointer(pymetaclass, "_CONVERT_TO_PY");
Py_DECREF(pymetaclass);

PyObject * pytaken_msg = convert_to_py(taken_msg);
PyObject * pytaken_msg = rclpy_convert_to_py(taken_msg, pymsg_type);
destroy_ros_message(taken_msg);
if (!pytaken_msg) {
// the function has set the Python error
Expand All @@ -2714,7 +2615,6 @@ rclpy_take(PyObject * Py_UNUSED(self), PyObject * args)

// if take failed, just do nothing
destroy_ros_message(taken_msg);
Py_DECREF(pymetaclass);
Py_RETURN_NONE;
}

Expand Down Expand Up @@ -2744,23 +2644,10 @@ rclpy_take_request(PyObject * Py_UNUSED(self), PyObject * args)
return NULL;
}

PyObject * pymetaclass = PyObject_GetAttrString(pyrequest_type, "__class__");

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

void * taken_request = create_ros_message();

destroy_ros_message_signature * destroy_ros_message = NULL;
void * taken_request = rclpy_create_from_py(pyrequest_type, &destroy_ros_message);
if (!taken_request) {
Py_DECREF(pymetaclass);
return PyErr_NoMemory();
return NULL;
}

rmw_request_id_t * header = (rmw_request_id_t *)PyMem_Malloc(sizeof(rmw_request_id_t));
Expand All @@ -2772,19 +2659,13 @@ rclpy_take_request(PyObject * Py_UNUSED(self), PyObject * args)
rcl_reset_error();
destroy_ros_message(taken_request);
PyMem_Free(header);
Py_DECREF(pymetaclass);
return NULL;
}

if (ret != RCL_RET_SERVICE_TAKE_FAILED) {
convert_to_py_signature * convert_to_py = get_capsule_pointer(pymetaclass, "_CONVERT_TO_PY");
Py_DECREF(pymetaclass);

PyObject * pytaken_request = convert_to_py(taken_request);
PyObject * pytaken_request = rclpy_convert_to_py(taken_request, pyrequest_type);
destroy_ros_message(taken_request);
if (!pytaken_request) {
// the function has set the Python error
PyMem_Free(header);
return NULL;
}

Expand All @@ -2797,7 +2678,6 @@ rclpy_take_request(PyObject * Py_UNUSED(self), PyObject * args)
// if take_request failed, just do nothing
PyMem_Free(header);
destroy_ros_message(taken_request);
Py_DECREF(pymetaclass);
Py_RETURN_NONE;
}

Expand All @@ -2824,24 +2704,12 @@ rclpy_take_response(PyObject * Py_UNUSED(self), PyObject * args)
return NULL;
}

PyObject * pymetaclass = PyObject_GetAttrString(pyresponse_type, "__class__");

create_ros_message_signature * create_ros_message = get_capsule_pointer(
pymetaclass, "_CREATE_ROS_MESSAGE");
assert(create_ros_message != NULL &&
"unable to retrieve create_ros_message function, type_support mustn't have been imported");

destroy_ros_message_signature * destroy_ros_message = get_capsule_pointer(
pymetaclass, "_DESTROY_ROS_MESSAGE");
assert(destroy_ros_message != NULL &&
"unable to retrieve destroy_ros_message function, type_support mustn't have been imported");

void * taken_response = create_ros_message();
destroy_ros_message_signature * destroy_ros_message = NULL;
void * taken_response = rclpy_create_from_py(pyresponse_type, &destroy_ros_message);
if (!taken_response) {
// the function has set the Python error
Py_DECREF(pymetaclass);
return NULL;
}

rmw_request_id_t * header = (rmw_request_id_t *)PyMem_Malloc(sizeof(rmw_request_id_t));
rcl_ret_t ret = rcl_take_response(client, header, taken_response);
int64_t sequence = header->sequence_number;
Expand All @@ -2854,10 +2722,7 @@ rclpy_take_response(PyObject * Py_UNUSED(self), PyObject * args)
}

if (ret != RCL_RET_CLIENT_TAKE_FAILED) {
convert_to_py_signature * convert_to_py = get_capsule_pointer(pymetaclass, "_CONVERT_TO_PY");
Py_DECREF(pymetaclass);

PyObject * pytaken_response = convert_to_py(taken_response);
PyObject * pytaken_response = rclpy_convert_to_py(taken_response, pyresponse_type);
destroy_ros_message(taken_response);
if (!pytaken_response) {
// the function has set the Python error
Expand All @@ -2879,7 +2744,6 @@ rclpy_take_response(PyObject * Py_UNUSED(self), PyObject * args)
PyTuple_SET_ITEM(pytuple, 0, Py_None);
Py_INCREF(Py_None);
PyTuple_SET_ITEM(pytuple, 1, Py_None);
Py_DECREF(pymetaclass);
destroy_ros_message(taken_response);
return pytuple;
}
Expand Down
2 changes: 1 addition & 1 deletion rclpy/src/rclpy/_rclpy_action.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <rcl/error_handling.h>
#include <rcl_action/rcl_action.h>

#include "./impl/common.h"
#include "rclpy_common/common.h"

/// Destroy an rcl_action entity.
/**
Expand Down
Loading