Skip to content

Commit

Permalink
Merge pull request #84 from jdlangs/jl1.5fix
Browse files Browse the repository at this point in the history
Restructure some typegen code to fix break in 1.5
  • Loading branch information
jdlangs authored Aug 18, 2020
2 parents 4df0ab0 + 769b7b1 commit 233a1c6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 42 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
language: julia
julia:
- 1.0
- 1.2
- 1.5
- nightly
matrix:
allow_failures:
- julia: nightly
sudo: required
dist: xenial
dist: bionic
env:
global:
- PYTHON=python
before_install:
- sudo apt-add-repository -y "deb http://packages.ros.org/ros/ubuntu xenial main"
- wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
- sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
- sudo apt-add-repository -y "deb http://packages.ros.org/ros/ubuntu bionic main"
- sudo apt-get update
- sudo apt-get -y install ros-kinetic-ros-base ros-kinetic-common-msgs
- sudo apt-get -y install python-rosdep ros-melodic-ros-base ros-melodic-common-msgs
- sudo rosdep init
- rosdep update
before_script:
- export PATH=/usr/bin:$PATH
- source /opt/ros/kinetic/setup.sh
- source /opt/ros/melodic/setup.sh
- roscore &
- sleep 5
- python test/echonode.py &
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "RobotOS"
uuid = "22415677-39a4-5241-a37a-00beabbbdae8"
version = "0.7.1"
version = "0.8.0"

[deps]
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
Expand Down
73 changes: 39 additions & 34 deletions src/gentypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,21 @@ function buildtype(mod::ROSSrvModule, typename::String)
[reqexprs; respexprs; srvexprs]
end

# Container for the generated expressions for each type
struct ROSTypeExprs
# The contents of the 'struct ... end' block
member_decls::Vector{Expr}
# The default values used for defining a no argument constructor
constructor_defs::Vector{Any}
# The conversions to PyObject
conv_to_pyobj_args::Vector{Expr}
# The conversion from PyObject
conv_from_pyobj_args::Vector{Expr}
end
ROSTypeExprs() = ROSTypeExprs(Expr[], Expr[], Expr[], Expr[])

#Create the core generated expressions for a native Julia message type that has
#data fields and interchanges with a python counterpart:
# (1) the 'type ... end' block
# (2) Default outer constructer with no arguments
# (3) convert(PyObject, ...)
# (4) convert(..., o::PyObject)
# (5) getproperty for accessing member constants
#data fields and interchanges with a python counterpart
function typecode(rosname::String, super::Symbol, members::Vector)
tname = _splittypestr(rosname)[2]
@debug("Type: ", tname)
Expand All @@ -448,44 +456,52 @@ function typecode(rosname::String, super::Symbol, members::Vector)
else; "ROS" end
jlsym = Symbol(_jl_safe_name(tname,suffix))

#First generate the interior expressions for each member separately
member_exprs = ROSTypeExprs()
for (namestr,typ) in members
@debug_addindent
_addtypemember!(member_exprs, namestr, typ)
@debug_subindent
end

#Now build the full expressions
exprs = Expr[]
#First the empty expressions
#(1) Type declaration
# Type declaration
push!(exprs, :(
mutable struct $jlsym <: $super
#Generated code here
$(member_exprs.member_decls...)
end
))
#(2) Default constructor, but only if the type has members
# Default constructor, but only if the type has members
if length(members) > 0
push!(exprs, :(
function $jlsym()
$jlsym() #Generated code inside parens here
$jlsym($(member_exprs.constructor_defs...))
end
))
else
push!(exprs, :())
end
#(3) Convert to PyObject
# Convert to PyObject
push!(exprs, :(
function convert(::Type{PyObject}, o::$jlsym)
py = pycall(RobotOS._rospy_objects[$rosname], PyObject)
#Generated code here
$(member_exprs.conv_to_pyobj_args...)
py
end
))
#(4) Convert from PyObject
# Convert from PyObject
push!(exprs, :(
function convert(jlt::Type{$jlsym}, o::PyObject)
if convert(String, o."_type") != _typerepr(jlt)
throw(InexactError(:convert, $jlsym, o))
end
jl = $jlsym()
#Generated code here
$(member_exprs.conv_from_pyobj_args...)
jl
end
))
#(5) Accessing member variables through getproperty
# Accessing member variables through getproperty
push!(exprs, :(
function getproperty(::Type{$jlsym}, s::Symbol)
try getproperty(RobotOS._rospy_objects[$rosname], s)
Expand All @@ -499,28 +515,16 @@ function typecode(rosname::String, super::Symbol, members::Vector)
end
end
))

#Now add the meat to the empty expressions above
for (namestr,typ) in members
@debug_addindent
_addtypemember!(exprs, namestr, typ)
@debug_subindent
end
push!(exprs, :(_typerepr(::Type{$jlsym}) = $rosname))

exprs
end


#Add the generated expression from a single member of a type, either built-in
#or ROS type. `exprs` is the Expr objects of the items created in `typecode`.
#Maybe this can be factored into something nicer.
function _addtypemember!(exprs, namestr, typestr)
function _addtypemember!(exprs::ROSTypeExprs, namestr, typestr)
@debug("$namestr :: $typestr")
typeargs = exprs[1].args[3].args
consargs = exprs[2].args[2].args[2].args
pyconargs = exprs[3].args[2].args
jlconargs = exprs[4].args[2].args

if typestr == "char" || typestr == "byte"
@warn("Use of type '$typestr' is deprecated in message definitions, " *
"use '$(lowercase(string(_ros_builtin_types[typestr])))' instead.")
Expand Down Expand Up @@ -564,10 +568,11 @@ function _addtypemember!(exprs, namestr, typestr)
jlconexpr = :(jl.$namesym = convert($j_typ, o.$namestr))
pyconexpr = :(py.$namestr = convert(PyObject, o.$namesym))
end
push!(typeargs, memexpr)
insert!(jlconargs, length(jlconargs), jlconexpr)
insert!(pyconargs, length(pyconargs), pyconexpr)
push!(consargs, defexpr)

push!(exprs.member_decls, memexpr)
push!(exprs.constructor_defs, defexpr)
push!(exprs.conv_to_pyobj_args, pyconexpr)
push!(exprs.conv_from_pyobj_args, jlconexpr)
end

#Build a String => Iterable{String} object from the individual package
Expand Down
2 changes: 1 addition & 1 deletion test/rospy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ init_node("jltest", anonymous=true)
#Parameters
@test length(RobotOS.get_param_names()) > 0
@test has_param("rosdistro")
@test chomp(get_param("rosdistro")) in ["hydro", "indigo", "jade", "kinetic", "lunar", "melodic"]
@test chomp(get_param("rosdistro")) in ["kinetic", "melodic", "noetic"]
@test ! has_param("some_param")
@test_throws KeyError get_param("some_param")
@test_throws KeyError delete_param("some_param")
Expand Down

2 comments on commit 233a1c6

@jdlangs
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/19756

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.0 -m "<description of version>" 233a1c643c364b664e93eedc22ea05200191ed2c
git push origin v0.8.0

Please sign in to comment.