@@ -430,13 +430,21 @@ function buildtype(mod::ROSSrvModule, typename::String)
430430 [reqexprs; respexprs; srvexprs]
431431end
432432
433+ # Container for the generated expressions for each type
434+ struct ROSTypeExprs
435+ # The contents of the 'struct ... end' block
436+ member_decls:: Vector{Expr}
437+ # The default values used for defining a no argument constructor
438+ constructor_defs:: Vector{Any}
439+ # The conversions to PyObject
440+ conv_to_pyobj_args:: Vector{Expr}
441+ # The conversion from PyObject
442+ conv_from_pyobj_args:: Vector{Expr}
443+ end
444+ ROSTypeExprs () = ROSTypeExprs (Expr[], Expr[], Expr[], Expr[])
445+
433446# Create the core generated expressions for a native Julia message type that has
434- # data fields and interchanges with a python counterpart:
435- # (1) the 'type ... end' block
436- # (2) Default outer constructer with no arguments
437- # (3) convert(PyObject, ...)
438- # (4) convert(..., o::PyObject)
439- # (5) getproperty for accessing member constants
447+ # data fields and interchanges with a python counterpart
440448function typecode (rosname:: String , super:: Symbol , members:: Vector )
441449 tname = _splittypestr (rosname)[2 ]
442450 @debug (" Type: " , tname)
@@ -448,44 +456,52 @@ function typecode(rosname::String, super::Symbol, members::Vector)
448456 else ; " ROS" end
449457 jlsym = Symbol (_jl_safe_name (tname,suffix))
450458
459+ # First generate the interior expressions for each member separately
460+ member_exprs = ROSTypeExprs ()
461+ for (namestr,typ) in members
462+ @debug_addindent
463+ _addtypemember! (member_exprs, namestr, typ)
464+ @debug_subindent
465+ end
466+
467+ # Now build the full expressions
451468 exprs = Expr[]
452- # First the empty expressions
453- # (1) Type declaration
469+ # Type declaration
454470 push! (exprs, :(
455471 mutable struct $ jlsym <: $super
456- # Generated code here
472+ $ (member_exprs . member_decls ... )
457473 end
458474 ))
459- # (2) Default constructor, but only if the type has members
475+ # Default constructor, but only if the type has members
460476 if length (members) > 0
461477 push! (exprs, :(
462478 function $jlsym ()
463- $ jlsym () # Generated code inside parens here
479+ $ jlsym ($ (member_exprs . constructor_defs ... ))
464480 end
465481 ))
466482 else
467483 push! (exprs, :())
468484 end
469- # (3) Convert to PyObject
485+ # Convert to PyObject
470486 push! (exprs, :(
471487 function convert (:: Type{PyObject} , o:: $jlsym )
472488 py = pycall (RobotOS. _rospy_objects[$ rosname], PyObject)
473- # Generated code here
489+ $ (member_exprs . conv_to_pyobj_args ... )
474490 py
475491 end
476492 ))
477- # (4) Convert from PyObject
493+ # Convert from PyObject
478494 push! (exprs, :(
479495 function convert (jlt:: Type{$jlsym} , o:: PyObject )
480496 if convert (String, o." _type" ) != _typerepr (jlt)
481497 throw (InexactError (:convert , $ jlsym, o))
482498 end
483499 jl = $ jlsym ()
484- # Generated code here
500+ $ (member_exprs . conv_from_pyobj_args ... )
485501 jl
486502 end
487503 ))
488- # (5) Accessing member variables through getproperty
504+ # Accessing member variables through getproperty
489505 push! (exprs, :(
490506 function getproperty (:: Type{$jlsym} , s:: Symbol )
491507 try getproperty (RobotOS. _rospy_objects[$ rosname], s)
@@ -499,28 +515,16 @@ function typecode(rosname::String, super::Symbol, members::Vector)
499515 end
500516 end
501517 ))
502-
503- # Now add the meat to the empty expressions above
504- for (namestr,typ) in members
505- @debug_addindent
506- _addtypemember! (exprs, namestr, typ)
507- @debug_subindent
508- end
509518 push! (exprs, :(_typerepr (:: Type{$jlsym} ) = $ rosname))
519+
510520 exprs
511521end
512522
513-
514523# Add the generated expression from a single member of a type, either built-in
515524# or ROS type. `exprs` is the Expr objects of the items created in `typecode`.
516525# Maybe this can be factored into something nicer.
517- function _addtypemember! (exprs, namestr, typestr)
526+ function _addtypemember! (exprs:: ROSTypeExprs , namestr, typestr)
518527 @debug (" $namestr :: $typestr " )
519- typeargs = exprs[1 ]. args[3 ]. args
520- consargs = exprs[2 ]. args[2 ]. args[2 ]. args
521- pyconargs = exprs[3 ]. args[2 ]. args
522- jlconargs = exprs[4 ]. args[2 ]. args
523-
524528 if typestr == " char" || typestr == " byte"
525529 @warn (" Use of type '$typestr ' is deprecated in message definitions, " *
526530 " use '$(lowercase (string (_ros_builtin_types[typestr]))) ' instead." )
@@ -564,10 +568,11 @@ function _addtypemember!(exprs, namestr, typestr)
564568 jlconexpr = :(jl.$ namesym = convert ($ j_typ, o.$ namestr))
565569 pyconexpr = :(py.$ namestr = convert (PyObject, o.$ namesym))
566570 end
567- push! (typeargs, memexpr)
568- insert! (jlconargs, length (jlconargs), jlconexpr)
569- insert! (pyconargs, length (pyconargs), pyconexpr)
570- push! (consargs, defexpr)
571+
572+ push! (exprs. member_decls, memexpr)
573+ push! (exprs. constructor_defs, defexpr)
574+ push! (exprs. conv_to_pyobj_args, pyconexpr)
575+ push! (exprs. conv_from_pyobj_args, jlconexpr)
571576end
572577
573578# Build a String => Iterable{String} object from the individual package
0 commit comments