@@ -430,13 +430,21 @@ function buildtype(mod::ROSSrvModule, typename::String)
430
430
[reqexprs; respexprs; srvexprs]
431
431
end
432
432
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
+
433
446
# 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
440
448
function typecode (rosname:: String , super:: Symbol , members:: Vector )
441
449
tname = _splittypestr (rosname)[2 ]
442
450
@debug (" Type: " , tname)
@@ -448,44 +456,52 @@ function typecode(rosname::String, super::Symbol, members::Vector)
448
456
else ; " ROS" end
449
457
jlsym = Symbol (_jl_safe_name (tname,suffix))
450
458
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
451
468
exprs = Expr[]
452
- # First the empty expressions
453
- # (1) Type declaration
469
+ # Type declaration
454
470
push! (exprs, :(
455
471
mutable struct $ jlsym <: $super
456
- # Generated code here
472
+ $ (member_exprs . member_decls ... )
457
473
end
458
474
))
459
- # (2) Default constructor, but only if the type has members
475
+ # Default constructor, but only if the type has members
460
476
if length (members) > 0
461
477
push! (exprs, :(
462
478
function $jlsym ()
463
- $ jlsym () # Generated code inside parens here
479
+ $ jlsym ($ (member_exprs . constructor_defs ... ))
464
480
end
465
481
))
466
482
else
467
483
push! (exprs, :())
468
484
end
469
- # (3) Convert to PyObject
485
+ # Convert to PyObject
470
486
push! (exprs, :(
471
487
function convert (:: Type{PyObject} , o:: $jlsym )
472
488
py = pycall (RobotOS. _rospy_objects[$ rosname], PyObject)
473
- # Generated code here
489
+ $ (member_exprs . conv_to_pyobj_args ... )
474
490
py
475
491
end
476
492
))
477
- # (4) Convert from PyObject
493
+ # Convert from PyObject
478
494
push! (exprs, :(
479
495
function convert (jlt:: Type{$jlsym} , o:: PyObject )
480
496
if convert (String, o." _type" ) != _typerepr (jlt)
481
497
throw (InexactError (:convert , $ jlsym, o))
482
498
end
483
499
jl = $ jlsym ()
484
- # Generated code here
500
+ $ (member_exprs . conv_from_pyobj_args ... )
485
501
jl
486
502
end
487
503
))
488
- # (5) Accessing member variables through getproperty
504
+ # Accessing member variables through getproperty
489
505
push! (exprs, :(
490
506
function getproperty (:: Type{$jlsym} , s:: Symbol )
491
507
try getproperty (RobotOS. _rospy_objects[$ rosname], s)
@@ -499,28 +515,16 @@ function typecode(rosname::String, super::Symbol, members::Vector)
499
515
end
500
516
end
501
517
))
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
509
518
push! (exprs, :(_typerepr (:: Type{$jlsym} ) = $ rosname))
519
+
510
520
exprs
511
521
end
512
522
513
-
514
523
# Add the generated expression from a single member of a type, either built-in
515
524
# or ROS type. `exprs` is the Expr objects of the items created in `typecode`.
516
525
# Maybe this can be factored into something nicer.
517
- function _addtypemember! (exprs, namestr, typestr)
526
+ function _addtypemember! (exprs:: ROSTypeExprs , namestr, typestr)
518
527
@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
-
524
528
if typestr == " char" || typestr == " byte"
525
529
@warn (" Use of type '$typestr ' is deprecated in message definitions, " *
526
530
" use '$(lowercase (string (_ros_builtin_types[typestr]))) ' instead." )
@@ -564,10 +568,11 @@ function _addtypemember!(exprs, namestr, typestr)
564
568
jlconexpr = :(jl.$ namesym = convert ($ j_typ, o.$ namestr))
565
569
pyconexpr = :(py.$ namestr = convert (PyObject, o.$ namesym))
566
570
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)
571
576
end
572
577
573
578
# Build a String => Iterable{String} object from the individual package
0 commit comments