Skip to content

Commit 9a65235

Browse files
plurisjacobperron
authored andcommitted
change logic(list -> array) in msg.cpp.em
1 parent 3a068ef commit 9a65235

File tree

1 file changed

+100
-78
lines changed

1 file changed

+100
-78
lines changed

rosidl_generator_java/resource/msg.cpp.em

Lines changed: 100 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,6 @@ from rosidl_parser.definition import NamespacedType
2222
msg_normalized_type = '__'.join(message.structure.namespaced_type.namespaced_name())
2323
msg_jni_type = '/'.join(message.structure.namespaced_type.namespaced_name())
2424

25-
list_java_type = "java.util.List"
26-
array_list_java_type = "java.util.ArrayList"
27-
28-
list_normalized_type = "java__util__List"
29-
list_jni_type = "java/util/List"
30-
31-
array_list_normalized_type = "java__util__ArrayList"
32-
array_list_jni_type = "java/util/ArrayList"
33-
3425
# Collect JNI types and includes
3526
cache = defaultdict(lambda: False)
3627
cache[msg_normalized_type] = msg_jni_type
@@ -39,8 +30,6 @@ member_includes = set()
3930
for member in message.structure.members:
4031
type_ = member.type
4132
if isinstance(type_, AbstractNestedType):
42-
cache[list_normalized_type] = list_jni_type
43-
cache[array_list_normalized_type] = array_list_jni_type
4433
type_ = type_.value_type
4534
if isinstance(type_, BasicType):
4635
member_includes.add('rosidl_generator_c/primitives_sequence.h')
@@ -220,72 +209,92 @@ JNIEXPORT jlong JNICALL Java_@(underscore_separated_jni_type_name)_getDestructor
220209
}
221210
@[for member in message.structure.members]@
222211
@{
223-
normalized_type = get_normalized_type(member.type)
212+
if isinstance(member.type, AbstractNestedType):
213+
normalized_type = get_normalized_type(member.type.value_type)
214+
get_java_name = get_java_type(member.type.value_type, use_primitives=True)
215+
get_method_name = get_java_type(member.type.value_type, use_primitives=True).capitalize()
216+
jni_signature = get_jni_signature(member.type.value_type)
217+
else:
218+
normalized_type = get_normalized_type(member.type)
219+
get_java_name = get_java_type(member.type, use_primitives=True)
220+
get_method_name = get_java_type(member.type, use_primitives=True).capitalize()
221+
jni_signature = get_jni_signature(member.type)
224222
}@
225223
@[ if isinstance(member.type, AbstractNestedType)]
226-
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "L@(list_jni_type);");
227-
jobject _jlist_@(member.name)_object = env->GetObjectField(_jmessage_obj, _jfield_@(member.name)_fid);
224+
@[ if isinstance(member.type.value_type, BasicType)]@
225+
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "[@(jni_signature)");
226+
j@(get_java_name)Array _jarray_@(member.name)_obj = (j@(get_java_name)Array)env->GetObjectField(_jmessage_obj, _jfield_@(member.name)_fid);
227+
@[ elif isinstance(member.type.value_type, AbstractGenericString)]@
228+
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "[Ljava/lang/String;");
229+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->GetObjectField(_jmessage_obj, _jfield_@(member.name)_fid);
230+
@[ else]@
231+
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "[L@('/'.join(member.type.value_type.namespaced_name()));");
232+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->GetObjectField(_jmessage_obj, _jfield_@(member.name)_fid);
233+
@[ end if]@
228234

229-
if (_jlist_@(member.name)_object != nullptr) {
230-
jmethodID _jlist_@(member.name)_get_mid = env->GetMethodID(_j@(list_normalized_type)_class_global, "get", "(I)Ljava/lang/Object;");
235+
if (_jarray_@(member.name)_obj != nullptr) {
231236
@[ if isinstance(member.type, AbstractSequence)]@
232-
jmethodID _jlist_@(member.name)_size_mid = env->GetMethodID(_j@(list_normalized_type)_class_global, "size", "()I");
233-
jint _jlist_@(member.name)_size = env->CallIntMethod(_jlist_@(member.name)_object, _jlist_@(member.name)_size_mid);
237+
@[ if isinstance(member.type, Array)]@
238+
jint _jarray_@(member.name)_size = @(member.type.size);
239+
@[ else]@
240+
jint _jarray_@(member.name)_size = env->GetArrayLength(_jarray_@(member.name)_obj);
241+
@[ end if]@
234242
@[ if isinstance(member.type.value_type, AbstractString)]@
235-
if (!rosidl_generator_c__String__Sequence__init(&(ros_message->@(member.name)), _jlist_@(member.name)_size)) {
243+
if (!rosidl_generator_c__String__Sequence__init(&(ros_message->@(member.name)), _jarray_@(member.name)_size)) {
236244
rcljava_throw_exception(env, "java/lang/IllegalStateException", "unable to create String__Array ros_message");
237245
}
238246
@[ elif isinstance(member.type.value_type, AbstractWString)]@
239-
if (!rosidl_generator_c__U16String__Sequence__init(&(ros_message->@(member.name)), _jlist_@(member.name)_size)) {
247+
if (!rosidl_generator_c__U16String__Sequence__init(&(ros_message->@(member.name)), _jarray_@(member.name)_size)) {
240248
rcljava_throw_exception(env, "java/lang/IllegalStateException", "unable to create U16String__Array ros_message");
241249
}
242250
@[ else]@
243251
@[ if isinstance(member.type.value_type, BasicType)]@
244-
if (!rosidl_generator_c__@(member.type.value_type.typename)__Sequence__init(&(ros_message->@(member.name)), _jlist_@(member.name)_size)) {
252+
if (!rosidl_generator_c__@(member.type.value_type.typename)__Sequence__init(&(ros_message->@(member.name)), _jarray_@(member.name)_size)) {
245253
rcljava_throw_exception(env, "java/lang/IllegalStateException", "unable to create @(member.type.value_type)__Array ros_message");
246254
}
247255
@[ else]@
248-
if (!@('__'.join(member.type.value_type.namespaced_name()))__Sequence__init(&(ros_message->@(member.name)), _jlist_@(member.name)_size)) {
256+
if (!@('__'.join(member.type.value_type.namespaced_name()))__Sequence__init(&(ros_message->@(member.name)), _jarray_@(member.name)_size)) {
249257
rcljava_throw_exception(env, "java/lang/IllegalStateException", "unable to create @(member.type.value_type)__Array ros_message");
250258
}
251259

252260
@[ end if]@
253261
@[ end if]@
254262
auto _dest_@(member.name) = ros_message->@(member.name).data;
255263
@[ else]@
256-
jint _jlist_@(member.name)_size = @(member.type.size);
264+
jint _jarray_@(member.name)_size = @(member.type.size);
257265

258266
auto _dest_@(member.name) = ros_message->@(member.name);
259267
@[ end if]@
260-
261-
for (jint i = 0; i < _jlist_@(member.name)_size; ++i) {
262-
auto element = env->CallObjectMethod(_jlist_@(member.name)_object, _jlist_@(member.name)_get_mid, i);
263-
@[ if isinstance(member.type.value_type, AbstractString)]@
268+
@[ if isinstance(member.type.value_type, BasicType)]@
269+
j@(get_java_name) *_jarray_@(member.name)_ptr = env->Get@(get_method_name)ArrayElements(_jarray_@(member.name)_obj, nullptr);
270+
std::copy(_jarray_@(member.name)_ptr, _jarray_@(member.name)_ptr + _jarray_@(member.name)_size, _dest_@(member.name));
271+
env->Release@(get_method_name)ArrayElements(_jarray_@(member.name)_obj, _jarray_@(member.name)_ptr, 0);
272+
@[ else]@
273+
for (jint i = 0; i < _jarray_@(member.name)_size; ++i) {
274+
auto element = env->GetObjectArrayElement(_jarray_@(member.name)_obj, i);
275+
@[ if isinstance(member.type.value_type, AbstractString)]@
264276
jstring _jfield_@(member.name)_value = static_cast<jstring>(element);
265277
if (_jfield_@(member.name)_value != nullptr) {
266-
const char * _str@(member.name) = env->GetStringUTFChars(_jfield_@(member.name)_value, 0);
278+
const char * _str_@(member.name) = env->GetStringUTFChars(_jfield_@(member.name)_value, 0);
267279
rosidl_generator_c__String__assign(
268-
&_dest_@(member.name)[i], _str@(member.name));
269-
env->ReleaseStringUTFChars(_jfield_@(member.name)_value, _str@(member.name));
280+
&_dest_@(member.name)[i], _str_@(member.name));
281+
env->ReleaseStringUTFChars(_jfield_@(member.name)_value, _str_@(member.name));
270282
}
271-
@[ elif isinstance(member.type.value_type, AbstractWString)]@
283+
@[ elif isinstance(member.type.value_type, AbstractWString)]@
272284
jstring _jfield_@(member.name)_value = static_cast<jstring>(element);
273285
if (_jfield_@(member.name)_value != nullptr) {
274-
const jchar * _str@(member.name) = env->GetStringChars(_jfield_@(member.name)_value, 0);
286+
const jchar * _str_@(member.name) = env->GetStringChars(_jfield_@(member.name)_value, 0);
275287
rosidl_generator_c__U16String__assign(
276-
&_dest_@(member.name)[i], _str@(member.name));
277-
env->ReleaseStringChars(_jfield_@(member.name)_value, _str@(member.name));
288+
&_dest_@(member.name)[i], _str_@(member.name));
289+
env->ReleaseStringChars(_jfield_@(member.name)_value, _str_@(member.name));
278290
}
279-
@[ elif isinstance(member.type.value_type, BasicType)]@
280-
@{
281-
call_method_name = 'Call%sMethod' % get_java_type(member.type.value_type, use_primitives=True).capitalize()
282-
}@
283-
_dest_@(member.name)[i] = env->@(call_method_name)(element, _j@(normalized_type)_value_global);
284-
@[ else]@
291+
@[ else]@
285292
_dest_@(member.name)[i] = *_j@(normalized_type)_from_java_function(element, nullptr);
286-
@[ end if]@
293+
@[ end if]@
287294
env->DeleteLocalRef(element);
288295
}
296+
@[ end if]@
297+
env->DeleteLocalRef(_jarray_@(member.name)_obj);
289298
}
290299
@[ else]@
291300
@[ if isinstance(member.type, AbstractGenericString)]@
@@ -349,61 +358,74 @@ jobject @(underscore_separated_type_name)__convert_to_java(@(msg_normalized_type
349358
}
350359
@[for member in message.structure.members]@
351360
@{
352-
normalized_type = get_normalized_type(member.type)
361+
if isinstance(member.type, AbstractNestedType):
362+
normalized_type = get_normalized_type(member.type.value_type)
363+
get_java_name = get_java_type(member.type.value_type, use_primitives=True)
364+
get_method_name = get_java_type(member.type.value_type, use_primitives=True).capitalize()
365+
jni_signature = get_jni_signature(member.type.value_type)
366+
else:
367+
normalized_type = get_normalized_type(member.type)
368+
get_java_name = get_java_type(member.type, use_primitives=True)
369+
get_method_name = get_java_type(member.type, use_primitives=True).capitalize()
370+
jni_signature = get_jni_signature(member.type)
353371
}@
354372
@[ if isinstance(member.type, AbstractNestedType)]@
355373
@[ if isinstance(member.type.value_type, (BasicType, AbstractGenericString))]@
356-
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "L@(list_jni_type);");
357-
jobject _jarray_list_@(member.name)_obj = env->NewObject(_j@(array_list_normalized_type)_class_global, _j@(array_list_normalized_type)_constructor_global);
358-
// TODO(esteve): replace ArrayList with a jobjectArray to initialize the array beforehand
359-
jmethodID _jlist_@(member.name)_add_mid = env->GetMethodID(_j@(array_list_normalized_type)_class_global, "add", "(Ljava/lang/Object;)Z");
374+
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "[@(jni_signature)");
375+
@[ else]@
376+
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "[L@('/'.join(member.type.value_type.namespaced_name()));");
377+
@[ end if]@
378+
379+
@[ if isinstance(member.type.value_type, BasicType)]@
360380
@[ if isinstance(member.type, Array)]@
361-
for (size_t i = 0; i < @(member.type.size); ++i) {
381+
j@(get_java_name)Array _jarray_@(member.name)_obj = env->New@(get_method_name)Array(@(member.type.size));
382+
j@(get_java_name) *_j@(get_java_name)_@(member.name)_buf = (j@(get_java_name) *)malloc(sizeof(j@(get_java_name)) * @(member.type.size));
383+
std::copy(_ros_message->@(member.name), _ros_message->@(member.name) + @(member.type.size), _j@(get_java_name)_@(member.name)_buf);
384+
env->Set@(get_method_name)ArrayRegion(_jarray_@(member.name)_obj, 0, @(member.type.size), (const j@(get_java_name) *)_j@(get_java_name)_@(member.name)_buf);
385+
@[ else]@
386+
j@(get_java_name)Array _jarray_@(member.name)_obj = env->New@(get_method_name)Array(_ros_message->@(member.name).size);
387+
j@(get_java_name) *_j@(get_java_name)_@(member.name)_buf = (j@(get_java_name) *)malloc(sizeof(j@(get_java_name)) * _ros_message->@(member.name).size);
388+
std::copy(_ros_message->@(member.name).data, _ros_message->@(member.name).data + _ros_message->@(member.name).size, _j@(get_java_name)_@(member.name)_buf);
389+
env->Set@(get_method_name)ArrayRegion(_jarray_@(member.name)_obj, 0, _ros_message->@(member.name).size, (const j@(get_java_name) *)_j@(get_java_name)_@(member.name)_buf);
390+
@[ end if]@
391+
free(_j@(get_java_name)_@(member.name)_buf);
392+
@[ elif isinstance(member.type.value_type, AbstractGenericString)]@
393+
@[ if isinstance(member.type, Array)]@
394+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->NewObjectArray(@(member.type.size), env->FindClass("java/lang/String"), NULL);
395+
for (size_t i = 0; i < @(member.type.size); i++) {
362396
auto _ros_@(member.name)_element = _ros_message->@(member.name)[i];
363397
@[ else]@
364-
for (size_t i = 0; i < _ros_message->@(member.name).size; ++i) {
398+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->NewObjectArray(_ros_message->@(member.name).size, env->FindClass("java/lang/String"), NULL);
399+
for (size_t i = 0; i < _ros_message->@(member.name).size; i++) {
365400
auto _ros_@(member.name)_element = _ros_message->@(member.name).data[i];
366401
@[ end if]@
367-
@[ if isinstance(member.type.value_type, AbstractGenericString)]@
368-
jobject _jlist_@(member.name)_element = nullptr;
402+
jstring _jarray_@(member.name)_element = nullptr;
369403
if (_ros_@(member.name)_element.data != nullptr) {
370-
@[ if isinstance(member.type.value_type, AbstractString)]@
371-
_jlist_@(member.name)_element = env->NewStringUTF(_ros_@(member.name)_element.data);
372-
@[ else]@
373-
_jlist_@(member.name)_element = env->NewString(_ros_@(member.name)_element.data, _ros_@(member.name)_element.size);
374-
@[ end if]@
375-
}
404+
@[ if isinstance(member.type.value_type, AbstractString)]@
405+
_jarray_@(member.name)_element = env->NewStringUTF(_ros_@(member.name)_element.data);
376406
@[ else]@
377-
jobject _jlist_@(member.name)_element = env->NewObject(
378-
_j@(normalized_type)_class_global, _j@(normalized_type)_constructor_global, _ros_@(member.name)_element);
379-
@[ end if]@
380-
if (_jlist_@(member.name)_element != nullptr) {
381-
jboolean _jlist_@(member.name)_add_result = env->CallBooleanMethod(_jarray_list_@(member.name)_obj, _jlist_@(member.name)_add_mid, _jlist_@(member.name)_element);
382-
assert(_jlist_@(member.name)_add_result);
407+
_jarray_@(member.name)_element = env->NewString(_ros_@(member.name)_element.data, _ros_@(member.name)_element.size);
408+
@[ end if]@
383409
}
410+
env->SetObjectArrayElement(_jarray_@(member.name)_obj, i, _jarray_@(member.name)_element);
411+
env->DeleteLocalRef(_jarray_@(member.name)_element);
384412
}
385413
@[ else]@
386-
387-
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "L@(list_jni_type);");
388-
jobject _jarray_list_@(member.name)_obj = env->NewObject(_j@(array_list_normalized_type)_class_global, _j@(array_list_normalized_type)_constructor_global);
389-
// TODO(esteve): replace ArrayList with a jobjectArray to initialize the array beforehand
390-
jmethodID _jlist_@(member.name)_add_mid = env->GetMethodID(_j@(array_list_normalized_type)_class_global, "add", "(Ljava/lang/Object;)Z");
391-
392414
@[ if isinstance(member.type, Array)]@
393-
for (size_t i = 0; i < @(member.type.size); ++i) {
394-
jobject _jlist_@(member.name)_element = _j@(normalized_type)_to_java_function(&(_ros_message->@(member.name)[i]), nullptr);
415+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->NewObjectArray(@(member.type.size), _j@(normalized_type)_class_global, NULL);
416+
for (size_t i = 0; i < @(member.type.size); i++) {
417+
jobject _jarray_@(member.name)_element = _j@(normalized_type)_to_java_function(&(_ros_message->@(member.name)[i]), nullptr);
395418
@[ else]@
396-
for (size_t i = 0; i < _ros_message->@(member.name).size; ++i) {
397-
jobject _jlist_@(member.name)_element = _j@(normalized_type)_to_java_function(&(_ros_message->@(member.name).data[i]), nullptr);
419+
jobjectArray _jarray_@(member.name)_obj = (jobjectArray)env->NewObjectArray(_ros_message->@(member.name).size, _j@(normalized_type)_class_global, NULL);
420+
for (size_t i = 0; i < _ros_message->@(member.name).size; i++) {
421+
jobject _jarray_@(member.name)_element = _j@(normalized_type)_to_java_function(&(_ros_message->@(member.name).data[i]), nullptr);
398422
@[ end if]@
399-
if (_jlist_@(member.name)_element != nullptr) {
400-
jboolean _jlist_@(member.name)_add_result = env->CallBooleanMethod(_jarray_list_@(member.name)_obj, _jlist_@(member.name)_add_mid, _jlist_@(member.name)_element);
401-
assert(_jlist_@(member.name)_add_result);
402-
}
423+
env->SetObjectArrayElement(_jarray_@(member.name)_obj, i, _jarray_@(member.name)_element);
424+
env->DeleteLocalRef(_jarray_@(member.name)_element);
403425
}
404426
@[ end if]@
405-
env->SetObjectField(_jmessage_obj, _jfield_@(member.name)_fid, _jarray_list_@(member.name)_obj);
406-
env->DeleteLocalRef(_jarray_list_@(member.name)_obj);
427+
env->SetObjectField(_jmessage_obj, _jfield_@(member.name)_fid, _jarray_@(member.name)_obj);
428+
env->DeleteLocalRef(_jarray_@(member.name)_obj);
407429
@[ else]@
408430
@[ if isinstance(member.type, AbstractGenericString)]@
409431
auto _jfield_@(member.name)_fid = env->GetFieldID(_j@(msg_normalized_type)_class_global, "@(member.name)", "Ljava/lang/String;");

0 commit comments

Comments
 (0)